Improve signal handling when accumulating noise from child processes.
authormdw <mdw>
Thu, 18 Jun 1998 15:08:14 +0000 (15:08 +0000)
committermdw <mdw>
Thu, 18 Jun 1998 15:08:14 +0000 (15:08 +0000)
src/noise.c

index f316306..2945be0 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: noise.c,v 1.5 1998/04/23 13:25:23 mdw Exp $
+ * $Id: noise.c,v 1.6 1998/06/18 15:08:14 mdw Exp $
  *
  * Collection of environmental noise
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: noise.c,v $
+ * Revision 1.6  1998/06/18 15:08:14  mdw
+ * Improve signal handling when accumulating noise from child processes.
+ *
  * Revision 1.5  1998/04/23 13:25:23  mdw
  * Try to reduce the amount of `ps'ing done under OSF/1, because /dev/kmem
  * seems very slow.
@@ -55,6 +58,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -100,16 +104,36 @@ static void noise__shell(const char *cmd)
   int pfd[2];
   pid_t pid;
 
+#ifdef HAVE_SIGPROCMASK
+  sigset_t ob, nb;
+#endif
+
   /* --- Create a pipe for talking to the child --- */
 
   if (pipe(pfd))
     return;
 
+  /* --- Sort out the signal handling for the parent --- *
+   *
+   * Block @SIGCHLD@ while this is going on.  Unlike the standard @system@
+   * function, I won't disable @SIGINT@ and @SIGQUIT@.  Then, if the user
+   * stops the child with a terminal signal, the parent (i.e., me) gets
+   * killed too, and I don't end up with a tiny dribble of entropy when I'm
+   * expecting quite a lot.
+   */
+
+#ifdef HAVE_SIGPROCMASK
+  sigemptyset(&nb);
+  sigaddset(&nb, SIGCHLD);
+  if (sigprocmask(SIG_BLOCK, &nb, &ob))
+    goto fail_0;
+#endif
+
   /* --- Create the child process --- */
 
   pid = fork();
   if (pid < 0)
-    return;
+    goto fail_1;
 
   if (pid == 0) {
     int fd;
@@ -119,9 +143,22 @@ static void noise__shell(const char *cmd)
       0
     };
 
-    /* --- Become whoever I'm being run as --- */
+    /* --- Restore signal handling things --- */
+
+#ifdef HAVE_SIGPROCMASK
+    sigprocmask(SIG_SETMASK, &nb, 0);
+#endif
+
+    /* --- Become nobody --- *
+     *
+     * This assumes that @-2@ is a safe user to be.  It shouldn't be root,
+     * because it doesn't need to be, and nothing should be done as root
+     * which could be done as someone else.  It shouldn't be the user who
+     * invoked me, because that would enable her to kill the children before
+     * I've read enough entropy from them, and that wouldn't be good.
+     */
 
-    setuid(getuid());
+    setuid(-2);
 
     /* --- Close the old standard streams --- */
 
@@ -177,11 +214,18 @@ static void noise__shell(const char *cmd)
 
   {
     int st;
-
     wait(&st);
     rand_add(&st, sizeof(st));
     rand_add(&pid, sizeof(pid));
   }
+
+  /* --- Restore signals --- */
+
+fail_1:
+#ifdef HAVE_SIGPROCMASK
+  sigprocmask(SIG_SETMASK, &ob, 0);
+#endif
+fail_0:;
 }
 
 /* --- @noise_acquire@ --- *