]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Init the arc4random seed before chrooting
authorRoy Marples <roy@marples.name>
Sun, 24 May 2020 12:23:20 +0000 (12:23 +0000)
committerRoy Marples <roy@marples.name>
Sun, 24 May 2020 12:23:20 +0000 (12:23 +0000)
/dev/urandom isn't available in the chroot.
So keep a fd open to it.

compat/arc4random.c
src/privsep.c

index 045e02343a7286b61135439db91e5da8dd311083..90098127c954d9e1cbd963b9c53cb954ea887189 100644 (file)
@@ -37,6 +37,7 @@ struct arc4_stream {
        uint8_t s[256];
        size_t count;
        pid_t stir_pid;
+       int fd;
 };
 
 #define S(n) (n)
@@ -46,7 +47,7 @@ struct arc4_stream {
 #define S256 S64(0), S64(64), S64(128), S64(192)
 
 static struct arc4_stream rs = { .i = 0xff, .j = 0, .s = { S256 },
-                    .count = 0, .stir_pid = 0 };
+                    .count = 0, .stir_pid = 0, .fd = -1 };
 
 #undef S
 #undef S4
@@ -103,7 +104,6 @@ arc4_getword(struct arc4_stream *as)
 static void
 arc4_stir(struct arc4_stream *as)
 {
-       int fd;
        struct {
                struct timeval tv;
                unsigned int rnd[(128 - sizeof(struct timeval)) /
@@ -112,13 +112,28 @@ arc4_stir(struct arc4_stream *as)
        size_t n;
 
        gettimeofday(&rdat.tv, NULL);
-       fd = open("/dev/urandom", O_RDONLY);
-       if (fd != -1) {
+       if (as->fd == -1) {
+#ifndef O_CLOEXEC
+               int fd_opts;
+#endif
+
+               as->fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK
+#ifdef O_CLOEXEC
+               | O_CLOEXEC
+#endif
+               );
+#ifndef O_CLOEXEC
+               if (as->fd != -1 &&
+                   (fd_opts = fcntl(as->fd, F_GETFD)))
+                       fcntl(as->fd, F_SETFD, fd_opts | FD_CLOEXEC);
+#endif
+       }
+
+       if (as->fd != -1) {
                /* If there is an error reading, just use what is
                 * on the stack. */
                /* coverity[check_return] */
-               (void)read(fd, rdat.rnd, sizeof(rdat.rnd));
-               close(fd);
+               (void)read(as->fd, rdat.rnd, sizeof(rdat.rnd));
        }
 
        /* fd < 0?  Ah, what the heck. We'll just take
index 6f042815743e60aa495d5f14796446536f90df51..858525f7bab15baf9bbfefdebbf41b26927879ca 100644 (file)
@@ -321,6 +321,12 @@ ps_start(struct dhcpcd_ctx *ctx)
 
        TAILQ_INIT(&ctx->ps_processes);
 
+#ifdef ARC4RANDOM_H
+       /* Seed the random number generator early incase it needs /dev/urandom
+        * which won't be available in the chroot. */
+       arc4random();
+#endif
+
        switch (pid = ps_root_start(ctx)) {
        case -1:
                logerr("ps_root_start");