When a nonlinear mapping's page is unmapped, its file offset is placed into the user's pte. As this can only hold (say) 29 bits, this places a per-arch upper bound on the file offsets which can be nonlinearly mapped. The patch enforces those offsets at remap_file_pages() time. It also adds additional checking on the remap_file_pages() incoming address range. Last time I looked, these checks aren't actually necessary, but it's clearer to do this up-front. 25-akpm/include/asm-i386/pgtable-2level.h | 2 ++ 25-akpm/mm/fremap.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff -puN mm/fremap.c~fremap-limit-offsets mm/fremap.c --- 25/mm/fremap.c~fremap-limit-offsets Wed Mar 12 15:10:22 2003 +++ 25-akpm/mm/fremap.c Wed Mar 12 15:59:12 2003 @@ -129,6 +129,14 @@ int sys_remap_file_pages(unsigned long s start = start & PAGE_MASK; size = size & PAGE_MASK; + /* Does the address range wrap, or is the span zero-sized? */ + if (start + size <= start) + return err; + + /* Can we represent this offset inside this architecture's pte's? */ + if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS)) + return err; + down_read(&mm->mmap_sem); vma = find_vma(mm, start); diff -puN include/asm-i386/pgtable-2level.h~fremap-limit-offsets include/asm-i386/pgtable-2level.h --- 25/include/asm-i386/pgtable-2level.h~fremap-limit-offsets Wed Mar 12 15:39:41 2003 +++ 25-akpm/include/asm-i386/pgtable-2level.h Wed Mar 12 15:39:58 2003 @@ -67,6 +67,8 @@ static inline pmd_t * pmd_offset(pgd_t * * Bits 0, 6 and 7 are taken, split up the 29 bits of offset * into this range: */ +#define PTE_FILE_MAX_BITS 29 + #define pte_to_pgoff(pte) \ ((((pte).pte_low >> 1) & 0x1f ) + (((pte).pte_low >> 8) << 5 )) _