BBS水木清华站∶精华区
发信人: lenx (冷·枫), 信区: Linux
标 题: [安全] Non-executable user stack and symlink fix
发信站: BBS 水木清华站 (Mon Nov 24 22:01:15 1997)
Linux目前安全的最佳方案, 对stack overflow和symlink的攻击都有了相当好的防范
ftp://ftp.sepc.ac.cn/pub/linux/collect/system/kernel/linux-stack-symlink.tgz
(sepc只对166.111/159.226/162.105开放)
Non-executable user stack area and symlink fix -- Linux kernel patch
----------------------------------------------------------------------
==========
Overview
==========
This patch is intended to add protection against two classes of security
holes: buffer overflows and symlinks in /tmp.
Most buffer overflow exploits are based on overwriting a function's return
address on the stack to point to some arbitrary code, which is also put
onto the stack. If the stack area is non-executable, buffer overflow
vulnerabilities become harder to exploit.
Another way to exploit a buffer overflow is to point the return address to
a function in libc, usually system(). This patch also changes the default
address that shared libraries are mmap()ed at to make it always contain a
zero byte. This makes it impossible to specify any more data (parameters
to the function, or more copies of the return address when filling with a
pattern) in an exploit that has to do with ASCIIZ strings (this is the
case for most overflow vulnerabilities).
However, note that this patch is by no means a complete solution, it just
adds an extra layer of security. Some buffer overflow vulnerabilities will
still remain exploitable a more complicated way. The reason for using such
a patch is to protect against some of the buffer overflow vulnerabilities
that are yet unknown.
In this version of my patch I also added a symlink security fix, originally
by Andrew Tridgell. I changed it to prevent from using hard links too, by
simply not allowing non-root users to create hard links to files they don't
own, in +t directories. This seems to be the desired behavior anyway, since
otherwise users couldn't remove such links they just created. I also added
exploit attempt logging, this code is shared with the non-executable stack
stuff, and was the reason to make it a single patch instead of two separate
ones. You can enable them separately anyway.
================
How to install
================
Apply the patch. Enable prompting for experimental code in your kernel
configuration, enable the patch itself (in General setup section). Read
help for the suboptions, and configure them. Also, enable the symlink fix
(in Filesystems section). Build the kernel and reboot.
You may also want to add the following line to your /etc/syslog.conf to
log [security] alerts separately:
kern.alert /var/log/alert
Additionally, you may do something like this (assuming the log file will
be empty most of the time):
> /var/log/alert
chown root.staff /var/log/alert
chmod 640 /var/log/alert
echo "more /var/log/alert" >> ~your_usual_non-root_account/.bash_profile
chattr +a /var/log/alert
[ The last command doesn't do much -- there're too many ways to get around
securelevel in Linux right now: loading a kernel module, writing to the
hard disk device, using iopl() and writing to the hard disk via ports...
This can't be done over NFS however... ]
Ensure that the patch is working correctly, use stacktest.c for that --
running './stacktest -e' should segfault, and a message about possible
buffer overflow exploit attempt should get logged to /var/log/alert (with
syslogd configuration described above, and if you have logging enabled).
If you enabled GCC trampolines autodetection, try running './stacktest -t',
it should succeed.
Also, check the address libc is mmap()ed at, its MSB should be zero instead
of 0x40 like it was before. Use a command like this:
strace /bin/ls 2>&1 | grep mmap\[^\|\]\*\|PROT_EXEC | sed s/\[^=\]\*=//
If you enabled the symlink fix you can also try to create a symlink in /tmp
(as a non-root user) pointing to a file that user has no read access to,
then switch to some other user that has the read access (for example, root)
and try to read the file via the link (like, cat /tmp/link). This should
fail, and a message should get logged (if enabled). Everything is similar
for write access, and for symlinks to files that don't exist. Now, you can
try to create a hard link in /tmp as a non-root user to a file that user
doesn't own. This should also fail.
========
F.A.Q.
========
Q: Will GCC-compiled programs that use trampolines work with the patch?
A: Yes, read help for the 'Autodetect GCC trampolines' configuration option.
Q: How do you differ a trampoline call from an exploit attempt?
A: Since most buffer overflow exploits overwrite the return address, the
instruction to pass control to the stack has to be a RET. With trampoline
calls the instruction is a CALL. However, in some cases such trampoline
autodetection can be fooled by RET'ing to a CALL instruction and making
this CALL pass control onto the stack (in reality, this also requires a
register to be set to the address). Again, read help for the 'Autodetect
GCC trampolines' configuration option.
Q: What is chstk.c for?
A: The patch adds an extra flag to ELF and a.out headers, which controls
whether the program will be allowed to execute code on the stack or not,
and chstk.c is what you should use to manage the flag. You might find it
useful if you choose to disable the GCC trampolines autodetection. BTW,
setting the flag also restores the original address shared libraries are
mmap()ed at, just in case some program depends on that.
Q: Why did you modify signal handler return code?
A: Originally the kernel put some code onto the stack to return from signal
handlers. Now signal handler returns are done via the GPF handler instead
(an invalid magic return address is put on the stack).
Q: What to do if a program needs to follow a symlink in a +t directory for
its normal operation (without introducing a security hole)?
A: Usually such a link needs to be created only once, so create it as root.
Such links are followed even when the patch is enabled.
Q: What will happen if someone does:
ln -s /etc/passwd ~/link
ln -s ~/link /tmp/link
and the vulnerable program runs as root and writes to /tmp/link?
A: The patch is not looking at the target of the symlink in /tmp, it only
checks if the symlink itself is owned by the user that vulnerable program
is running as, and doesn't follow the link if not (like in this example).
Q: Is there some performance impact of using the patch?
A: Well, the only thing affected is singal handler returns. I didn't want
to modify the sigreturn syscall, so there is some extra code to setup its
stack frame. I don't think this has a noticable effect on the performance:
saved context checks and other signal handling stuff are taking much more
time. Also, executing code on the stack was not fast anyway.
Signed,
Solar Designer <solar@false.com>
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.118.33]
BBS水木清华站∶精华区