sorz/sstp-server

Breaks when running under Python 3.10

mgperkow opened this issue · 6 comments

sstp-server segfaults immediately after accepting and setting up a connection when running under Python 3.10. The segfault seems to happen within the context of codecmodule.c.

Can confirm.

I have also been able to track this down to a segfault in "codecmodule.c":

2022-03-12 11:02:35,636 INFO: Listening on 0.0.0.0:4433...
2022-03-12 11:02:47,270 INFO: SSTP control packet (CALL_CONNECT_REQUEST) received.
2022-03-12 11:02:47,270 INFO: Registered address 192.168.123.234
2022-03-12 11:02:47,287 VERBOSE: Raw data: 7eff7d23c0217d217d217d207d387d227d267d207d207d207d207d237d24c2277d257d2664e17d2f8a7d277d227d287d22d0e47

Next that happens in PPPDProtocol.out_received is frames = self.decoder.unescape(data) where the segfault occurs, and the following line of self.sstp.write_ppp_frames(frames) is never reached.

Server here is a current Arch Linux with CPython 3.10.2, tested with MikroTik ROS 7.1.3 client.
EDIT: Works fine when using CPython 3.9.10.

...well, since it's also working again with CPython 3.11, I guess it's nothing truly related to this package. 🤷‍♂️

Is there any workaround we can apply beyond creating a new environment for python 3.11 since this one is not GA yet?

I am running Ubuntu 22.04 which comes with 3.10 by default and I don't think it's possible for me to downport to 3.9.

Ideally there would be a patch to allow compatibility with 3.10 as well.

Thanks in advance

I happened to come back to this and decided to try to analyze it a little more in-depth myself. I'm not really a Python programmer, but I'm pretty experienced with other languages, so I did some breakpointing and debugging and found the exact instruction where the program was crashing. After a little trial and error (and perusing the Python developer docs a bit), I came up with this patch, which seems to correct the problem when running on Python 3.10.8 (which I'm currently using) after rebuilding the sstp-server package from source:

--- sstpd/codecmodule.c.orig    2022-10-17 15:06:17.238786534 -0400
+++ sstpd/codecmodule.c 2022-10-17 15:04:21.130988032 -0400
@@ -1,3 +1,4 @@
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <stdbool.h>

@@ -147,7 +148,7 @@ PppDecoder_unescape(PppDecoder *self, Py
                 PyObject* frame = Py_BuildValue("y#",
                         self->frame_buf, self->frame_buf_pos - 2);
                 if (PyList_Append(frames, frame) == -1) {
-                    Py_DECREF(frame);
+                    if (frame) Py_DECREF(frame);
                     self->frame_buf_pos = 0;
                     PyBuffer_Release(&buf_in);
                     return NULL;

I happened to come back to this and decided to try to analyze it a little more in-depth myself. I'm not really a Python programmer, but I'm pretty experienced with other languages, so I did some breakpointing and debugging and found the exact instruction where the program was crashing. After a little trial and error (and perusing the Python developer docs a bit), I came up with this patch, which seems to correct the problem when running on Python 3.10.8 (which I'm currently using) after rebuilding the sstp-server package from source:

--- sstpd/codecmodule.c.orig    2022-10-17 15:06:17.238786534 -0400
+++ sstpd/codecmodule.c 2022-10-17 15:04:21.130988032 -0400
@@ -1,3 +1,4 @@
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <stdbool.h>

@@ -147,7 +148,7 @@ PppDecoder_unescape(PppDecoder *self, Py
                 PyObject* frame = Py_BuildValue("y#",
                         self->frame_buf, self->frame_buf_pos - 2);
                 if (PyList_Append(frames, frame) == -1) {
-                    Py_DECREF(frame);
+                    if (frame) Py_DECREF(frame);
                     self->frame_buf_pos = 0;
                     PyBuffer_Release(&buf_in);
                     return NULL;

then why not opening a pull request ?

Oh, I suppose I could. I'm kinda new to that end of the process, but I'll read through the documentation on pull requests and see if I can get one going.

Any tips for installing python 3.11 in a way that it works with the sstpd command on Arch?

Been struggling to set it up