8000 Python -builtin segfault if attempt to delete struct member · Issue #3203 · swig/swig · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Python -builtin segfault if attempt to delete struct member #3203
Closed
@jim-easterbrook

Description

@jim-easterbrook

I've found a bug if a user tries to delete an attribute of a struct wrapped with SWIG.

Example interface file struct_del_member_segfault.i:

%module struct_del_member_segfault

%inline %{
struct Foo {
  int x;
};
%}

Extension built with setup.py

from distutils.core import setup, Extension

setup (name = 'struct_del_member_segfault',
       ext_modules = [Extension(
           '_struct_del_member_segfault',
           sources=['struct_del_member_segfault_wrap.c'])],
       py_modules = ["struct_del_member_segfault"],
       )

Test file test.py:

import struct_del_member_segfault

s = struct_del_member_segfault.Foo()
print('get member')
print(s.x)
print('set member')
s.x = 123
print('del member')
del s.x

Build and run:

$ swig -python -builtin -nofastunpack struct_del_member_segfault.i 
$ python3 setup.py build_ext --inplace
running build_ext
building '_struct_del_member_segfault' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -DOPENSSL_LOAD_CONF -fwrapv -fno-semantic-interposition -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -I/usr/include/python3.6m -c struct_del_member_segfault_wrap.c -o build/temp.linux-x86_64-3.6/struct_del_member_segfault_wrap.o
gcc -pthread -shared build/temp.linux-x86_64-3.6/struct_del_member_segfault_wrap.o -L/usr/lib64 -lpython3.6m -o /home/jim/Documents/projects/swig/bugs/struct_del_member_segfault/_struct_del_member_segfault.cpython-36m-x86_64-linux-gnu.so
$ python3 test.py 
get member
0
set member
del member
Segmentation fault (core dumped)

If I omit the -nofastunpack option I get a slightly better result:

$ python3 test.py 
get member
0
set member
del member
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    del s.x
SystemError: error return without exception set

The segfault occurs in SwigPyBuiltin_SetterClosure, which is passed a NULL value to delete the attribute. It calls SWIG_Py_INCREF on the NULL, causing a segfault.

A possible cure is to add the following to SwigPyBuiltin_SetterClosure and SwigPyBuiltin_FunpackSetterClosure:

  if (!val) {
    PyErr_Format(PyExc_TypeError, "Illegal member variable deletion in type '%.300s'", obj->ob_type->tp_name);
    return -1;
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0