]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: bypass child cleanup when child exits with a magic exit code
authorRalph Boehme <slow@samba.org>
Sun, 26 Oct 2025 08:56:09 +0000 (09:56 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 17 Jul 2026 10:18:37 +0000 (10:18 +0000)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Anoop C S <anoopcs@samba.org>
libcli/smb/smbXcli_base.h
source3/smbd/server.c

index e88a866c6ac931a2dd4630122082b5be2b76012e..27d4fe5b90ba63b17e937454f656194b5fe95fb7 100644 (file)
@@ -22,6 +22,7 @@
 #define _SMBXCLI_BASE_H_
 
 #define SMB_SUICIDE_PACKET 0x74697865
+#define SMB_SUICIDE_EXIT_STATUS_BYPASS_CLEANUP 234
 
 #include "replace.h"
 #include <tevent.h>
index a54a80ac5d914f60468b1db5f8710d2b15925178..c34bed84aa06ad159fc2eaed504d9d284e81ec29 100644 (file)
@@ -61,6 +61,7 @@
 #include "source3/lib/substitute.h"
 #include "lib/addrchange.h"
 #include "../source4/lib/tls/tls.h"
+#include "libcli/smb/smbXcli_base.h"
 
 #ifdef HAVE_LIBQUIC
 #include <netinet/quic.h>
@@ -879,7 +880,8 @@ static void cleanupd_started(struct tevent_req *req)
 
 static void remove_child_pid(struct smbd_parent_context *parent,
                             pid_t pid,
-                            bool unclean_shutdown)
+                            bool unclean_shutdown,
+                            bool ignore)
 {
        struct smbd_child_pid *child;
        NTSTATUS status;
@@ -901,6 +903,11 @@ static void remove_child_pid(struct smbd_parent_context *parent,
                return;
        }
 
+       if (ignore) {
+               DBG_WARNING("Ignoring exit of child %d\n", pid);
+               return;
+       }
+
        if (pid == procid_to_pid(&parent->cleanupd)) {
                struct tevent_req *req;
 
@@ -986,13 +993,19 @@ static void smbd_sig_chld_handler(struct tevent_context *ev,
 
        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
                bool unclean_shutdown = False;
+               bool ignore = false;
 
                /* If the child terminated normally, assume
                   it was an unclean shutdown unless the
                   status is 0
                */
                if (WIFEXITED(status)) {
-                       unclean_shutdown = WEXITSTATUS(status);
+                       int exitcode = WEXITSTATUS(status);
+                       unclean_shutdown = (exitcode != 0);
+#ifdef ENABLE_SELFTEST
+                       ignore = (exitcode ==
+                                 SMB_SUICIDE_EXIT_STATUS_BYPASS_CLEANUP);
+#endif
                }
                /* If the child terminated due to a signal
                   we always assume it was unclean.
@@ -1000,7 +1013,7 @@ static void smbd_sig_chld_handler(struct tevent_context *ev,
                if (WIFSIGNALED(status)) {
                        unclean_shutdown = True;
                }
-               remove_child_pid(parent, pid, unclean_shutdown);
+               remove_child_pid(parent, pid, unclean_shutdown, ignore);
        }
 }