From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760097AbZKFWKR (ORCPT ); Fri, 6 Nov 2009 17:10:17 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759946AbZKFWKO (ORCPT ); Fri, 6 Nov 2009 17:10:14 -0500 Received: from kroah.org ([198.145.64.141]:39746 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932178AbZKFWFs (ORCPT ); Fri, 6 Nov 2009 17:05:48 -0500 X-Mailbox-Line: From gregkh@mini.kroah.org Fri Nov 6 13:59:51 2009 Message-Id: <20091106215951.465536726@mini.kroah.org> User-Agent: quilt/0.48-1 Date: Fri, 06 Nov 2009 13:56:14 -0800 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, KOSAKI Motohiro , Christoph Lameter Subject: [11/30] mbind(): fix leak of never putback pages References: <20091106215603.413650799@mini.kroah.org> Content-Disposition: inline; filename=mbind-fix-leak-of-never-putback-pages.patch In-Reply-To: <20091106220156.GA13813@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2.6.29-stable review patch. If anyone has any objections, please let us know. ------------------ From: KOSAKI Motohiro commit ab8a3e14e6f8e567560f664bbd29aefb306a274e upstream. If mbind() receives an invalid address, do_mbind leaks a page. The following test program detects this leak. This patch fixes it. migrate_efault.c ======================================= #include #include #include #include #include #include #include static unsigned long pagesize; static void* make_hole_mapping(void) { void* addr; addr = mmap(NULL, pagesize*3, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); if (addr == MAP_FAILED) return NULL; /* make page populate */ memset(addr, 0, pagesize*3); /* make memory hole */ munmap(addr+pagesize, pagesize); return addr; } int main(int argc, char** argv) { void* addr; int ch; int node; struct bitmask *nmask = numa_allocate_nodemask(); int err; int node_set = 0; while ((ch = getopt(argc, argv, "n:")) != -1){ switch (ch){ case 'n': node = strtol(optarg, NULL, 0); numa_bitmask_setbit(nmask, node); node_set = 1; break; default: ; } } argc -= optind; argv += optind; if (!node_set) numa_bitmask_setbit(nmask, 0); pagesize = getpagesize(); addr = make_hole_mapping(); err = mbind(addr, pagesize*3, MPOL_BIND, nmask->maskp, nmask->size, MPOL_MF_MOVE_ALL); if (err) perror("mbind "); return 0; } ======================================= Signed-off-by: KOSAKI Motohiro Acked-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/mempolicy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -985,7 +985,8 @@ static long do_mbind(unsigned long start if (!err && nr_failed && (flags & MPOL_MF_STRICT)) err = -EIO; - } + } else + putback_lru_pages(&pagelist); up_write(&mm->mmap_sem); mpol_put(new);