[ python-Bugs-1003471 ] Python 1.5.2 security vulnerability

SourceForge.net noreply at sourceforge.net
Sat Aug 7 20:44:23 CEST 2004


Bugs item #1003471, was opened at 2004-08-04 14:42
Message generated for change (Comment added) made by tim_one
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1003471&group_id=5470

Category: Python Interpreter Core
Group: Platform-specific
Status: Open
Resolution: None
Priority: 5
Submitted By: Kirby Kuehl (vacuum)
>Assigned to: Tim Peters (tim_one)
Summary: Python 1.5.2 security vulnerability

Initial Comment:
First off, I realize that Python 1.5.2 is old, I am just 
reporting it to be thorough.

I was doing a security audit of an application that used 
this old version of python and found the following bug in 
the joinpath function.

#0  0xff133bf0 in strncpy () from /usr/lib/libc.so.1
(gdb) bt

#0  0xff133bf0 in strncpy () from /usr/lib/libc.so.1
(gdb) bt
#0  0xff133bf0 in strncpy () from /usr/lib/libc.so.1
#1  0x000304e0 in joinpath (buffer=0x83528 'A' 
<repeats 200 times>..., 
    stuff=0x84140 'A' <repeats 200 times>...) 
at ./getpath.c:255
#2  0x00030604 in search_for_prefix 
(argv0_path=0xffbff530 "/opt/OPSW/bin", 
    home=0xff3a0840 'A' <repeats 200 times>...) 
at ./getpath.c:300
#3  0x00030a48 in calculate_path () at ./getpath.c:481
#4  0x00030e6c in Py_GetProgramFullPath () 
at ./getpath.c:634
#5  0x0002dcac in _PySys_Init () at sysmodule.c:413
#6  0x0002b414 in Py_Initialize () at pythonrun.c:142
#7  0x0001755c in Py_Main (argc=1, argv=0xffbffcdc) 
at main.c:245
#8  0x000171f0 in main (argc=1, argv=0xffbffcdc) at 
python.c:12
#8  0x000171f0 in main (argc=1, argv=0xffbffcdc) at 
python.c:12
(gdb) frame 1
#1  0x000304e0 in joinpath (buffer=0x83528 'A' 
<repeats 200 times>..., 
    stuff=0x84140 'A' <repeats 200 times>...) 
at ./getpath.c:255
255     ./getpath.c: No such file or directory.
        in ./getpath.c


snippet from Python-1.5.2/Modules/getpath.c :

static void
joinpath(buffer, stuff)
    char *buffer;
    char *stuff;
{
    int n, k;
    if (stuff[0] == SEP)
        n = 0;
    else {
        n = strlen(buffer);
        if (n > 0 && buffer[n-1] != SEP && n < 
MAXPATHLEN)
            buffer[n++] = SEP;
    }
    k = strlen(stuff);
    if (n + k > MAXPATHLEN)
        k = MAXPATHLEN - n;
    strncpy(buffer+n, stuff, k);
    buffer[n+k] = '\0';
}

further examining the backtrace:
(gdb) print n
$1 = 4999
(gdb) print k
$2 = -3975

(gdb) print buffer
$4 = 0x83528 'A' <repeats 200 times>...
(gdb) print stuff
$5 = 0x84140 'A' <repeats 200 times>...

if (n + k > MAXPATHLEN) /* NOTE: MAXPATHLEN is 1024 
*/
        k = MAXPATHLEN - n; /* NOTE: here k is 1024 - 
4999  which is the -3975 */

Which of course crashes in strncpy(buffer+n, stuff, k);


Thanks,
Kirby Kuehl





----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2004-08-07 14:44

Message:
Logged In: YES 
user_id=31435

I'm going to add the panic-check I suggested -- this code is 
too complicated to have any confidence in "eyeball analysis" 
over time.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-08-07 14:39

Message:
Logged In: YES 
user_id=31435

Yup, and rev 1.32 intended to plug the envar attack.

----------------------------------------------------------------------

Comment By: Kirby Kuehl (vacuum)
Date: 2004-08-07 14:15

Message:
Logged In: YES 
user_id=116409

by exporting environment variables. Check sharefuzz which
can be found here:
http://www.atstake.com/research/tools/index.html#vulnerability_scanning


----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-08-07 12:43

Message:
Logged In: YES 
user_id=31435

Pretty compilcated internally.  A very similar joinpath still 
exists.  While it's not documented or checked, joinpath's code 
clearly *assumes* strlen(buffer) <= MAXPATHLEN on entry.  
But it's called from 25 places, and it's not immediately obvious 
that all call sites guarantee this on all paths.

Rev 1.32 of getpath (for Python 2.0) *intended* to fix buffer 
overflow problems, mostly by changing unsafe strcpy() calls 
to strncpy() calls.

This is delicate, though.  I'd be a lot happier if joinpath 
verified that n <= MAXPATHLEN on entry, and called 
Py_FatalError() if not so (converting a buffer overrun into a 
bug report).

----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2004-08-07 11:55

Message:
Logged In: YES 
user_id=6656

I'm not sure I understand.  How do you get n to be so huge?

At any rate, I don't think the bug is present in modern Python, but 
until I understand how this one was triggered, I'm not prepared to 
be sure...

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1003471&group_id=5470


More information about the Python-bugs-list mailing list