-
Notifications
You must be signed in to change notification settings - Fork 66
Description
Environment:
- Ubuntu 22.04, kernel 6.8.0-87-generic
- Python 3.10.12 (python3.10-dbg installed)
- pysctp 0.7.2 (pip install), _sctp.so linked to /lib/x86_64-linux-gnu/libsctp.so.1
Problem:
When sctp_recv_msg handles SCTP_SEND_FAILED or SCTP_REMOTE_ERROR notifications whose payload is arbitrary binary data, interpret_notification() calls PyUnicode_FromStringAndSize(cdata, ldata). If the bytes are not valid UTF-8 (or allocation fails), this function returns NULL. The code immediately calls PyDict_SetItemString(dict, "data", NULL), which leads to _Py_INCREF(NULL) and a SIGSEGV.
Crash backtrace (python3.10-dbg + core dump):
#5 _Py_INCREF(op=0x0)
#6 insertdict(... value=0x0) at dictobject.c:1075
#7 PyDict_SetItem(...)
#8 PyDict_SetItemString(... item=0x0)
#9 interpret_notification(dict=..., pnotif=..., size=...) at _sctp.c:1815
#10 sctp_recv_msg(...) at _sctp.c:1865
Expected behavior:
If the notification payload cannot be converted to a Unicode object, the function should either raise a Python exception or store the data as bytes. It must never insert NULL into the dictionary.
Actual behavior:
The Python interpreter crashes whenever a send-failure / remote-error notification contains non UTF-8 data.
How to reproduce:
- Enable SCTP send_failure and peer_error events.
- Send data that triggers SCTP_SEND_FAILED (or a remote error) with non-UTF8 payload.
- Call sctp.sctp_recv() in Python; as soon as the notification arrives, python3 crashes with SIGSEGV.
Suggested fix:
Treat “data” as bytes and check for NULL before inserting into the dict.
Possible patch:
case SCTP_SEND_FAILED: {
...
if (ldata >= 0) {
PyObject* info = PyDict_New();
PyObject* data_obj = PyBytes_FromStringAndSize(cdata, ldata);
if (!info || !data_obj) {
Py_XDECREF(info);
Py_XDECREF(data_obj);
return;
}
PyDict_SetItemString(dict, "_info", info);
Py_DECREF(info);
PyDict_SetItemString(dict, "error", Py23_PyLong_FromLong(n->ssf_error));
PyDict_SetItemString(dict, "assoc_id", Py23_PyLong_FromLong(n->ssf_assoc_id));
PyDict_SetItemString(dict, "data", data_obj);
Py_DECREF(data_obj);
}
break;
case SCTP_REMOTE_ERROR: {
...
if (ldata >= 0) {
PyObject* data_obj = PyBytes_FromStringAndSize(cdata, ldata);
if (!data_obj) { return; }
PyDict_SetItemString(dict, "error", Py23_PyLong_FromLong(n->sre_error));
PyDict_SetItemString(dict, "assoc_id", Py23_PyLong_FromLong(n->sre_assoc_id));
PyDict_SetItemString(dict, "data", data_obj);
Py_DECREF(data_obj);
}
break;
Workaround:
None at Python level; any application receiving such a notification will crash.
Please confirm and repair it so that sctp_recv_msg no longer segfaults when notification payloads contain arbitrary binary data.