This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PyArg_ParseTupleAndKeywords potential core dump
Type: Stage:
Components: Interpreter Core Versions: Python 2.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: ehuss, georg.brandl
Priority: release blocker Keywords:

Created on 2006-07-17 02:23 by ehuss, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg29190 - (view) Author: Eric Huss (ehuss) Date: 2006-07-17 02:23
After getting bit by bug 893549, I was noticing that
sometimes I was getting a core dump instead of a
TypeError when PyArg_ParseTupleAndKeywords was skipping
over a type the "skipitem" code does not understand.

There are about 4 problems I will describe (though they
are related, so it's probably not worth filing seperate
bugs).

The problem is that the "levels" variable is passed to
the seterror function uninitialized.  If levels does
not happen to contain any 0 elements, then the
iteration code in seterror will go crazy (I will get to
this in a moment).

In the one place where "skipitem" is called, you will
notice it immediately calls seterror() if it returned
an error message.  However, "levels" is not set by the
skipitem function, and thus seterror iterates over an
uninitialized value.  I suggest setting levels[0] = 0
somewhere in the beginning of the code, since the
expectations of setting the "levels" seems awefully
delicate.

(As a side note, there's no bounds checking on the
levels variable, either.  It seems unlikely that
someone will have 32 levels of nested variables, but I
think it points to a general problem with how the
variable is passed around.)

A second fix is to set levels[0] = 0 if setitem fails
before calling seterror().

Now, returning to the "seterror goes crazy" problem I
mentioned earlier, the following code in the seterror
function:

while (levels[i] > 0 && (int)(p-buf) < 220) {

should be:

while (levels[i] > 0 && (int)(p-buf) > 220) {

At least, that's what I'm assuming it is supposed to
be.  I think it should be clear why this is bad.

But wait, there's more!  The snprintf in seterror call
uses the incorrect size of buf.  The following line:

PyOS_snprintf(p, sizeof(buf) - (buf - p),

should be:

PyOS_snprintf(p, sizeof(buf) - (p - buf),

My particular platform (FreeBSD) puts a NUL character
at the end of the buffer.  However, since the size of
the buffer is computed incorrectly, this line of code
stomps on the stack (overwritting the levels value in
my case).

Let me know if you have any questions, or want any
sample code.
msg29191 - (view) Author: Eric Huss (ehuss) Date: 2006-07-17 02:28
Logged In: YES 
user_id=393416

Oops, skip the section about <220 being >220.  I've been
staring at it too long.  The rest of the issues should be
valid, though.
msg29192 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-07-26 08:04
Logged In: YES 
user_id=849994

Fixed the "levels[0] = 0" and the "p-buf" issue in rev.
50843.  Still waiting for input on python-dev about the
levels overflow, though I think it can be ignored.
msg29193 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-08-09 07:08
Logged In: YES 
user_id=849994

Fixed the "levels overflow" problem by introducing an upper
bound on the tuple nesting depth in rev. 51158.
History
Date User Action Args
2022-04-11 14:56:18adminsetgithub: 43681
2006-07-17 02:23:25ehusscreate