[ python-Bugs-1003471 ] Python 1.5.2 security vulnerability still
present in 2.3.4
SourceForge.net
noreply at sourceforge.net
Mon Aug 9 19:56:06 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: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Kirby Kuehl (vacuum)
Assigned to: Nobody/Anonymous (nobody)
Summary: Python 1.5.2 security vulnerability still present in 2.3.4
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-09 13:56
Message:
Logged In: YES
user_id=31435
The patch didn't intend to fix a bug that's known to exist.
Python 2.0 presumably fixed the bugs here, but in a shaky
way, relying on dozens of distinct call sites to establish an
undocumented precondition. joinpath() suffers a buffer
overrun if the precondition isn't met. The patch verifies that
the precondition *is* met, killing the Python process if it's
not. That should never happen, but joinpath() is called on so
many distinct code paths that "eyeball analysis" is inadequate.
To test the patch, change any of joinpath's call sites to
violate the precondition, and see that Python dies then. The
OP suggested a driver to provoke an envar attack, in the
2004-08-07 14:15 comment.
----------------------------------------------------------------------
Comment By: A.M. Kuchling (akuchling)
Date: 2004-08-09 13:39
Message:
Logged In: YES
user_id=11375
How would I go about testing the patch? Where can I find
code that tickles the bug?
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2004-08-07 21:01
Message:
Logged In: YES
user_id=31435
I checked in the attached patch too. If there's ever another
release in the 2.3 line, these patches would make decent
backport candidates.
----------------------------------------------------------------------
Comment By: Kirby Kuehl (vacuum)
Date: 2004-08-07 18:19
Message:
Logged In: YES
user_id=116409
As tim_one poin
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2004-08-07 15:15
Message:
Logged In: YES
user_id=31435
Unassigned myself, since I did all I can here. Someone on
Linux should test the patch I attached.
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2004-08-07 15:13
Message:
Logged In: YES
user_id=31435
I checked in the change to PC/getpathp.c, which is used on
Windows. I'm attaching a patch to Modules/getpath.c, which
isn't used on Windows (so I can't test it).
----------------------------------------------------------------------
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