[kernel] Page Protection
Page Protection
x86
#1 set_pages_rw , change_page_attr
int set_pages_rw(struct page *page, int numpages) // use virt_to_page()
{
unsigned long addr = (unsigned long)page_address(page);
return set_memory_rw(addr, numpages);
}
int set_memory_rw(unsigned long addr, int numpages)
{
return change_page_attr_set(&addr, numpages, __pgprot(_PAGE_RW), 0);
}
```
- 특정 영역(BIOS, .rodata, ...)이 들어오면 `` _PAGE_RW`` flag를 제거해버리기 때문에 사용할 수 없다.
- ``c EXPORT_SYMBOL()``로 지정되어 있지 않아서 사용할 수 없다.
- source/arch/x86/include/asm/set_memory.h에 정의되어 있기는 하지만 이를 ``c include``해봐야 `` insmod`` 시 `` Unknown symbol in module`` 에러가 발생한다.
- kenrel 2.6.24 이하 버전에서는 ``c change_page_attr()``이 직접 export 되어 있으나, 버전이 올라가면서 함수 자체가 사라졌다.
#2 lookup_address
/source/arch/x86/mm/pageattr.c#L353 : lookup_addersss_in_pgd
```c
virt_addr
→ pgd ( Page Global Directory )
→ pud ( Page Upper Directory )
→ pmd ( Page Middle Directory )
→ pte ( Page Table Entry ) // return *pte_t
Page Frame ( phys_addr )
```
#3 cr0
0 PE Protected Mode Enable 1 : protected mode, 0 : real mode
1 MP Monitor co-processor
2 EM Emulation
3 TS Task switched
4 ET Extension type
5 NE Numeric error
16 WP Write protect the CPU can't write to read-only pages when privilege level is 0
18 AM Alignment mask
29 NW Not-write through
30 CD Cache disable
31 PG Paging
```
/source/arch/x86/include/asm/special_insns.h#L142 : read_cr0 / write_cr0
매크로로 등록해서 사용하면 된다.
```c
#define cr0_WP_off write_cr0( read_cr0() & (~0x10000) );
#define cr0_WP_on write_cr0( read_cr0() | 0x10000 );
```
만약 사용할 수 없는 경우, 구현이 간단하므로 직접 인라인 어셈블리 작성해서 사용하면 된다.
쉘코드에 넣어야 하는 경우
```c
asm volatile(
"pushl %eax \n\t"
"pushl %ebx \n\t"
"movl %cr0, %eax \n\t"
"movl $0x10000, %ebx \n\t"
"notl %ebx \n\t"
"andl %ebx, %eax \n\t"
"movl %eax, %cr0 \n\t"
"popl %ebx \n\t"
"popl %eax"
);
```
arm
set_memory_rw
'OS > Kernel' 카테고리의 다른 글
[kernel] hook sys_call_table (0) | 2017.10.20 |
---|---|
[kernel] get sys_call_table (0) | 2017.10.16 |
[kernel] addr_limit : kernel space arg (0) | 2017.10.15 |
[kernel] LKM, Loadable Kernel Module / Kernel Compile (0) | 2017.10.14 |
[kernel] virt_to_phys (0) | 2017.10.13 |