From ce8e5821dff2673d23fe4f6ba394ab07afd0e73f Mon Sep 17 00:00:00 2001 From: Trumeet Date: Fri, 23 Dec 2022 23:33:39 -0800 Subject: Fix setsid(2) fails with EPERM when the binary has SUID bit It is always good to read APUE before writing anything Unix. --- main.c | 67 ++++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/main.c b/main.c index 8c537d3..a05f0a1 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,7 @@ #include #include #include +#include struct auth_env a_env; struct proc_env p_env = { @@ -54,32 +55,50 @@ int main(int argc, char **argv) { } a_env.exe[len] = '\0'; - /* Because we need to frequently dup(2). */ - setbuf(stdout, NULL); - signal(SIGHUP, SIG_IGN); - struct sigaction sa = { - .sa_flags = 0, - .sa_handler = interrupt_int - }; - sigemptyset(&sa.sa_mask); - /* Return EINTR on these signals to exit safely. */ - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); + pid_t chld; + /* Detach from the current session. */ + if (!(chld = fork())) { + /* Because we need to frequently dup(2). */ + setbuf(stdout, NULL); + signal(SIGHUP, SIG_IGN); + struct sigaction sa = { + .sa_flags = 0, + .sa_handler = interrupt_int + }; + sigemptyset(&sa.sa_mask); + /* Return EINTR on these signals to exit safely. */ + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); - int r = sd_setup(); - if (r == -1) { - sd_cleanup(); - return 13; + int r = sd_setup(); + if (r == -1) { + sd_cleanup(); + return 13; + } + if (r) { + sd_cleanup(); + r = main_consent(0); + } else { + dprintf(p_env.err, "Complete authorization on TTY %d by running `chvt %d`.\n", + p_env.vt, + p_env.vt); + r = main_consent(1); + sd_cleanup(); + } + return r; } - if (r) { - sd_cleanup(); - r = main_consent(0); + if (chld == -1) { + LOGFV("Cannot fork: %m", errno); + return errno; + } + int status; + if (waitpid(chld, &status, 0) == -1) { + LOGFV("Cannot wait for child: %m", errno); + return errno; + } + if (WIFEXITED(status)) { + return WEXITSTATUS(status); } else { - dprintf(p_env.err, "Complete authorization on TTY %d by running `chvt %d`.\n", - p_env.vt, - p_env.vt); - r = main_consent(1); - sd_cleanup(); + return 255; } - return r; } -- cgit v1.2.3