From e1289bf52f9dbc8da311fe2064af85076edf82b1 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 8 Sep 2006 00:51:17 +0000 Subject: [PATCH] Make kernel code pages read-only. From Godmar Back, with changes. --- src/threads/init.c | 6 ++++-- src/threads/kernel.lds.S | 3 ++- src/threads/pte.h | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/threads/init.c b/src/threads/init.c index 458f67c..8495826 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -168,15 +168,17 @@ paging_init (void) { uint32_t *pd, *pt; size_t page; + extern char _start, _end_kernel_text; pd = base_page_dir = palloc_get_page (PAL_ASSERT | PAL_ZERO); pt = NULL; for (page = 0; page < ram_pages; page++) { uintptr_t paddr = page * PGSIZE; - void *vaddr = ptov (paddr); + char *vaddr = ptov (paddr); size_t pde_idx = pd_no (vaddr); size_t pte_idx = pt_no (vaddr); + bool in_kernel_text = &_start <= vaddr && vaddr < &_end_kernel_text; if (pd[pde_idx] == 0) { @@ -184,7 +186,7 @@ paging_init (void) pd[pde_idx] = pde_create (pt); } - pt[pte_idx] = pte_create_kernel (vaddr, true); + pt[pte_idx] = pte_create_kernel (vaddr, !in_kernel_text); } /* Store the physical address of the page directory into CR3 diff --git a/src/threads/kernel.lds.S b/src/threads/kernel.lds.S index 28721e2..437ced3 100644 --- a/src/threads/kernel.lds.S +++ b/src/threads/kernel.lds.S @@ -12,7 +12,8 @@ SECTIONS /* Kernel starts with code, followed by read-only data and writable data. */ .text : { *(.start) *(.text) } = 0x90 - .rodata : { *(.rodata) *(.rodata.*) } + .rodata : { *(.rodata) *(.rodata.*) . = ALIGN(0x1000); } + _end_kernel_text = .; .data : { *(.data) } /* BSS (zero-initialized data) is after everything else. */ diff --git a/src/threads/pte.h b/src/threads/pte.h index 74a52f4..1660727 100644 --- a/src/threads/pte.h +++ b/src/threads/pte.h @@ -84,7 +84,7 @@ static inline uint32_t *pde_get_pt (uint32_t pde) { The PTE's page is readable. If WRITABLE is true then it will be writable as well. The page will be usable only by ring 0 code (the kernel). */ -static inline uint32_t pte_create_kernel (uint32_t *page, bool writable) { +static inline uint32_t pte_create_kernel (void *page, bool writable) { ASSERT (pg_ofs (page) == 0); return vtop (page) | PTE_P | (writable ? PTE_W : 0); } @@ -93,7 +93,7 @@ static inline uint32_t pte_create_kernel (uint32_t *page, bool writable) { The PTE's page is readable. If WRITABLE is true then it will be writable as well. The page will be usable by both user and kernel code. */ -static inline uint32_t pte_create_user (uint32_t *page, bool writable) { +static inline uint32_t pte_create_user (void *page, bool writable) { return pte_create_kernel (page, writable) | PTE_U; } -- 2.30.2