diff options
author | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2019-03-31 04:54:21 +0000 |
---|---|---|
committer | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2019-03-31 04:54:21 +0000 |
commit | e145e69f2295a9e6d92f9122b47d40e5c8784fc7 (patch) | |
tree | a118f930f2cfd87d696c0cd3ee8cdcd38f40b064 | |
parent | 872b85a91e0cc15599cdb71db920b994023d8d0e (diff) |
Modify radiusd_bsdauth module to do "fork + exec" main process instead of
just fork to have separate ASLR/cookies per process. Based on claudio@ work
for bgpd.
-rw-r--r-- | usr.sbin/radiusd/radiusd_bsdauth.c | 86 |
1 files changed, 62 insertions, 24 deletions
diff --git a/usr.sbin/radiusd/radiusd_bsdauth.c b/usr.sbin/radiusd/radiusd_bsdauth.c index 7f03a0c41ee..ccdcdb91a44 100644 --- a/usr.sbin/radiusd/radiusd_bsdauth.c +++ b/usr.sbin/radiusd/radiusd_bsdauth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radiusd_bsdauth.c,v 1.8 2017/08/21 21:41:13 deraadt Exp $ */ +/* $OpenBSD: radiusd_bsdauth.c,v 1.9 2019/03/31 04:54:20 yasuoka Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -25,6 +25,7 @@ #include <bsd_auth.h> #include <err.h> #include <errno.h> +#include <fcntl.h> #include <grp.h> #include <imsg.h> #include <login_cap.h> @@ -61,11 +62,13 @@ struct auth_groupcheck_args { size_t grouplen; }; -static pid_t module_bsdauth_main(int, int); +__dead static void + module_bsdauth_main(void); static void module_bsdauth_config_set(void *, const char *, int, char * const *); static void module_bsdauth_userpass(void *, u_int, const char *, const char *); +static pid_t start_child(char *, int); __dead static void fatal(const char *); @@ -77,25 +80,40 @@ static struct module_handlers module_bsdauth_handlers = { int main(int argc, char *argv[]) { - int pipe_chld, pairsock[2], status; + int ch, pairsock[2], status; struct imsgbuf ibuf; struct imsg imsg; ssize_t n; size_t datalen; pid_t pid; + char *saved_argv0; + + while ((ch = getopt(argc, argv, "M")) != -1) + switch (ch) { + case 'M': + module_bsdauth_main(); + /* never return, not reached here */ + break; + default: + break; + } + saved_argv0 = argv[0]; + argc -= optind; + argv += optind; - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pairsock) == -1) + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, + PF_UNSPEC, pairsock) == -1) err(EXIT_FAILURE, "socketpair"); - pipe_chld = pairsock[1]; - pid = module_bsdauth_main(pairsock[0], pairsock[1]); + openlog(NULL, LOG_PID, LOG_DAEMON); + + pid = start_child(saved_argv0, pairsock[1]); /* * Privileged process */ - openlog(NULL, LOG_PID, LOG_DAEMON); setproctitle("[priv]"); - imsg_init(&ibuf, pipe_chld); + imsg_init(&ibuf, pairsock[0]); if (pledge("stdio getpw rpath proc exec", NULL) == -1) err(EXIT_FAILURE, "pledge"); @@ -210,24 +228,15 @@ group_done: exit(WEXITSTATUS(status)); } -static pid_t -module_bsdauth_main(int pipe_prnt, int pipe_chld) +static void +module_bsdauth_main(void) { int i; - pid_t pid; struct module_bsdauth module_bsdauth; - pid = fork(); - if (pid == -1) - err(EXIT_FAILURE, "fork"); - - if (pid > 0) { - close(pipe_prnt); - return (pid); - } - close(pipe_chld); - - /* main process */ + /* + * main process + */ setproctitle("[main]"); openlog(NULL, LOG_PID, LOG_DAEMON); memset(&module_bsdauth, 0, sizeof(module_bsdauth)); @@ -238,7 +247,7 @@ module_bsdauth_main(int pipe_prnt, int pipe_chld) module_drop_privilege(module_bsdauth.base); module_load(module_bsdauth.base); - imsg_init(&module_bsdauth.ibuf, pipe_prnt); + imsg_init(&module_bsdauth.ibuf, 3); if (pledge("stdio proc", NULL) == -1) err(EXIT_FAILURE, "pledge"); @@ -255,7 +264,7 @@ module_bsdauth_main(int pipe_prnt, int pipe_chld) } free(module_bsdauth.okgroups); - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } static void @@ -378,6 +387,35 @@ auth_ng: return; } +pid_t +start_child(char *argv0, int fd) +{ + char *argv[5]; + int argc = 0; + pid_t pid; + + switch (pid = fork()) { + case -1: + fatal("cannot fork"); + case 0: + break; + default: + close(fd); + return (pid); + } + + if (fd != 3) { + if (dup2(fd, 3) == -1) + fatal("cannot setup imsg fd"); + } else if (fcntl(fd, F_SETFD, 0) == -1) + fatal("cannot setup imsg fd"); + + argv[argc++] = argv0; + argv[argc++] = "-M"; /* main proc */ + execvp(argv0, argv); + fatal("execvp"); +} + static void fatal(const char *msg) { |