From 7b089af85d4438b1b7449c74f65dfd834f6e9e33 Mon Sep 17 00:00:00 2001 From: Florian Best Date: Wed, 15 Nov 2023 18:30:59 +0100 Subject: [PATCH] fix(udl): Fix listener segfault for modules using new listener api The new UDL Python API defines modrdn as int instead of the string "1": (gdb) p *var $1 = {ob_refcnt = 1000010831, ob_type = 0x7f341f835ae0 } In UCS 5.0 this was not a problem, as `PyArg_Parse(var, "s", &str1);` worked nevertheless and resulted in: (gdb) p str1 $2 = 0x7ffef407aea8 "\002" This seems to have changed in Python 3.11 or earlier and caused: kernel: [18330.428271] univention-dire[15235]: segfault at 0 ip 00007f23ced86618 sp 00007fff7570ae48 error 4 in libc.so.6[7f23cec45000+155000] likely on CPU 0 (core 0, socket 0) kernel: [18330.428285] Code: e1 ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 89 f8 62 a1 fd 00 ef c0 25 ff 0f 00 00 3d e0 0f 00 00 0f 87 38 01 00 00 <62> f3 7d 20 3f 07 00 c5 fb 93 c0 85 c0 74 59 f3 0f bc c0 c3 0f 1f #1 0x00007f341f0bd7ee in __GI___strdup (s=0x0) at ./string/strdup.c:41 #2 0x000055b0683cfd20 in module_get_string (module=, name=name@entry=0x55b0683dbf65 "modrdn") at ./src/handlers.c:158 #3 0x000055b0683d0580 in handler_import (filename=0x7ffc300a2440 "/usr/lib/univention-directory-listener/system/ldap-cache-baa04df67e7af6bb0769f5cb7e72dba9.py") at ./src/handlers.c:239 #4 0x000055b0683d0d02 in handlers_load_path (path=0x55b069fcc7b0 "/usr/lib/univention-directory-listener/system") at ./src/handlers.c:516 #5 0x000055b0683d14a0 in handlers_load_path (path=0x55b069fcc7b0 "/usr/lib/univention-directory-listener/system") at ./src/handlers.c:629 #6 handlers_load_all_paths () at ./src/handlers.c:535 #7 handlers_init () at ./src/handlers.c:627 #8 0x000055b0683ce530 in main (argc=, argv=) at ./src/main.c:564 The modrdn was now changed into a boolean flag. Prior it was evaluated similar. the pure presence of it (e.g. "0") caused modrdn to be evaluated as true. Bug #56533 --- .../src/handlers.c | 28 +++++++++++++------ .../src/handlers.h | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/management/univention-directory-listener/src/handlers.c b/management/univention-directory-listener/src/handlers.c index 3d153c9d71f..67a5f33ef3c 100644 --- a/management/univention-directory-listener/src/handlers.c +++ b/management/univention-directory-listener/src/handlers.c @@ -139,17 +139,32 @@ static PyObject *module_get_object(PyObject *module, char *name) { } +/* Retrieve bool(name) from Python module. */ +static bool module_get_bool(PyObject *module, char *name) { + PyObject *attr; + int result; + attr = module_get_object(module, name); + result = PyObject_IsTrue(attr); + Py_XDECREF(attr); + return result == 1; +} + + /* Retrieve string from Python module. */ static char *module_get_string(PyObject *module, char *name) { PyObject *var; char *str1, *str2 = NULL; if ((var = PyObject_GetAttrString(module, name)) == NULL) - goto error0; - PyArg_Parse(var, "s", &str1); + goto error1; + if (!PyUnicode_Check(var)) + goto error0; + if (PyArg_Parse(var, "s", &str1) != 1) + goto error0; str2 = strdup(str1); - Py_XDECREF(var); error0: + Py_XDECREF(var); +error1: return str2; } @@ -228,11 +243,7 @@ static int handler_import(char *filename) { } if (PyObject_HasAttrString(handler->module, "modrdn")) { /* optional */ - handler->modrdn = module_get_string(handler->module, "modrdn"); - if (handler->modrdn == NULL) { - error_msg = "module_get_string(\"modrdn\")"; - goto error; - } + handler->modrdn = module_get_bool(handler->module, "modrdn"); } PyErr_Clear(); // Silent error when attribute is not set @@ -333,7 +344,6 @@ static int handler_import(char *filename) { } free(handler->filters); free(handler->description); - free(handler->modrdn); free(handler->name); free(handler); univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "import of filename=%s failed in %s", filename, error_msg ? error_msg : "???"); diff --git a/management/univention-directory-listener/src/handlers.h b/management/univention-directory-listener/src/handlers.h index b5a278d3414..6f7f067ccb6 100644 --- a/management/univention-directory-listener/src/handlers.h +++ b/management/univention-directory-listener/src/handlers.h @@ -66,7 +66,7 @@ struct _Handler { char *description; struct filter **filters; char **attributes; - char *modrdn; + bool modrdn; bool handle_every_delete; PyObject *handler; PyObject *initialize;