From 62af25d44e542548d8cdecb061a6001e0071ee76 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Sep 2023 13:57:26 +0200 Subject: [PATCH] nsswitch: add test for pthread_key_delete missuse (bug 15464) This is based on https://bugzilla.samba.org/attachment.cgi?id=18081 written by Krzysztof Piotr Oledzki BUG: https://bugzilla.samba.org/show_bug.cgi?id=15464 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- nsswitch/b15464-testcase.c | 77 +++++++++++++++++++++++++++ nsswitch/wscript_build | 5 ++ selftest/knownfail.d/b15464_testcase | 1 + source3/selftest/tests.py | 6 +++ testprogs/blackbox/b15464-testcase.sh | 21 ++++++++ 5 files changed, 110 insertions(+) create mode 100644 nsswitch/b15464-testcase.c create mode 100644 selftest/knownfail.d/b15464_testcase create mode 100755 testprogs/blackbox/b15464-testcase.sh diff --git a/nsswitch/b15464-testcase.c b/nsswitch/b15464-testcase.c new file mode 100644 index 00000000000..decb474a81e --- /dev/null +++ b/nsswitch/b15464-testcase.c @@ -0,0 +1,77 @@ +#include "replace.h" +#include "system/wait.h" +#include "system/threads.h" +#include + +int main(int argc, const char *argv[]) +{ + pid_t pid; + int wstatus; + pthread_key_t k1; + pthread_key_t k2; + pthread_key_t k3; + char *val = NULL; + const char *nss_winbind = (argc >= 2 ? argv[1] : "bin/plugins/libnss_winbind.so.2"); + void *nss_winbind_handle = NULL; + union { + int (*fn)(void); + void *symbol; + } nss_winbind_endpwent = { .symbol = NULL, }; + + /* + * load and invoke something simple like + * _nss_winbind_endpwent in order to + * get the libnss_winbind internal going + */ + nss_winbind_handle = dlopen(nss_winbind, RTLD_NOW); + printf("%d: nss_winbind[%s] nss_winbind_handle[%p]\n", + getpid(), nss_winbind, nss_winbind_handle); + assert(nss_winbind_handle != NULL); + + nss_winbind_endpwent.symbol = dlsym(nss_winbind_handle, + "_nss_winbind_endpwent"); + printf("%d: nss_winbind_handle[%p] _nss_winbind_endpwent[%p]\n", + getpid(), nss_winbind_handle, nss_winbind_endpwent.symbol); + assert(nss_winbind_endpwent.symbol != NULL); + (void)nss_winbind_endpwent.fn(); + + val = malloc(1); + assert(val != NULL); + + pthread_key_create(&k1, NULL); + pthread_setspecific(k1, val); + printf("%d: k1=%d\n", getpid(), k1); + + pid = fork(); + if (pid) { + free(val); + wait(&wstatus); + return WEXITSTATUS(wstatus); + } + + pthread_key_create(&k2, NULL); + pthread_setspecific(k2, val); + + printf("%d: Hello after fork, k1=%d, k2=%d\n", getpid(), k1, k2); + + pid = fork(); + + if (pid) { + free(val); + wait(&wstatus); + return WEXITSTATUS(wstatus); + } + + pthread_key_create(&k3, NULL); + pthread_setspecific(k3, val); + + printf("%d: Hello after fork2, k1=%d, k2=%d, k3=%d\n", getpid(), k1, k2, k3); + + if (k1 == k2 || k2 == k3) { + printf("%d: FAIL inconsistent keys\n", getpid()); + return 1; + } + + printf("%d: OK consistent keys\n", getpid()); + return 0; +} diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build index 3247b6c2b7c..4e62bb4c946 100644 --- a/nsswitch/wscript_build +++ b/nsswitch/wscript_build @@ -15,6 +15,11 @@ if bld.CONFIG_SET('HAVE_PTHREAD'): deps='wbclient pthread', for_selftest=True ) + bld.SAMBA_BINARY('b15464-testcase', + source='b15464-testcase.c', + deps='replace pthread dl', + for_selftest=True + ) # The nss_wrapper code relies strictly on the linux implementation and # name, so compile but do not install a copy under this name. diff --git a/selftest/knownfail.d/b15464_testcase b/selftest/knownfail.d/b15464_testcase new file mode 100644 index 00000000000..94dd7db7c2a --- /dev/null +++ b/selftest/knownfail.d/b15464_testcase @@ -0,0 +1 @@ +^b15464_testcase.run.b15464-testcase diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 9d77c49ed48..fa51f7fdcbd 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -67,6 +67,8 @@ except KeyError: samba4bindir = bindir() config_h = os.path.join(samba4bindir, "default/include/config.h") +bbdir = os.path.join(srcdir(), "testprogs/blackbox") + # check available features config_hash = dict() f = open(config_h, 'r') @@ -958,6 +960,10 @@ if with_pthreadpool: [os.path.join(samba3srcdir, "script/tests/test_libwbclient_threads.sh"), "$DOMAIN", "$DC_USERNAME"]) + plantestsuite("b15464_testcase", "none", + [os.path.join(bbdir, "b15464-testcase.sh"), + binpath("b15464-testcase"), + binpath("plugins/libnss_winbind.so.2")]) plantestsuite("samba3.test_nfs4_acl", "none", [os.path.join(bindir(), "test_nfs4_acls"), diff --git a/testprogs/blackbox/b15464-testcase.sh b/testprogs/blackbox/b15464-testcase.sh new file mode 100755 index 00000000000..b0c88260d4c --- /dev/null +++ b/testprogs/blackbox/b15464-testcase.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Blackbox wrapper for bug 15464 +# Copyright (C) 2023 Stefan Metzmacher + +if [ $# -lt 2 ]; then + cat <