lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <12456768291898-git-send-email-krzysiek@podlesie.net>
Date:	Mon, 22 Jun 2009 15:20:29 +0200
From:	Krzysztof Mazur <krzysiek@...lesie.net>
To:	linux-mm@...ck.org
Cc:	linux-kernel@...r.kernel.org,
	Krzysztof Mazur <krzysiek@...lesie.net>
Subject: [PATCH] generic arch_get_unmapped_area(): make sure that addr >= TASK_UNMAPPED_BASE

Generic arch_get_unmapped_area() use mm->free_area_cache for start_addr
and addr even when it's smaller that TASK_UNMAPPED_BASE.

	if (len > mm->cached_hole_size) {
	        start_addr = addr = mm->free_area_cache;
	} else {
	        start_addr = addr = TASK_UNMAPPED_BASE;
 	        mm->cached_hole_size = 0;
 	}

I don't know how it should work (maybe mm->free_area_cache should be
never smaller than TASK_UNMAPPED_BASE, but it was 0 when I took strace
below), but I copied code from x86-64's arch_get_unmapped_area(),
there is:

	if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
	    && len <= mm->cached_hole_size) {
		mm->cached_hole_size = 0;
		mm->free_area_cache = begin;
	}
	addr = mm->free_area_cache;
	if (addr < begin)
		addr = begin;
	start_addr = addr;

Now with check for begin (TASK_UNMAPPED_BASE in generic code) it seems
to be ok.

Previously I had -EACCESS when process used legacy VA layout (for instance
because of no RLIMIT_STACK limit):

setrlimit(RLIMIT_STACK, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
...
vfork(Process 1819 attached (waiting for parent)
Process 1819 resumed (parent 1818 ready)
)                                 = 1819
[pid  1819] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid  1819] execve("/bin/sh", ["/bin/sh", "-c", "if test ! -f config.h; then \\\n  "...], [/* 26 vars */]) = 0
[pid  1819] brk(0)                      = 0x8a01000
[pid  1819] uname({sys="Linux", node="geronimo", ...}) = 0
[pid  1819] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[pid  1819] open("/etc/ld.so.cache", O_RDONLY) = 3
[pid  1819] fstat64(3, {st_mode=S_IFREG|0644, st_size=105204, ...}) = 0
[pid  1819] mmap2(NULL, 105204, PROT_READ, MAP_PRIVATE, 3, 0) = -1 EACCES (Permission denied)

Signed-off-by: Krzysztof Mazur <krzysiek@...lesie.net>
---
 mm/mmap.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index 34579b2..577cfc0 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1289,12 +1289,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
-	if (len > mm->cached_hole_size) {
-	        start_addr = addr = mm->free_area_cache;
-	} else {
-	        start_addr = addr = TASK_UNMAPPED_BASE;
-	        mm->cached_hole_size = 0;
+
+	if (len <= mm->cached_hole_size) {
+		mm->free_area_cache = TASK_UNMAPPED_BASE;
+		mm->cached_hole_size = 0;
 	}
+	addr = mm->free_area_cache;
+	if (addr < TASK_UNMAPPED_BASE)
+		addr = TASK_UNMAPPED_BASE;
+	start_addr = addr;
 
 full_search:
 	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
-- 
1.5.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ