aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2009-07-26 09:39:42 +0200
committerWilly Tarreau <w@1wt.eu>2009-07-26 14:19:29 +0200
commit0a2155d9feb1a916a568b209336b4023d6f164de (patch)
tree86f853368f00fcedbb4924ff8082e2c280aff384
parentd34496c0f78a60182ba99f2228d4cec7815efaea (diff)
downloadlinux-2.4-0a2155d9feb1a916a568b209336b4023d6f164de.tar.gz
personality: clear MMAP_PAGE_ZERO on exec if mmap_min_addr is set
Patch related to commit f9fabcb58a6d26d6efde842d1703ac7cfa9427b6 in 2.6. Executing an SVR4 binary causes page 0 to be mapped, bypassing the mmap_min_addr setting. The kernel detects SVR binaries by checking the ELF interpreter's name declared in the executable. Unfortunately, some archs (at least x86_64) allow the caller of the executable to change the personality to SVR4 before calling execve() and this personality will remain in the callee (similar to what is done in 2.6). This poses a problem because on such archs, if a setuid program is called with that personality set, it will automatically receive a mapped page 0 regardless of mmap_min_addr restrictions. Even if it later drops privileges to call unsafe code, this unsafe code will be able to change page 0 restrictions and use it as desired. As of now, x86_64 is the only arch known to work like this, and i386 and alpha are the only ones known not to be affected. The following patch closes this hole by clearing MMAP_PAGE_ZERO when mmap_min_addr is set. That way, legacy SVR4 binaries relying on page 0 to be mapped will still work when mmap_min_addr is not set, and people who don't run such binaries can maintain full protection by setting mmap_min_addr to non-zero. Special thanks go to Solar Designer for the time spent analysing the issues, impacts and workarounds on 2.4, as well as for proposing this patch. Further work is needed to make an inventory of each arch's behaviour. For more information, please refer to the 2.6 patch as well as Julien Tinnes and Tavis Ormandy's work on this subject. Reported-by: Solar Designer <solar@openwall.com> Signed-off-by: Willy Tarreau <w@1wt.eu>
-rw-r--r--fs/exec.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 87d06b14265bcb..c8d2dcfa75005f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -629,6 +629,9 @@ int flush_old_exec(struct linux_binprm * bprm)
current->task_dumpable = 1;
}
+ if (mmap_min_addr)
+ current->personality &= ~(unsigned long)MMAP_PAGE_ZERO;
+
name = bprm->filename;
for (i=0; (ch = *(name++)) != '\0';) {
if (ch == '/')