Bug 559719 (CVE-2010-0411) - CVE-2010-0411 systemtap: Crash with systemtap script using __get_argv()
Summary: CVE-2010-0411 systemtap: Crash with systemtap script using __get_argv()
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2010-0411
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard: impact=moderate,source=redhat,reporte...
Depends On: 561886 561887 561888 561889 561890
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-01-28 20:09 UTC by Issue Tracker
Modified: 2019-06-08 12:54 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-09-10 21:15:06 UTC


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


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2010:0124 normal SHIPPED_LIVE Important: systemtap security update 2010-03-01 19:02:50 UTC
Sourceware 11234 None None None Never
Red Hat Product Errata RHSA-2010:0125 normal SHIPPED_LIVE Moderate: systemtap security update 2010-03-01 19:19:42 UTC

Description Issue Tracker 2010-01-28 20:09:27 UTC
Escalated to Bugzilla from IssueTracker

Comment 1 David Jeffery 2010-01-28 20:12:54 UTC
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 22:10:37 UTC
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-29 01:31:23 UTC
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 05:18:40 UTC
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 15:57:34 UTC
This has been assigned CVE-2010-0411

Comment 21 Josh Stone 2010-02-05 02:49:27 UTC
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 18:07:24 UTC
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 18:07:40 UTC
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 22:23:13 UTC
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 22:36:23 UTC
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 19:02:58 UTC
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 19:19:51 UTC
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 15:19:09 UTC
(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.