In the system call mmap(), if the value of "offset" plus "length" exceeds the offset maximum of "off_t", the error EOVERFLOW should be returned. ------------------------------------------------------------------------ void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) ------------------------------------------------------------------------ Here is the detail how EOVERFLOW is returned: The argument "offset" is shifted right by PAGE_SHIFT bits in sys_mmap(mmap systemcall). ------------------------------------------------------------------------ sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off) { error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); } ------------------------------------------------------------------------ In sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff), do_mmap_pgoff() is called as follows: ------------------------------------------------------------------------ sys_mmap_pgoff(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); } ------------------------------------------------------------------------ In do_mmap_pgoff(file, addr, len, prot, flags, pgoff), the code path which returns with the error EOVERFLOW exists already. ------------------------------------------------------------------------ do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) return -EOVERFLOW; } ------------------------------------------------------------------------ However, in this case, giving off=0xfffffffffffff000 and len=0xfffffffffffff000 on x86_64 arch, EOVERFLOW is not returned. It is because the argument, "off" and "len" are shifted right by PAGE_SHIFT bits and thus the condition "(pgoff + (len >> PAGE_SHIFT)) < pgoff" never becomes true. To fix this bug, it is necessary to compare "off" plus "len" with "off" by units of "off_t". The patch is here: Signed-off-by: Naotaka Hamaguchi <n.hamaguchi@xxxxxxxxxxxxxx> --- mm/mmap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index eae90af..e74e736 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -948,6 +948,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, vm_flags_t vm_flags; int error; unsigned long reqprot = prot; + off_t off = pgoff << PAGE_SHIFT; /* * Does the application expect PROT_READ to imply PROT_EXEC? @@ -971,7 +972,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return -ENOMEM; /* offset overflow? */ - if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) + if ((off + len) < off) return -EOVERFLOW; /* Too many mappings? */ -- 1.7.7.4 --- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>