Получение SIGSEGV при вызове функции модуля расширения python3, работающей с Py_buffer - PullRequest
0 голосов
/ 12 января 2020

Я играю с Python C модулями расширения, и у меня есть эта простая функция:

static PyObject *e_parse_metadata(PyObject *self, PyObject *args) {
    Py_buffer buf;

    if(!PyArg_ParseTuple(args, "y#", &buf)) {
        // interpreter raises exception, we return NULL to indicate failure
        return NULL;
    }

    fprintf(stdout, "extension: %c%c\n\n", *((char *) buf.buf) + 0, *((char*) buf.buf + 1)); // should print "BM"

    PyBuffer_Release(&buf);

    return PyLong_FromLong(33l);
}

Он пытается получить Py_buffer из аргумента, переданного ему из в пределах Python. Затем он отображает первые 2 байта из буфера в виде символов для stdout, освобождает буфер и возвращает ссылку на новый PyObject, представляющий целое число 33.


Далее у меня есть Python пример использования указанной функции:

#!/usr/bin/env python3

import bbmp_utils # my module

with open('./mit.bmp', 'rb') as mit:
    if(mit.readable()):
        filedata = mit.read()
        res = bbmp_utils.parse_metadata(filedata) # call to my function in the extension module
        print(res, type(res))

В результате модуль расширения успешно печатает первые 2 байта из потока байтов (extension: BM) в стандартный вывод, но затем он завершается: fish: “env PYTHONPATH=./build_dbg pyth…” terminated by signal SIGSEGV (Address boundary error)


Как ни странно, прямая передача экземпляра bytes в мою функцию расширения не вызывает кражу sh вообще, например

res = bbmp_utils.parse_metadata(mit.read())

Почему первый пример приводит к cra sh, а второй - нет?

1 Ответ

0 голосов
/ 12 января 2020

Я использовал неправильный спецификатор формата при разборе Python аргументов.

y# требует, чтобы длина буфера также передавалась в PyArg_ParseTuple, чего я не делал. Также обратите внимание, что вариант # предполагает наличие буфера только для чтения.


y* работает как положено.


Это хорошо, но все еще не объясняет почему одна из python версий дает сбой, а другая - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...