Make kernel code pages read-only.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 8 Sep 2006 00:51:17 +0000 (00:51 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 8 Sep 2006 00:51:17 +0000 (00:51 +0000)
From Godmar Back, with changes.

src/threads/init.c
src/threads/kernel.lds.S
src/threads/pte.h

index 458f67cb2bbd7a7424950d8a219c9f08747c30f8..8495826da379a3624e061d3a53cc8432aa04764c 100644 (file)
@@ -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
index 28721e2832a27a73c895a98daa89cd47471027e9..437ced3eb4a0e00553452c9857e330d1fde3bc7d 100644 (file)
@@ -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. */
index 74a52f44815534d05873984ed6cc7320eac7f6ba..1660727108385418a2cf07edba939f2a77ed9399 100644 (file)
@@ -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;
 }