[ python-Bugs-1077106 ] Negative numbers to os.read() cause segfault

SourceForge.net noreply at sourceforge.net
Sun Dec 5 11:30:29 CET 2004


Bugs item #1077106, was opened at 2004-12-01 21:40
Message generated for change (Comment added) made by mwh
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1077106&group_id=5470

Category: Python Interpreter Core
Group: Python 2.4
Status: Open
Resolution: Accepted
Priority: 5
Submitted By: Jp Calderone (kuran)
Assigned to: Michael Hudson (mwh)
Summary: Negative numbers to os.read() cause segfault

Initial Comment:
Python 2.3.4 (#2, Sep 24 2004, 08:39:09)
[GCC 3.3.4 (Debian 1:3.3.4-12)] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> import sys, os
>>> stdin = sys.stdin.fileno()
>>> os.read(stdin, 0)
''
>>> os.read(stdin, 0)
''
>>> os.read(stdin, -1)
asdkljasd
'asdk\x01\x00\x00\x00\x00\x00'
>>> os.read(stdin, 100)
Segmentation fault
exarkun at boson:~$

This problem persists in Python 2.4, although the
resulting incorrect behavior differs slightly (at least
on my build), as is to be expected of a memory
corrupting bug.

Note that the value returned from os.read(stdin, -1) is
incorrect in addition to the subsequent read segfaulting.


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

>Comment By: Michael Hudson (mwh)
Date: 2004-12-05 10:30

Message:
Logged In: YES 
user_id=6656

I'm waiting until I'm not behind a modem at my parents' house :)

Tomorrow.

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

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-12-05 00:39

Message:
Logged In: YES 
user_id=80475

No, I simply tried the OP's example and reported its
behavior on my system.

If you don't want to create a new test file, try adding this
on to test_subprocess.

Yes, I read the patch.  Yes, I forgot you added the
assertion already.

So are you going commit or wait for an engraved invitation?
 <wink>

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

Comment By: Michael Hudson (mwh)
Date: 2004-12-04 21:11

Message:
Logged In: YES 
user_id=6656

Hmm.  Did you try a debug build and/or a range of arguments?

Is os.read actually tested anywhere?  I can't find any...

> Also, you could prevent/detect future errors by adding an
> assertion (checking for negative arguments) to
> PyString_FromStringAndSize().

Did you read the patch? <wink>

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

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-12-04 20:58

Message:
Logged In: YES 
user_id=80475

No doubt it is a clear bug.  My note was just a data point.
 Had I been able to reproduce the error on my machine, I
would have been able to make a test_case and checkin a fix.

So, please, if you can demonstrate the error, go ahead and
check-in a fix with a testcase.

The OSError is probably fine though there is an alternative
of having a ValueError raised immediately after the args are
parsed in the read() method.

Also, you could prevent/detect future errors by adding an
assertion (checking for negative arguments) to
PyString_FromStringAndSize().

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

Comment By: Michael Hudson (mwh)
Date: 2004-12-04 20:38

Message:
Logged In: YES 
user_id=6656

I'm surprised at all this discussion.  It's a clear bug.  The only question is 
what the error message should be.  The attached makes it 

OSError: [Errno 22] Invalid argument

which seems most faithful to what the read() syscall does.

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

Comment By: Gerrit Holl (gerrit)
Date: 2004-12-04 20:13

Message:
Logged In: YES 
user_id=13298

FWIW, another data point, Python 2.4., Linux 2.6.9, Fedora
Core 3:

$ python2.4 t.py < /usr/src/linux/README
Traceback (most recent call last):
  File "t.py", line 3, in ?
    os.read(0, -1)
OSError: [Errno 22] Invalid argument
$ python2.4 t.py < /dev/zero
Traceback (most recent call last):
  File "t.py", line 3, in ?
    os.read(0, -1)
OSError: [Errno 14] Bad address
$ python2.4 t.py < /dev/urandom
Segmentation fault

Interesting.

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

Comment By: George Yoshida (quiver)
Date: 2004-12-04 11:43

Message:
Logged In: YES 
user_id=671362

On Win2k(Python 2.3.4 & 2.4), I get:
>>> os.read(si, -1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OSError: [Errno 12] Not enough space

On Linux(SUSE 9.2 & kernel 2.6.5-7.108-smp & gcc 3.3.3) 
in Python 2.4 debug built, I get:

>>>os.read(si, -1)
asd
Debug memory block at address p=0x4024d6b8:
    31 bytes originally requested
    The 4 pad bytes at p-4 are FORBIDDENBYTE, as expected.
    The 4 pad bytes at tail=0x4024d6d7 are not all 
FORBIDDENBYTE
(0xfb):
        at tail+0: 0x0a *** OUCH
        at tail+1: 0xfb
        at tail+2: 0xfb
        at tail+3: 0xfb
    The block was made by call #10310 to debug 
malloc/realloc.
    Data at p: 00 00 00 00 00 00 00 00 ... ff 00 00 00 00 61 
73 64
Fatal Python error: bad trailing pad byte
Aborted

In a normal built, same as Jp.

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

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-12-04 04:29

Message:
Logged In: YES 
user_id=80475

In both Py2.3.4 and Py2.4, I get the following correct
behavior on WinME:

>>> os.read(si, -1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OSError: [Errno 22] Invalid argument


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

Comment By: James Y Knight (foom)
Date: 2004-12-01 23:11

Message:
Logged In: YES 
user_id=1104715

This appears to be because PyString_FromStringAndSize takes a signed int 
for size, doesn't verify that it is > 0, and then adds it to 
sizeof(PyStringObject):
    op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + 
size);

PyObject_MALLOC will fail if given a < 0 size, but, if size is > 
-sizeof(PyStringObject), the object will be allocated, but too small. Then, 
memory gets clobbered.

If it returned NULL like it should, posix_read's error handling would be 
fine.


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

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


More information about the Python-bugs-list mailing list