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: Segfault in c_char_p of ctypes
Type: Stage:
Components: Extension Modules Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: theller Nosy List: belopolsky, nnorwitz, seb_martini, theller
Priority: high Keywords:

Created on 2007-04-16 10:45 by seb_martini, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
c_char_p.patch theller, 2007-04-20 19:52 Patch for printing c_char_p without crashing
c_char_p_2.patch theller, 2007-06-08 17:01 Second patch
Messages (10)
msg31813 - (view) Author: sebastien Martini (seb_martini) Date: 2007-04-16 10:45
Hi,

I experienced a segmentation fault (when providing a wrong argument type to c_char_p) in the ctypes module under Linux and with the version 2.5 .


sundae:~$ python
Python 2.5.1c1 (release25-maint, Apr  6 2007, 22:02:36) 
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> c_char_p(42)
zsh: segmentation fault (core dumped)  python
sundae:~$  


Regards,

Sebastien Martini
msg31814 - (view) Author: sebastien Martini (seb_martini) Date: 2007-04-16 19:40
c_wchar_p also contains this bug.


msg31815 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2007-04-18 07:37
Thanks for the bug report Sebastien.

This bug occurs in 2.5 and in the trunk, so it's not a regression.  Thomas, could you take a look?  Integers are specifically allowed here (floats are not).  The problem is when trying to print the repr:

#0  PyString_FromString (str=0x2a <Address 0x2a out of bounds>) at Objects/stringobject.c:108
#1  z_get (ptr=0x2ae1aa9d6450, size=8) at Modules/_ctypes/cfield.c:1373
#2  Simple_get_value (self=0x2ae1aa9d63f8) at Modules/_ctypes/_ctypes.c:4007
#3  Simple_repr (self=0x2ae1aa9d63f8) at Modules/_ctypes/_ctypes.c:4095
#4  PyObject_Repr (v=0x2ae1aa9d63f8) at Objects/object.c:361
msg31816 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2007-04-18 19:20
This is a difficult issue.  The integer (which is interpreted as address) is allowed because some libraries use 'char *' pointers initialized to small, invalid addresses for special purposes.

On windows, printing a c_char_p(42) does not crash, it raises a ValueError instead:
>>> from ctypes import *
>>> c_char_p(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid string pointer 0x00B20B48
>>>

Windows does this by checking if there is a valid string at the address (see Modules/_ctypes/cfield.c, line 1366) by calling the IsBadStringPointer api function.  Do other platforms have a function that can do this check?

If not, I'm afraid we would have to give up on the very convenient repr of 'normal' c_char_p instances:

>>> c_char_p("foo bar")
c_char_p('foo bar')
>>>

and only print the address (at least on non-windows).
msg31817 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2007-04-19 06:58
> Do other platforms have a function that can do this check?

There's no platform independent way to do this.

I don't know anything about ctypes, but what might be a way to handle this is providing a way to convert an integer into a pointer (like a void*).  Then all these routines could accept this void* type that you would define, but not accept a raw integer.  That means people would still have access to do the same thing they can currently do, but it would be clearer that they are playing with fire by converting any int into a pointer.

There are so many ways to use ctypes to crash, I'm not sure if this is worth fixing, except perhaps in the docs to point out the issues.
msg31818 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2007-04-19 20:47
It is easy to distinguish between a c_char_p that is created from a python string from one that is created from a python int: the former has an _objects attribute set to a string:

>>> x,y = map(c_char_p, ('abc',42))
>>> (x._objects,y._objects)
('abc', None)

It may be reasonable to give up a "nice" repr for the cases where c_char_p is not known to point into a python string. You can still keep "nice" str, so users can still enjoy a crash by printing c_char_p(42). :-)
msg31819 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2007-04-20 19:52
belopolsky:  _objects is only set when the c_char_p instance is created in the way you described.  It will not be set if the instance is modified by a foreign function call, so this is not robust.

nnorwitz: Sure there are many ways to crash Python with ctypes, but printing c_char_p(42) should not carsh, IMO.

I believe the best strategy would be to behave this way on Windows where the check for a valid string pointer can be made:

>>> c_char_p(42)
c_char_p(0x2A)
>>> c_char("foo")
c_char('foo')
>>>

and this way on other systems:

>>> c_char_p(42)
c_char_p(0x2A)
>>> c_char_p("foo")
c_char_p(0x2A7F3B)
>>>

The attached patch fixes this for c_char_p, a similar patch should be applied to c_wchar_p.
File Added: c_char_p.patch
msg31820 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2007-04-20 20:42
theller: [_objects] will not be set if the instance is modified by a foreign function call, so this is not robust.

I thought about this before making my suggestion.  I believe people will be less surprized if objects returned from an ffi call print with funny numbers than getting c_char_p(NNNNN) after entering c_char_p("abc"). 

A few comments on the patch:

1. Since c_void_p is printed in decimal, shouldn't c_char_p be treated the same? If hexadecimal is prefered, maybe c_void_p should be changed.

2. Currently c_char_p(0) is printed as c_char_p(None), but the patch will change that to c_char_p(0).
msg31821 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2007-06-08 17:01
Here's a patch that fixes the problems that belopolsky mentions: c_char_p_2.patch
File Added: c_char_p_2.patch
msg31822 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2007-07-13 17:14
Committed as SVN rev 56351 (release25-maint) and rev 56352 (trunk).
History
Date User Action Args
2022-04-11 14:56:23adminsetgithub: 44854
2007-04-16 10:45:20seb_martinicreate