Index | Thread | Search

From:
Mikolaj Kucharski <mikolaj@kucharski.name>
Subject:
FIX/WIP: Intermittent SIGSEGV in ansible-libssh-1.2.2
To:
ports@openbsd.org
Cc:
Denis Fondras <denis@openbsd.org>
Date:
Thu, 14 Nov 2024 16:19:53 +0000

Download raw body.

Thread
Hi,

I would like to use ansible-libssh and its exec_command(), but I am
currently getting intermittent SIGSEGVs. I have work in progress patch
from upstream inlined below.

My diff also enables debug package, but I am not sure does it add
any value in Python modules, as I didn't see any improvement in gdb's
bt output for compiled Python modules, so maybe it's not worth enabling.
I would appreciate comment on this, if someone he deeper underanding of
Python's compiled modules.

For me, the important bit is the upstream patch itself. The patch
introduces a memory leak, but makes running exec_command() reliable
without a crash.


diff -ruN -xCVS -xTODO -xMakefile-testing py-ansible-libssh/Makefile py-ansible-libssh-new/Makefile
--- py-ansible-libssh/Makefile	Thu Nov 14 16:03:33 2024
+++ py-ansible-libssh-new/Makefile	Thu Nov 14 16:02:08 2024
@@ -3,6 +3,7 @@
 DISTNAME =		ansible-pylibssh-${MODPY_EGG_VERSION}
 PKGNAME =		py-ansible-libssh-${MODPY_EGG_VERSION}
 CATEGORIES =		sysutils
+REVISION =		0
 
 MAINTAINER =		Denis Fondras <denis@openbsd.org>
 
@@ -17,6 +18,8 @@
 MODULES =		lang/python
 MODPY_PI =		Yes
 MODPY_PYBUILD =		setuptools_scm
+
+DEBUG_PACKAGES =	${BUILD_PACKAGES}
 
 CFLAGS +=		-I${LOCALBASE}/include
 BUILD_DEPENDS =		sysutils/py-expandvars${MODPY_FLAVOR} \
diff -ruN -xCVS -xTODO -xMakefile-testing py-ansible-libssh/patches/patch-src_pylibsshext_channel_pyx py-ansible-libssh-new/patches/patch-src_pylibsshext_channel_pyx
--- py-ansible-libssh/patches/patch-src_pylibsshext_channel_pyx	Thu Jan  1 00:00:00 1970
+++ py-ansible-libssh-new/patches/patch-src_pylibsshext_channel_pyx	Thu Nov 14 15:59:37 2024
@@ -0,0 +1,43 @@
+- https://github.com/ansible/pylibssh/issues/645
+- https://github.com/ansible/pylibssh/issues/657
+- https://github.com/ansible/pylibssh/pull/658
+
+Index: src/pylibsshext/channel.pyx
+--- src/pylibsshext/channel.pyx.orig
++++ src/pylibsshext/channel.pyx
+@@ -20,6 +20,7 @@ import time
+ from io import BytesIO
+ 
+ from cpython.bytes cimport PyBytes_AS_STRING
++from cpython.mem cimport PyMem_Malloc
+ from libc.string cimport memset
+ 
+ from pylibsshext.errors cimport LibsshChannelException
+@@ -166,12 +167,15 @@ cdef class Channel:
+             raise LibsshChannelException("Failed to execute command [{0}]: [{1}]".format(command, rc))
+         result = CompletedProcess(args=command, returncode=-1, stdout=b'', stderr=b'')
+ 
+-        cdef callbacks.ssh_channel_callbacks_struct cb
+-        memset(&cb, 0, sizeof(cb))
++        cb_size = sizeof(callbacks.ssh_channel_callbacks_struct)
++        cdef callbacks.ssh_channel_callbacks_struct *cb = <callbacks.ssh_channel_callbacks_struct *>PyMem_Malloc(cb_size)
++        if cb is NULL:
++            raise LibsshChannelException("Memory allocation error")
++        memset(cb, 0, cb_size)
+         cb.channel_data_function = <callbacks.ssh_channel_data_callback>&_process_outputs
+         cb.userdata = <void *>result
+-        callbacks.ssh_callbacks_init(&cb)
+-        callbacks.ssh_set_channel_callbacks(channel, &cb)
++        callbacks.ssh_callbacks_init(cb)
++        callbacks.ssh_set_channel_callbacks(channel, cb)
+ 
+         libssh.ssh_channel_send_eof(channel)
+         result.returncode = libssh.ssh_channel_get_exit_status(channel)
+@@ -179,6 +183,7 @@ cdef class Channel:
+             libssh.ssh_channel_close(channel)
+             libssh.ssh_channel_free(channel)
+ 
++        # XXX leaking the memory of the callbacks
+         return result
+ 
+     def send_eof(self):


-- 
Regards,
 Mikolaj