privsep: Init the arc4random seed before chrooting

/dev/urandom isn't available in the chroot.
So keep a fd open to it.
This commit is contained in:
Roy Marples 2020-05-24 12:23:20 +00:00
parent 0f1316cd81
commit 83b52a68f9
2 changed files with 27 additions and 6 deletions

View 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

View 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");