summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2019-03-31 04:54:21 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2019-03-31 04:54:21 +0000
commite145e69f2295a9e6d92f9122b47d40e5c8784fc7 (patch)
treea118f930f2cfd87d696c0cd3ee8cdcd38f40b064
parent872b85a91e0cc15599cdb71db920b994023d8d0e (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.c86
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)
{