The branch, v4-19-stable has been updated via 5b54d9e2be8 VERSION: Disable GIT_SNAPSHOT for the 4.19.2 release. via 7d9af74ca74 WHATSNEW: Add release notes for Samba 4.19.2. via f0da8219262 CVE-2023-5568 third_party/heimdal: Fix PKINIT freshness token memory handling (Import lorikeet-heimdal-202310092148 (commit 38aa80e35b6b1e16b081fa9c005c03b1e6994204)) via 147050697e1 ctdb-daemon: Call setproctitle_init() via 6d875c29c3c VERSION: Bump version up to Samba 4.19.2... via fe7adbfc2d1 Merge branch 'v4-19-stable' into v4-19-test via 79101588626 smbd: Fix BZ15481 via ebc4bbbf707 tests: Add reproducer for BZ15481 via 9ba1c94e3e1 s4:kdc: Add correct Asserted Identity SID in response to an S4U2Self request via c30984f095d s3: smbd: Ensure we remove any pending aio values for named pipes on forced shutdown. via 09e00c0a6c5 s3: torture: Add a new SMB2 test: SMB2-PIPE-READ-ASYNC-DISCONNECT via f3d07e123ec s3: smbd: named pipe writes are async. Use the same logic as for named pipe transacts to avoid crashes on shutdown. via 68b8a5c438d s3: smbd: named pipe reads are async. Use the same logic as for named pipe transacts to avoid crashes on shutdown. via 3ac075735c1 s3: smbd: Add some DEVELOPER-only code to panic if the destructor for an aio_lnk is called and the associated fsp doesn't exist. via d70374c3479 s3: libsmb: Add a missing return statement in the timeout case. via 374ba0d2c9a nsswitch/wb_common.c: fix socket fd and memory leaks of global state via 7d04c32ed7e nsswitch/wb_common.c: don't operate on a stale wb_global_ctx.key via 9c10f828dfb nsswitch/wb_common.c: winbind_destructor can always use get_wb_global_ctx() via 61f6f46b26b nsswitch/wb_common.c: fix build without HAVE_PTHREAD via 340b7fd1eec nsswitch: add test for pthread_key_delete missuse (bug 15464) via eadd7e5f9bb mdssvc: better support for search with mdfind from Macs via a8c5fe34b63 VERSION: Bump version up to Samba 4.19.1... from 6872b662d0d Merge tag 'samba-4.19.1' into v4-19-stable
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-19-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 65 ++++++++- ctdb/server/ctdbd.c | 2 + nsswitch/b15464-testcase.c | 77 +++++++++++ nsswitch/wb_common.c | 152 +++++++++++++++------ nsswitch/wscript_build | 5 + python/samba/tests/libsmb-basic.py | 27 ++++ source3/libsmb/clidfs.c | 1 + source3/rpc_server/mdssvc/mdssvc.c | 8 +- ...torture_s3.sh => test_smbtorture_nocrash_s3.sh} | 12 ++ source3/selftest/tests.py | 22 +++ source3/smbd/close.c | 8 ++ source3/smbd/filename.c | 12 +- source3/smbd/smb2_aio.c | 24 ++++ source3/smbd/smb2_read.c | 13 ++ source3/smbd/smb2_write.c | 13 ++ source3/torture/proto.h | 1 + source3/torture/test_smb2.c | 117 ++++++++++++++++ source3/torture/torture.c | 8 +- source4/kdc/wdc-samba4.c | 22 --- testprogs/blackbox/b15464-testcase.sh | 21 +++ third_party/heimdal/kdc/pkinit.c | 5 +- 22 files changed, 545 insertions(+), 72 deletions(-) create mode 100644 nsswitch/b15464-testcase.c copy source3/script/tests/{test_smbtorture_s3.sh => test_smbtorture_nocrash_s3.sh} (62%) create mode 100755 testprogs/blackbox/b15464-testcase.sh Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index 9d6ab2d76b7..5ac084390fd 100644 --- a/VERSION +++ b/VERSION @@ -25,7 +25,7 @@ ######################################################## SAMBA_VERSION_MAJOR=4 SAMBA_VERSION_MINOR=19 -SAMBA_VERSION_RELEASE=1 +SAMBA_VERSION_RELEASE=2 ######################################################## # If a official release has a serious bug # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index f6f6fabd42f..b9b3205212c 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,3 +1,65 @@ + ============================== + Release Notes for Samba 4.19.2 + October 16, 2023 + ============================== + + +This is the latest stable release of the Samba 4.19 release series. + + +Changes since 4.19.1 +-------------------- + +o Jeremy Allison <j...@samba.org> + * BUG 15423: Use-after-free in aio_del_req_from_fsp during smbd shutdown + after failed IPC FSCTL_PIPE_TRANSCEIVE. + * BUG 15426: clidfs.c do_connect() missing a "return" after a cli_shutdown() + call. + +o Ralph Boehme <s...@samba.org> + * BUG 15463: macOS mdfind returns only 50 results. + +o Volker Lendecke <v...@samba.org> + * BUG 15481: GETREALFILENAME_CACHE can modify incoming new filename with + previous cache entry value. + +o Stefan Metzmacher <me...@samba.org> + * BUG 15464: libnss_winbind causes memory corruption since samba-4.18, + impacts sendmail, zabbix, potentially more. + +o Martin Schwenke <mschwe...@ddn.com> + * BUG 15479: ctdbd: setproctitle not initialized messages flooding logs. + +o Joseph Sutton <josephsut...@catalyst.net.nz> + * BUG 15491: CVE-2023-5568 Heap buffer overflow with freshness tokens in the + Heimdal KDC in Samba 4.19 + * BUG 15477: The heimdal KDC doesn't detect s4u2self correctly when fast is + in use. + + +####################################### +Reporting bugs & Development Discussion +####################################### + +Please discuss this release on the samba-technical mailing list or by +joining the #samba-technical:matrix.org matrix room, or +#samba-technical IRC channel on irc.libera.chat. + +If you do report problems then please try to send high quality +feedback. If you don't provide vital information to help us track down +the problem then you will probably be ignored. All bug reports should +be filed under the Samba 4.1 and newer product in the project's Bugzilla +database (https://bugzilla.samba.org/). + + +====================================================================== +== Our Code, Our Bugs, Our Responsibility. +== The Samba Team +====================================================================== + + +Release notes for older releases follow: +---------------------------------------- ============================== Release Notes for Samba 4.19.1 October 10, 2023 @@ -68,8 +130,7 @@ database (https://bugzilla.samba.org/). ====================================================================== -Release notes for older releases follow: ----------------------------------------- +---------------------------------------------------------------------- ============================== Release Notes for Samba 4.19.0 September 04, 2023 diff --git a/ctdb/server/ctdbd.c b/ctdb/server/ctdbd.c index 10541cb21f1..a388bff1598 100644 --- a/ctdb/server/ctdbd.c +++ b/ctdb/server/ctdbd.c @@ -170,6 +170,8 @@ int main(int argc, const char *argv[]) const char *test_mode; bool ok; + setproctitle_init(argc, discard_const(argv), environ); + /* * Basic setup */ 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 <assert.h> + +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/wb_common.c b/nsswitch/wb_common.c index d569e761ebe..b7f84435a4e 100644 --- a/nsswitch/wb_common.c +++ b/nsswitch/wb_common.c @@ -26,6 +26,7 @@ #include "replace.h" #include "system/select.h" #include "winbind_client.h" +#include "lib/util/dlinklist.h" #include <assert.h> #ifdef HAVE_PTHREAD_H @@ -37,74 +38,113 @@ static __thread char client_name[32]; /* Global context */ struct winbindd_context { + struct winbindd_context *prev, *next; int winbindd_fd; /* winbind file descriptor */ bool is_privileged; /* using the privileged socket? */ pid_t our_pid; /* calling process pid */ + bool autofree; /* this is a thread global context */ }; static struct wb_global_ctx { - bool initialized; #ifdef HAVE_PTHREAD pthread_once_t control; pthread_key_t key; + bool key_initialized; +#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +#define WB_GLOBAL_MUTEX_INITIALIZER PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP #else - bool dummy; +#define WB_GLOBAL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #endif +#define WB_GLOBAL_LIST_LOCK do { \ + int __pret = pthread_mutex_lock(&wb_global_ctx.list_mutex); \ + assert(__pret == 0); \ +} while(0) +#define WB_GLOBAL_LIST_UNLOCK do { \ + int __pret = pthread_mutex_unlock(&wb_global_ctx.list_mutex); \ + assert(__pret == 0); \ +} while(0) + pthread_mutex_t list_mutex; +#else /* => not HAVE_PTHREAD */ +#define WB_GLOBAL_LIST_LOCK do { } while(0) +#define WB_GLOBAL_LIST_UNLOCK do { } while(0) +#endif /* not HAVE_PTHREAD */ + struct winbindd_context *list; } wb_global_ctx = { #ifdef HAVE_PTHREAD .control = PTHREAD_ONCE_INIT, + .list_mutex = WB_GLOBAL_MUTEX_INITIALIZER, #endif + .list = NULL, }; static void winbind_close_sock(struct winbindd_context *ctx); +static void winbind_ctx_free_locked(struct winbindd_context *ctx); +static void winbind_cleanup_list(void); #ifdef HAVE_PTHREAD static void wb_thread_ctx_initialize(void); -static void wb_atfork_child(void) +static void wb_atfork_prepare(void) { - struct winbindd_context *ctx = NULL; - int ret; + WB_GLOBAL_LIST_LOCK; +} - ctx = (struct winbindd_context *)pthread_getspecific(wb_global_ctx.key); - if (ctx == NULL) { - return; - } +static void wb_atfork_parent(void) +{ + WB_GLOBAL_LIST_UNLOCK; +} - ret = pthread_setspecific(wb_global_ctx.key, NULL); - assert(ret == 0); +static void wb_atfork_child(void) +{ + wb_global_ctx.list_mutex = (pthread_mutex_t)WB_GLOBAL_MUTEX_INITIALIZER; - winbind_close_sock(ctx); - free(ctx); + if (wb_global_ctx.key_initialized) { + int ret; - ret = pthread_key_delete(wb_global_ctx.key); - assert(ret == 0); + /* + * After a fork the child still believes + * it is the same thread as in the parent. + * So pthread_getspecific() would return the + * value of the thread that called fork(). + * + * But we don't want that behavior, so + * we just clear the reference and let + * winbind_cleanup_list() below 'autofree' + * the parent threads global context. + */ + ret = pthread_setspecific(wb_global_ctx.key, NULL); + assert(ret == 0); + } - wb_global_ctx.control = (pthread_once_t)PTHREAD_ONCE_INIT; + /* + * But we need to close/cleanup the global state + * of the parents threads. + */ + winbind_cleanup_list(); } static void wb_thread_ctx_destructor(void *p) { struct winbindd_context *ctx = (struct winbindd_context *)p; - winbind_close_sock(ctx); - free(ctx); + winbindd_ctx_free(ctx); } static void wb_thread_ctx_initialize(void) { int ret; - ret = pthread_atfork(NULL, - NULL, + ret = pthread_atfork(wb_atfork_prepare, + wb_atfork_parent, wb_atfork_child); assert(ret == 0); ret = pthread_key_create(&wb_global_ctx.key, wb_thread_ctx_destructor); assert(ret == 0); + + wb_global_ctx.key_initialized = true; } -#endif static struct winbindd_context *get_wb_thread_ctx(void) { @@ -129,9 +169,14 @@ static struct winbindd_context *get_wb_thread_ctx(void) *ctx = (struct winbindd_context) { .winbindd_fd = -1, .is_privileged = false, - .our_pid = 0 + .our_pid = 0, + .autofree = true, }; + WB_GLOBAL_LIST_LOCK; + DLIST_ADD_END(wb_global_ctx.list, ctx); + WB_GLOBAL_LIST_UNLOCK; + ret = pthread_setspecific(wb_global_ctx.key, ctx); if (ret != 0) { free(ctx); @@ -139,6 +184,7 @@ static struct winbindd_context *get_wb_thread_ctx(void) } return ctx; } +#endif /* HAVE_PTHREAD */ static struct winbindd_context *get_wb_global_ctx(void) { @@ -147,7 +193,8 @@ static struct winbindd_context *get_wb_global_ctx(void) static struct winbindd_context _ctx = { .winbindd_fd = -1, .is_privileged = false, - .our_pid = 0 + .our_pid = 0, + .autofree = false, }; #endif @@ -155,9 +202,11 @@ static struct winbindd_context *get_wb_global_ctx(void) ctx = get_wb_thread_ctx(); #else ctx = &_ctx; + if (ctx->prev == NULL && ctx->next == NULL) { + DLIST_ADD_END(wb_global_ctx.list, ctx); + } #endif - wb_global_ctx.initialized = true; return ctx; } @@ -231,6 +280,30 @@ static void winbind_close_sock(struct winbindd_context *ctx) } } +static void winbind_ctx_free_locked(struct winbindd_context *ctx) +{ + winbind_close_sock(ctx); + DLIST_REMOVE(wb_global_ctx.list, ctx); + free(ctx); +} + +static void winbind_cleanup_list(void) +{ + struct winbindd_context *ctx = NULL, *next = NULL; + + WB_GLOBAL_LIST_LOCK; + for (ctx = wb_global_ctx.list; ctx != NULL; ctx = next) { + next = ctx->next; + + if (ctx->autofree) { + winbind_ctx_free_locked(ctx); + } else { + winbind_close_sock(ctx); + } + } + WB_GLOBAL_LIST_UNLOCK; +} + /* Destructor for global context to ensure fd is closed */ #ifdef HAVE_DESTRUCTOR_ATTRIBUTE @@ -240,22 +313,18 @@ __attribute__((destructor)) #endif static void winbind_destructor(void) { - struct winbindd_context *ctx; - - if (!wb_global_ctx.initialized) { - return; +#ifdef HAVE_PTHREAD + if (wb_global_ctx.key_initialized) { + int ret; + ret = pthread_key_delete(wb_global_ctx.key); + assert(ret == 0); + wb_global_ctx.key_initialized = false; } -#ifdef HAVE_PTHREAD_H - ctx = (struct winbindd_context *)pthread_getspecific(wb_global_ctx.key); - if (ctx == NULL) { - return; - } -#else - ctx = get_wb_global_ctx(); -#endif + wb_global_ctx.control = (pthread_once_t)PTHREAD_ONCE_INIT; +#endif /* HAVE_PTHREAD */ - winbind_close_sock(ctx); + winbind_cleanup_list(); } #define CONNECT_TIMEOUT 30 @@ -937,11 +1006,16 @@ struct winbindd_context *winbindd_ctx_create(void) ctx->winbindd_fd = -1; + WB_GLOBAL_LIST_LOCK; + DLIST_ADD_END(wb_global_ctx.list, ctx); + WB_GLOBAL_LIST_UNLOCK; + return ctx; } void winbindd_ctx_free(struct winbindd_context *ctx) { - winbind_close_sock(ctx); - free(ctx); + WB_GLOBAL_LIST_LOCK; + winbind_ctx_free_locked(ctx); + WB_GLOBAL_LIST_UNLOCK; } 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/python/samba/tests/libsmb-basic.py b/python/samba/tests/libsmb-basic.py index cbe7cce5bae..163c5b09ea9 100644 --- a/python/samba/tests/libsmb-basic.py +++ b/python/samba/tests/libsmb-basic.py @@ -215,6 +215,33 @@ class LibsmbTestCase(samba.tests.libsmb.LibsmbTests): c1.unlink("x") c1 = None + def test_gencache_pollution_bz15481(self): + c = libsmb.Conn(self.server_ip, "tmp", self.lp, self.creds) + fh = c.create("file", + DesiredAccess=security.SEC_STD_DELETE, + CreateDisposition=libsmb.FILE_CREATE) + + # prime the gencache File->file + fh_upper = c.create("File", + DesiredAccess=security.SEC_FILE_READ_ATTRIBUTE, + CreateDisposition=libsmb.FILE_OPEN) + c.close(fh_upper) -- Samba Shared Repository