From: Joseph Sutton Date: Sun, 11 Apr 2021 22:23:20 +0000 (+1200) Subject: util: Ensure debugger is not started until it is allowed to attach X-Git-Tag: tevent-0.11.0~1065 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=416c9bbc4f8c92fd0951ce6f03228fd22aedd650;p=thirdparty%2Fsamba.git util: Ensure debugger is not started until it is allowed to attach Use a pipe to ensure that the debugger is not started until after the prctl() call allowing it to attach to the parent, avoiding a potential race condition. Signed-off-by: Joseph Sutton Signed-off-by: Andrew Bartlett Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Tue Apr 20 12:33:40 UTC 2021 on sn-devel-184 --- diff --git a/lib/util/util.c b/lib/util/util.c index b175b22cf13..7eee60b85cd 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -1166,27 +1166,56 @@ void anonymous_shared_free(void *ptr) */ void samba_start_debugger(void) { - pid_t pid = fork(); - if (pid == -1) { - return; - } else if (pid) { + int ready_pipe[2]; + char c; + int ret; + pid_t pid; + + ret = pipe(ready_pipe); + SMB_ASSERT(ret == 0); + + pid = fork(); + SMB_ASSERT(pid >= 0); + + if (pid) { + c = 0; + + ret = close(ready_pipe[0]); + SMB_ASSERT(ret == 0); #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER) /* * Make sure the child process can attach a debugger. + * + * We don't check the error code as the debugger + * will tell us if it can't attach. */ - prctl(PR_SET_PTRACER, pid, 0, 0, 0); + (void)prctl(PR_SET_PTRACER, pid, 0, 0, 0); #endif + ret = write(ready_pipe[1], &c, 1); + SMB_ASSERT(ret == 1); + + ret = close(ready_pipe[1]); + SMB_ASSERT(ret == 0); + + /* Wait for gdb to attach. */ sleep(2); } else { char *cmd = NULL; - if (asprintf(&cmd, "gdb --pid %u", getppid()) == -1) { - _exit(EXIT_FAILURE); - } + ret = close(ready_pipe[1]); + SMB_ASSERT(ret == 0); + + ret = read(ready_pipe[0], &c, 1); + SMB_ASSERT(ret == 1); + + ret = close(ready_pipe[0]); + SMB_ASSERT(ret == 0); + + ret = asprintf(&cmd, "gdb --pid %u", getppid()); + SMB_ASSERT(ret != -1); execlp("xterm", "xterm", "-e", cmd, (char *) NULL); - free(cmd); - _exit(errno); + smb_panic("execlp() failed"); } } #endif