Index: sbin/dumpon/dumpon.c =================================================================== --- sbin/dumpon/dumpon.c +++ sbin/dumpon/dumpon.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -210,7 +211,7 @@ #ifdef HAVE_CRYPTO static void -genkey(const char *pubkeyfile, struct diocskerneldump_arg *kdap) +_genkey(const char *pubkeyfile, struct diocskerneldump_arg *kdap) { FILE *fp; RSA *pubkey; @@ -305,6 +306,50 @@ } RSA_free(pubkey); } + +/* + * Run genkey() in a child so it can use capability mode without affecting + * the rest of the runtime. + */ +static void +genkey(const char *pubkeyfile, struct diocskerneldump_arg *kdap) +{ + pid_t pid; + int error, filedes[2], status; + + if (pipe2(filedes, O_CLOEXEC) != 0) + err(1, "pipe"); + pid = fork(); + switch (pid) { + case -1: + err(1, "fork"); + break; + case 0: + close(filedes[0]); + _genkey(pubkeyfile, kdap); + /* Write the new kdap back to the parent. */ + error = write(filedes[1], kdap, sizeof(*kdap)); + if (error != sizeof(*kdap)) + err(1, "genkey pipe write"); + exit(0); + } + close(filedes[1]); + /* Read in the child's genkey() result into kdap. */ + error = read(filedes[0], kdap, sizeof(*kdap)); + if (error != sizeof(*kdap)) + errx(1, "genkey pipe read"); + error = waitpid(pid, &status, WEXITED); + if (error == -1) + err(1, "waitpid"); + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) + errx(1, "genkey child exited with status %d", + WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + errx(1, "genkey child exited with signal %d", + WTERMSIG(status)); + close(filedes[0]); + return; +} #endif static void