SquawkBirdies
SquawkBirdies

Reputation: 187

Python 3 C Extension Causes Segmentation Fault When Imported

I am trying to port this Python extension to work with Python 3. Python 3 made many changes to the Python C/C++ API that necessitate modifications to legacy modules' initialization and argument passing functions. So far, I have taken the old Python 2 code:

#include <Python.h>
#include <openssl/crypto.h>

static PyObject* SecureString_clearmem(PyObject *self, PyObject *str) {
    char *buffer;
    Py_ssize_t length;

    if (PyString_AsStringAndSize(str, &buffer, &length) != -1) {
        OPENSSL_cleanse(buffer, length);
    }
    return Py_BuildValue("");
}

static PyMethodDef SecureStringMethods[] = {
    {"clearmem", SecureString_clearmem, METH_O,
        PyDoc_STR("clear the memory of the string")},
    {NULL, NULL, 0, NULL},
};

PyMODINIT_FUNC initSecureString(void)
{
    (void) Py_InitModule("SecureString", SecureStringMethods);
}

And I have made this, following this example:

#define PY_SSIZE_T_CLEAN

#include <Python.h>
#include <openssl/crypto.h>

static PyObject* SecureString_clearmem(PyObject *self, PyObject *args) {
    char *buffer;
    Py_ssize_t length;

    if(!PyArg_ParseTuple(args, "s#", &buffer, &length)) {
        return NULL;
    }
    OPENSSL_cleanse(buffer, length);
    Py_RETURN_NONE;
}

static PyMethodDef SecureStringMethods[] = {
    {"SecureString_clearmem", SecureString_clearmem, METH_VARARGS, "clear the memory of the string"},
    {NULL, NULL, 0, NULL},
};

static struct PyMethodDef SecureStringDef = {
    PyModuleDef_HEAD_INIT,
    "SecureString",
    NULL,
    -1,
    SecureStringMethods,
};

PyMODINIT_FUNC PyInit_SecureString(void) {
    Py_Initialize(); 
    return PyModule_Create(&SecureStringDef);
}

In theory, this should follow the new Python 3 rules for module initialization, argument passing, and string size variables. It successfully compiles and installs (I am using the same setup.py distributed with the project), but when I try to import it:

import SecureString

I get a segmentation fault:

Segmentation fault: 11

I have tried to attach gdb to examine the C code, but gdb is not working on my computer with Python C modules. I have also tried commenting out the OpenSSL code to see if that was the source of the problem, to no avail. My Python3 installation runs other programs that don't use this library. Could someone take a look at this and suggest where I should look or what I should try next?

Thanks!

Upvotes: 1

Views: 1260

Answers (1)

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160687

The segfault is most likely caused by you defining the module struct as a PyMethodDef instead of a PyModuleDef:

static struct PyModuleDef SecureStringDef 

In addition to that. I'm not sure why you've called Py_Initialize in the initialization function. Calling it is a no-op (since you're already running in an initialized interpreter when you call it).

As an aside, there's no need for the gist, Python already has information on how to port from 2 to 3.

Upvotes: 1

Related Questions