Bug 559719 - (CVE-2010-0411) CVE-2010-0411 systemtap: Crash with systemtap script using __get_argv()
CVE-2010-0411 systemtap: Crash with systemtap script using __get_argv()
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
medium Severity medium
: ---
: ---
Assigned To: Red Hat Product Security
impact=moderate,source=redhat,reporte...
: Security
Depends On: 561886 561887 561888 561889 561890
Blocks:
  Show dependency treegraph
 
Reported: 2010-01-28 15:09 EST by Issue Tracker
Modified: 2015-08-19 04:43 EDT (History)
9 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-09-10 17:15:06 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Fix for __get_argv overflow (1.74 KB, patch)
2010-01-29 00:18 EST, Josh Stone
no flags Details | Diff
Rewrite __get_argv without embedded-C (103 bytes, text/plain)
2010-02-04 21:49 EST, Josh Stone
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
Sourceware 11234 None None None Never

  None (edit)
Description Issue Tracker 2010-01-28 15:09:27 EST
Escalated to Bugzilla from IssueTracker
Comment 1 David Jeffery 2010-01-28 15:12:54 EST
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.
Comment 2 Josh Stone 2010-01-28 17:10:37 EST
I've confirmed the issue and filed it upstream:
http://sourceware.org/bugzilla/show_bug.cgi?id=11234
Comment 6 Frank Ch. Eigler 2010-01-28 20:31:23 EST
A quick workaround/fix in the form of a patch to a file under /usr/share/systemtap/tapset is likely.
Comment 7 Josh Stone 2010-01-29 00:18:40 EST
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
Comment 13 Vincent Danen 2010-02-04 10:57:34 EST
This has been assigned CVE-2010-0411
Comment 21 Josh Stone 2010-02-04 21:49:27 EST
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.
Comment 27 Fedora Update System 2010-02-15 13:07:24 EST
systemtap-1.1-2.fc11 has been submitted as an update for Fedora 11.
http://admin.fedoraproject.org/updates/systemtap-1.1-2.fc11
Comment 28 Fedora Update System 2010-02-15 13:07:40 EST
systemtap-1.1-2.fc12 has been submitted as an update for Fedora 12.
http://admin.fedoraproject.org/updates/systemtap-1.1-2.fc12
Comment 29 Fedora Update System 2010-02-18 17:23:13 EST
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.
Comment 30 Fedora Update System 2010-02-18 17:36:23 EST
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.
Comment 31 errata-xmlrpc 2010-03-01 14:02:58 EST
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
Comment 32 errata-xmlrpc 2010-03-01 14:19:51 EST
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
Comment 35 David Smith 2010-03-09 10:19:09 EST
(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.

Note You need to log in before you can comment on or make changes to this bug.