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.


 include/asm-i386/pgtable-2level.h |    2 ++
 include/asm-i386/pgtable-3level.h |    1 +
 mm/fremap.c                       |   10 ++++++++++
 3 files changed, 13 insertions(+)

diff -puN mm/fremap.c~fremap-limit-offsets mm/fremap.c
--- 25/mm/fremap.c~fremap-limit-offsets	2003-03-13 20:17:53.000000000 -0800
+++ 25-akpm/mm/fremap.c	2003-03-13 20:46:51.000000000 -0800
@@ -129,6 +129,16 @@ 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 PTE_FILE_MAX_BITS < BITS_PER_LONG
+	if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS))
+		return err;
+#endif
+
 	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	2003-03-13 20:17:53.000000000 -0800
+++ 25-akpm/include/asm-i386/pgtable-2level.h	2003-03-13 20:17:53.000000000 -0800
@@ -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 ))
 
diff -puN include/asm-i386/pgtable-3level.h~fremap-limit-offsets include/asm-i386/pgtable-3level.h
--- 25/include/asm-i386/pgtable-3level.h~fremap-limit-offsets	2003-03-13 20:18:38.000000000 -0800
+++ 25-akpm/include/asm-i386/pgtable-3level.h	2003-03-13 20:19:02.000000000 -0800
@@ -121,5 +121,6 @@ static inline pmd_t pfn_pmd(unsigned lon
  */
 #define pte_to_pgoff(pte) ((pte).pte_high)
 #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+#define PTE_FILE_MAX_BITS       32
 
 #endif /* _I386_PGTABLE_3LEVEL_H */

_