From: Roy Marples Date: Sun, 24 May 2020 12:23:20 +0000 (+0000) Subject: privsep: Init the arc4random seed before chrooting X-Git-Tag: v9.1.0~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83b52a68f949b444a724688d21f9cb26bfcdcd90;p=thirdparty%2Fdhcpcd.git privsep: Init the arc4random seed before chrooting /dev/urandom isn't available in the chroot. So keep a fd open to it. --- diff --git a/compat/arc4random.c b/compat/arc4random.c index 045e0234..90098127 100644 --- a/compat/arc4random.c +++ b/compat/arc4random.c @@ -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 diff --git a/src/privsep.c b/src/privsep.c index 6f042815..858525f7 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -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");