From: <bod...@fu...> - 2004-10-08 19:17:55
|
To make the vsyscall-page available for copy_from_user() and ptrace(), we should use kernel's "gate-vma" mechanism. Therefore we need a valid page structure. To have this, one page (or more) is allocated at boot time, the contents of the vsyscall-page is copied into this page and the page's pte is inserted in swapper's pagetables. Now it will be copied into the pagetables of all processes. Note: this alone doesn't work, since FIXADDR_USER_START and FIXADDR_USER_END are not yet defined correctly. Also access_ok_skas() does not yet grant read accesses to pages not in the normal user area. Risks: Please check the first hunk! I don't know, whether this change is OK. Maybe fixrange_init() is wrong anyway with 3-level-pagetables? Signed-off-by: Bodo Stroesser <bod...@fu...> --- --- linux-2.6.9-rc2-orig/arch/um/kernel/mem.c 2004-09-27 19:24:56.000000000 +0200 +++ linux-2.6.9-rc2/arch/um/kernel/mem.c 2004-10-05 15:36:57.032218318 +0200 @@ -121,7 +121,7 @@ for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { pmd = (pmd_t *)pgd; - for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { + for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pmd(pmd, __pmd(_KERNPG_TABLE + @@ -175,6 +175,29 @@ } #endif /* CONFIG_HIGHMEM */ +static void __init fixaddr_user_init( void) +{ + long size = FIXADDR_USER_END - FIXADDR_USER_START; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + unsigned long paddr, vaddr = FIXADDR_USER_START; + + if ( ! size ) + return; + + fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); + paddr = (unsigned long)alloc_bootmem_low_pages( size); + memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size); + paddr = __pa(paddr); + for ( ; size > 0; size-=PAGE_SIZE, vaddr+=PAGE_SIZE, paddr+=PAGE_SIZE) { + pgd = swapper_pg_dir + pgd_index(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset_kernel(pmd, vaddr); + pte_set_val( (*pte), paddr, PAGE_READONLY); + } +} + void paging_init(void) { unsigned long zones_size[MAX_NR_ZONES], vaddr; @@ -195,6 +218,8 @@ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); + fixaddr_user_init(); + #ifdef CONFIG_HIGHMEM init_highmem(); #endif |
From: Adam H. <ad...@do...> - 2004-10-11 19:29:47
|
On Fri, 8 Oct 2004, wrote: > To make the vsyscall-page available for copy_from_user() and > ptrace(), we should use kernel's "gate-vma" mechanism. > Therefore we need a valid page structure. To have this, one > page (or more) is allocated at boot time, the contents of the > vsyscall-page is copied into this page and the page's pte is > inserted in swapper's pagetables. > Now it will be copied into the pagetables of all processes. > > Note: this alone doesn't work, since FIXADDR_USER_START and > FIXADDR_USER_END are not yet defined correctly. Also > access_ok_skas() does not yet grant read accesses to > pages not in the normal user area. > > Risks: > Please check the first hunk! I don't know, whether this change is OK. > Maybe fixrange_init() is wrong anyway with 3-level-pagetables? > > > Signed-off-by: Bodo Stroesser <bod...@fu...> > > --- > > > --- linux-2.6.9-rc2-orig/arch/um/kernel/mem.c 2004-09-27 19:24:56.000000000 +0200 > +++ linux-2.6.9-rc2/arch/um/kernel/mem.c 2004-10-05 15:36:57.032218318 +0200 > @@ -121,7 +121,7 @@ > > for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { > pmd = (pmd_t *)pgd; > - for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { > + for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) { > if (pmd_none(*pmd)) { > pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); > set_pmd(pmd, __pmd(_KERNPG_TABLE + > @@ -175,6 +175,29 @@ > } > #endif /* CONFIG_HIGHMEM */ > > +static void __init fixaddr_user_init( void) > +{ > + long size = FIXADDR_USER_END - FIXADDR_USER_START; > + pgd_t *pgd; > + pmd_t *pmd; > + pte_t *pte; > + unsigned long paddr, vaddr = FIXADDR_USER_START; > + > + if ( ! size ) > + return; > + > + fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); > + paddr = (unsigned long)alloc_bootmem_low_pages( size); > + memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size); Use consistent spacing. > + paddr = __pa(paddr); > + for ( ; size > 0; size-=PAGE_SIZE, vaddr+=PAGE_SIZE, paddr+=PAGE_SIZE) { > + pgd = swapper_pg_dir + pgd_index(vaddr); > + pmd = pmd_offset(pgd, vaddr); > + pte = pte_offset_kernel(pmd, vaddr); > + pte_set_val( (*pte), paddr, PAGE_READONLY); > + } > +} > + > void paging_init(void) > { > unsigned long zones_size[MAX_NR_ZONES], vaddr; > @@ -195,6 +218,8 @@ > vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; > fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); > > + fixaddr_user_init(); > + > #ifdef CONFIG_HIGHMEM > init_highmem(); > #endif > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > User-mode-linux-devel mailing list > Use...@li... > https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel > |