[Boost-bugs] [Boost C++ Libraries] #8978: Segfault crash in boost.python with keyword arguments and overloads.

Subject: [Boost-bugs] [Boost C++ Libraries] #8978: Segfault crash in boost.python with keyword arguments and overloads.
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-08-08 18:28:09


#8978: Segfault crash in boost.python with keyword arguments and overloads.
------------------------------+-------------------------
 Reporter: amohr@… | Owner: rwgk
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: Python
  Version: Boost 1.51.0 | Severity: Showstopper
 Keywords: |
------------------------------+-------------------------
 Please see the thread on the python c++ sig email list here (lacking
 protocol prefix to pass spam check):
 mail.python.org/pipermail/cplusplus-sig/2013-August/017012.html

 Here is a minimal repro case:
 ------------------------------------------------
 // C++
 #include <boost/python.hpp>

 static void f1(int a0, int a1) { }
 static void f2(int a0, int a1, int a2) { }

 BOOST_PYTHON_MODULE(kwargCrash) {
     boost::python::def("f", f1, (arg("a1")=2));
     boost::python::def("f", f2, (arg("a2")=2));
 }

 # Python
 import kwargCrash
 kwargCrash.f(0, a1=2)
 ------------------------------------------------

 Version found info: boost 1.51.0, Python 2.7.5, gcc 4.8.1.

 Please see the list thread linked above for a detailed explanation of why
 the crash occurs. In short, boost.python calls PyTuple_GET_ITEM() on
 None, and then unconditionally uses the result as a key to look up in a
 dict. This boost.python code hasn't changed in a long time. I suspect
 Python has changed, and is now returning NULL here instead of None, and
 calling PyDict_GetItem with NULL crashes.

 Here is a patch to the boost.python code that fixes the bug. It simply
 checks to see if it got None from the m_arg_names tuple, and if so, that
 means the overload does not accept a keyword arg in that position, so it
 rejects the overload. This fixes the crash and works correctly across our
 codebase and testsuite.

 If the patch looks good, it would be great to apply it and add the repro
 case to the test suite.

 Thanks!

 --- ./libs/python/src/object/function.cpp.orig 2013-07-22
 17:38:54.000000000 -0700
 +++ ./libs/python/src/object/function.cpp 2013-08-07
 10:25:26.963988000 -0700
 @@ -182,6 +182,16 @@
                              // Get the keyword[, value pair]
 corresponding
                              PyObject* kv =
 PyTuple_GET_ITEM(f->m_arg_names.ptr(), arg_pos);

 + // If kv is None, this overload does not
 accept a
 + // keyword argument in this position, meaning
 that
 + // the caller did not supply enough
 positional
 + // arguments. Reject the overload.
 + if (kv == Py_None) {
 + PyErr_Clear();
 + inner_args = handle<>();
 + break;
 + }
 +
                              // If there were any keyword arguments,
                              // look up the one we need for this
                              // argument position

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8978>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC