Escalated to Bugzilla from IssueTracker
The length checking in the __get_argv() function in systemtap's tapset is faulty. This failure can result in buffer overflows which will overwrite memory not controlled by systemtap. The usual symptom is a crash from the slab do to a slab structure being overwritten. Memory corruption can be triggered by anyone if a systemtap script using __get_argv() or the probe point syscall.execve is running. A user just needs to start processes with very large argv lists. The problem is caused by the improper handling of the return code from strlcpy(). The code in __get_argv(): rc = strlcpy (str, buf, len); str += rc; len -= rc; treats the return code as the amount of memory copied. But it's not. strlcpy() returns the equivalent of strlen(buf) which can be greater than len. When copying multiple argv strings, this can result in len going negative. And the len checks in __get_argv check for 0. With len negative, __get_argv will continue copying the argv and overflow the memory buffer. Steps to reproduce: This is can be reproduced with a very minimal systemtap script. Run the systemtap script: probe syscall.execve { printf("%s\n", args); } The probe point syscall.execve uses __get_argv() internally to create the variable args. Then, as any user run a loop executing a process with a really long arg list. For example, "/bin/echo <ABSOLUTE_PATH_TO_KERNEL>/include/*/*" to get a huge arg list. (Don't use the shell's built-in echo!) and occasionally dump /proc/slabinfo to force a walk of the slab structures. #!/bin/bash while [ "0" = "0" ] ; do HOME=1 /bin/echo /usr/src/kernels/2.6.18-128.el5-PAE-i686/include/*/* cat /proc/slabinfo done The test system would usually crash in under 30 seconds with the systemtap and shell script running.
I've confirmed the issue and filed it upstream: http://sourceware.org/bugzilla/show_bug.cgi?id=11234
A quick workaround/fix in the form of a patch to a file under /usr/share/systemtap/tapset is likely.
Created attachment 387497 [details] Fix for __get_argv overflow Here is a patch for /usr/share/systemtap/tapset/aux_syscall.stp, taken from upstream commit f754097. I believe that __get_argv is sufficiently hardened with this fix, but let me know if you see anything else. Thanks, Josh
This has been assigned CVE-2010-0411
Created attachment 388943 [details] Rewrite __get_argv without embedded-C We believe that this patch is preferable: the vulnerable functions are now written in the native script language, with all the protection that entails.
systemtap-1.1-2.fc11 has been submitted as an update for Fedora 11. http://admin.fedoraproject.org/updates/systemtap-1.1-2.fc11
systemtap-1.1-2.fc12 has been submitted as an update for Fedora 12. http://admin.fedoraproject.org/updates/systemtap-1.1-2.fc12
systemtap-1.1-2.fc11 has been pushed to the Fedora 11 stable repository. If problems still persist, please make note of it in this bug report.
systemtap-1.1-2.fc12 has been pushed to the Fedora 12 stable repository. If problems still persist, please make note of it in this bug report.
This issue has been addressed in following products: Red Hat Enterprise Linux 5 Via RHSA-2010:0124 https://rhn.redhat.com/errata/RHSA-2010-0124.html
This issue has been addressed in following products: Red Hat Enterprise Linux 4 Via RHSA-2010:0125 https://rhn.redhat.com/errata/RHSA-2010-0125.html
Upstream patch: http://sourceware.org/git/gitweb.cgi?p=systemtap.git;a=patch;h=a2d399c87a642190f08ede63dc6fc434a5a8363a
(In reply to comment #34) > Upstream patch: > http://sourceware.org/git/gitweb.cgi?p=systemtap.git;a=patch;h=a2d399c87a642190f08ede63dc6fc434a5a8363a Actually, that patch, depending on the systemtap version, might or might not be the patch used to fix the problem. Here's some history. Originally, Josh fixed the embedded-C version of this function in this patch: <http://sources.redhat.com/git/gitweb.cgi?p=systemtap.git;a=commitdiff;h=f75409719f120a3dbee66d761cf23a64092d1414> Then, he decided to rewrite __get_argv without embedded-C. That's the patch you referenced. The "rewrite __get_argv without embedded-C" patch uses a systemtap feature that is only present in systemtap version 1.1 and up. I'm referring to the "preprocessor conditional for kernel configuration testing" feature (which looks like "%( CONFIG_foo == "y" %? ... %)"). We decided to avoid backporting that new feature to older versions of systemtap. So, versions of systemtap less than 1.1 have gotten the original fix (where Josh fixed the embedded-C version of __get_argv). Systemtap versions of 1.1 or higher have gotten the "rewrite __get_argv without embedded-C" patch.