Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932237Ab2FGEPu (ORCPT ); Thu, 7 Jun 2012 00:15:50 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:63306 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932180Ab2FGEPp (ORCPT ); Thu, 7 Jun 2012 00:15:45 -0400 Message-Id: <20120607040337.204816103@linuxfoundation.org> User-Agent: quilt/0.60-19.1 Date: Thu, 07 Jun 2012 13:03:41 +0900 From: Greg KH To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Siddhesh Poyarekar , Tejun Heo , Oleg Nesterov , Jens Axboe , Peter Zijlstra , Hugh Dickins Subject: [ 05/82] mm/fork: fix overflow in vma length when copying mmap on clone In-Reply-To: <20120607041406.GA13233@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2595 Lines: 83 3.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Siddhesh Poyarekar commit 7edc8b0ac16cbaed7cb4ea4c6b95ce98d2997e84 upstream. The vma length in dup_mmap is calculated and stored in a unsigned int, which is insufficient and hence overflows for very large maps (beyond 16TB). The following program demonstrates this: #include #include #include #define GIG 1024 * 1024 * 1024L #define EXTENT 16393 int main(void) { int i, r; void *m; char buf[1024]; for (i = 0; i < EXTENT; i++) { m = mmap(NULL, (size_t) 1 * 1024 * 1024 * 1024L, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (m == (void *)-1) printf("MMAP Failed: %d\n", m); else printf("%d : MMAP returned %p\n", i, m); r = fork(); if (r == 0) { printf("%d: successed\n", i); return 0; } else if (r < 0) printf("FORK Failed: %d\n", r); else if (r > 0) wait(NULL); } return 0; } Increase the storage size of the result to unsigned long, which is sufficient for storing the difference between addresses. Signed-off-by: Siddhesh Poyarekar Cc: Tejun Heo Cc: Oleg Nesterov Cc: Jens Axboe Cc: Peter Zijlstra Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/fork.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/kernel/fork.c +++ b/kernel/fork.c @@ -356,7 +356,8 @@ static int dup_mmap(struct mm_struct *mm } charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { - unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; + unsigned long len; + len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ goto fail_nomem; charge = len; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/