[hackers] [utmp] Avoid race conditions between fork and wait || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Sun, 10 Aug 2014 21:25:21 +0200

commit 836feec54d58f145d34b14baee7cb0ff677cbd26
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
Date: Thu Aug 7 14:52:19 2014 +0200

    Avoid race conditions between fork and wait
    
    If some signal arrives to the parent between these two points
    then it is possible to have dirty entries in utmp.

diff --git a/utmp.c b/utmp.c
index c893ae1..d0d556c 100644
--- a/utmp.c
+++ b/utmp.c
_AT_@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <signal.h>
 
 #include <sys/types.h>
 #include <unistd.h>
_AT_@ -39,6 +40,7 @@ main(int argc, char *argv[])
 {
         int status;
         uid_t uid;
+ sigset_t set;
         extern void addutmp(void), delutmp(void);
 
         egid = getegid();
_AT_@ -54,8 +56,12 @@ main(int argc, char *argv[])
         setenv("SHELL", pass->pw_shell, 0);
         setenv("HOME", pass->pw_dir, 0);
 
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+
         switch (fork()) {
         case 0:
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
                 argv[0] = getenv("SHELL");
                 execv(argv[0], argv);
                 die("error executing shell:%s", strerror(errno));
_AT_@ -63,10 +69,13 @@ main(int argc, char *argv[])
                 die("error spawning child:%s", strerror(errno));
         default:
                 addutmp();
- if (wait(&status) == -1) {
- fprintf(stderr, "error waiting child:%s
",
- strerror(errno));
- }
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+
+ if (wait(&status) == -1)
+ perror("error waiting child");
                 delutmp();
         }
         return 0;
Received on Sun Aug 10 2014 - 21:25:21 CEST

This archive was generated by hypermail 2.3.0 : Sun Aug 10 2014 - 21:36:09 CEST