aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-12-23 23:33:39 -0800
committerTrumeet <yuuta@yuuta.moe>2022-12-23 23:33:39 -0800
commitce8e5821dff2673d23fe4f6ba394ab07afd0e73f (patch)
tree5850b553207344a6d103e2a77f0387183687f873
parent03ab6ba2c4efd9c9c5b92d8fb1f51ad51e255a08 (diff)
downloadsecdesk-ce8e5821dff2673d23fe4f6ba394ab07afd0e73f.tar
secdesk-ce8e5821dff2673d23fe4f6ba394ab07afd0e73f.tar.gz
secdesk-ce8e5821dff2673d23fe4f6ba394ab07afd0e73f.tar.bz2
secdesk-ce8e5821dff2673d23fe4f6ba394ab07afd0e73f.zip
Fix setsid(2) fails with EPERM when the binary has SUID bit
It is always good to read APUE before writing anything Unix.
-rw-r--r--main.c67
1 files 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 <string.h>
#include <signal.h>
#include <errno.h>
+#include <sys/wait.h>
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;
}