Move privileged initialization from frontend to main process.
authorflorian <florian@openbsd.org>
Sun, 10 Dec 2017 10:07:54 +0000 (10:07 +0000)
committerflorian <florian@openbsd.org>
Sun, 10 Dec 2017 10:07:54 +0000 (10:07 +0000)
Needed for future work where we will spin up children via
fork - privdrop - exec. Child processes will no longer come
up with root privileges.

sbin/slaacd/control.c
sbin/slaacd/frontend.c
sbin/slaacd/frontend.h
sbin/slaacd/slaacd.c
sbin/slaacd/slaacd.h

index 76b0f3b..6fd83bb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: control.c,v 1.1 2017/06/03 10:00:29 florian Exp $     */
+/*     $OpenBSD: control.c,v 1.2 2017/12/10 10:07:54 florian Exp $     */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -85,9 +85,7 @@ control_init(char *path)
                return (-1);
        }
 
-       control_state.fd = fd;
-
-       return (0);
+       return (fd);
 }
 
 int
index 8998e3d..3a193e2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frontend.c,v 1.9 2017/11/04 17:23:05 florian Exp $    */
+/*     $OpenBSD: frontend.c,v 1.10 2017/12/10 10:07:54 florian Exp $   */
 
 /*
  * Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -84,7 +84,7 @@ struct nd_router_solicit       rs;
 struct nd_opt_hdr               nd_opt_hdr;
 struct ether_addr               nd_opt_source_link_addr;
 struct sockaddr_in6             dst;
-int                             icmp6sock, routesock, ioctlsock;
+int                             icmp6sock = -1, ioctlsock;
 
 struct icmp6_ev {
        struct event             ev;
@@ -112,24 +112,21 @@ frontend_sig_handler(int sig, short event, void *bula)
 }
 
 void
-frontend(int debug, int verbose, char *sockname)
+frontend(int debug, int verbose)
 {
        struct event             ev_sigint, ev_sigterm;
        struct passwd           *pw;
-       struct icmp6_filter      filt;
        struct in6_pktinfo      *pi;
        struct cmsghdr          *cm;
        size_t                   rcvcmsglen, sndcmsglen;
-       int                      hoplimit = 255, on = 1, rtfilter;
+       int                      hoplimit = 255;
        uint8_t                 *rcvcmsgbuf, *sndcmsgbuf;
 
        log_init(debug, LOG_DAEMON);
        log_setverbose(verbose);
 
 #ifndef        SMALL
-       /* Create slaacd control socket outside chroot. */
-       if (control_init(sockname) == -1)
-               fatalx("control socket setup failed");
+       control_state.fd = -1;
 #endif /* SMALL */
 
        if ((pw = getpwnam(SLAACD_USER)) == NULL)
@@ -144,12 +141,6 @@ frontend(int debug, int verbose, char *sockname)
        setproctitle("%s", log_procnames[slaacd_process]);
        log_procinit(log_procnames[slaacd_process]);
 
-       if ((icmp6sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
-               fatal("ICMPv6 socket");
-
-       if ((routesock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
-               fatal("route socket");
-
        if ((ioctlsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
                fatal("socket");
 
@@ -158,27 +149,6 @@ frontend(int debug, int verbose, char *sockname)
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
 
-       if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
-           sizeof(on)) < 0)
-               fatal("IPV6_RECVPKTINFO");
-
-       if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
-           sizeof(on)) < 0)
-               fatal("IPV6_RECVHOPLIMIT");
-
-       /* only router advertisements */
-       ICMP6_FILTER_SETBLOCKALL(&filt);
-       ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
-       if (setsockopt(icmp6sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
-           sizeof(filt)) == -1)
-               fatal("ICMP6_FILTER");
-
-       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
-           ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL);
-       if (setsockopt(routesock, PF_ROUTE, ROUTE_MSGFILTER,
-           &rtfilter, sizeof(rtfilter)) < 0)
-               fatal("setsockopt(ROUTE_MSGFILTER)");
-
        if (pledge("stdio inet recvfd route", NULL) == -1)
                fatal("pledge");
 
@@ -202,18 +172,6 @@ frontend(int debug, int verbose, char *sockname)
            iev_main->handler, iev_main);
        event_add(&iev_main->ev, NULL);
 
-#ifndef        SMALL
-       /* Listen on control socket. */
-       TAILQ_INIT(&ctl_conns);
-       control_listen();
-#endif /* SMALL */
-
-       event_set(&ev_route, routesock, EV_READ | EV_PERSIST, route_receive,
-           NULL);
-
-       event_set(&icmp6ev.ev, icmp6sock, EV_READ | EV_PERSIST, icmp6_receive,
-           NULL);
-
        rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
            CMSG_SPACE(sizeof(int));
        if((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL)
@@ -369,12 +327,38 @@ frontend_dispatch_main(int fd, short event, void *bula)
                        event_set(&iev_engine->ev, iev_engine->ibuf.fd,
                        iev_engine->events, iev_engine->handler, iev_engine);
                        event_add(&iev_engine->ev, NULL);
-
-                       if (pledge("stdio inet route", NULL) == -1)
-                               fatal("pledge");
-
+                       break;
+               case IMSG_ICMP6SOCK:
+                       if ((icmp6sock = imsg.fd) == -1)
+                               fatalx("%s: expected to receive imsg "
+                                   "ICMPv6 fd but didn't receive any",
+                                   __func__);
+                       event_set(&icmp6ev.ev, icmp6sock, EV_READ | EV_PERSIST,
+                           icmp6_receive, NULL);
+                       break;
+               case IMSG_ROUTESOCK:
+                       if ((fd = imsg.fd) == -1)
+                               fatalx("%s: expected to receive imsg "
+                                   "routesocket fd but didn't receive any",
+                                   __func__);
+                       event_set(&ev_route, fd, EV_READ | EV_PERSIST,
+                           route_receive, NULL);
+                       break;
+#ifndef        SMALL
+               case IMSG_CONTROLFD:
+                       if ((fd = imsg.fd) == -1)
+                               fatalx("%s: expected to receive imsg "
+                                   "control fd but didn't receive any",
+                                   __func__);
+                       control_state.fd = fd;
+                       /* Listen on control socket. */
+                       TAILQ_INIT(&ctl_conns);
+                       control_listen();
+#endif /* SMALL */
                        break;
                case IMSG_STARTUP:
+                       if (pledge("stdio inet route", NULL) == -1)
+                               fatal("pledge");
                        frontend_startup();
                        break;
 #ifndef        SMALL
@@ -616,7 +600,16 @@ frontend_startup(void)
 {
        struct if_nameindex     *ifnidxp, *ifnidx;
 
+       if (!event_initialized(&ev_route))
+               fatalx("%s: did not receive a route socket from the main "
+                   "process", __func__);
+
        event_add(&ev_route, NULL);
+
+       if (!event_initialized(&icmp6ev.ev))
+               fatalx("%s: did not receive a icmp6 socket fd from the main "
+                   "process", __func__);
+
        event_add(&icmp6ev.ev, NULL);
 
        if ((ifnidxp = if_nameindex()) == NULL)
index 531d720..061f542 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frontend.h,v 1.2 2017/07/06 15:02:53 florian Exp $    */
+/*     $OpenBSD: frontend.h,v 1.3 2017/12/10 10:07:54 florian Exp $    */
 
 /*
  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -20,7 +20,7 @@
 TAILQ_HEAD(ctl_conns, ctl_conn)        ctl_conns;
 #endif /* SMALL */
 
-void            frontend(int, int, char *);
+void            frontend(int, int);
 void            frontend_dispatch_main(int, short, void *);
 void            frontend_dispatch_engine(int, short, void *);
 int             frontend_imsg_compose_main(int, pid_t, void *, uint16_t);
index 02c8011..88dc4ec 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: slaacd.c,v 1.12 2017/11/03 12:28:41 florian Exp $     */
+/*     $OpenBSD: slaacd.c,v 1.13 2017/12/10 10:07:54 florian Exp $     */
 
 /*
  * Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -31,6 +31,7 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 #include <netinet6/in6_var.h>
+#include <netinet/icmp6.h>
 
 #include <err.h>
 #include <errno.h>
@@ -68,6 +69,9 @@ const char* imsg_type_name[] = {
        "IMSG_UPDATE_ADDRESS",
        "IMSG_CTL_SEND_SOLICITATION",
        "IMSG_SOCKET_IPC",
+       "IMSG_ICMP6SOCK",
+       "IMSG_ROUTESOCK",
+       "IMSG_CONTROLFD",
        "IMSG_STARTUP",
        "IMSG_UPDATE_IF",
        "IMSG_REMOVE_IF",
@@ -87,7 +91,7 @@ __dead void   main_shutdown(void);
 
 void   main_sig_handler(int, short, void *);
 
-static pid_t   start_child(int, char *, int, int, int, char *);
+static pid_t   start_child(int, char *, int, int, int);
 
 void   main_dispatch_frontend(int, short, void *);
 void   main_dispatch_engine(int, short, void *);
@@ -98,6 +102,9 @@ void add_gateway(struct imsg_configure_dfr *);
 void   delete_gateway(struct imsg_configure_dfr *);
 
 static int     main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
+int            main_imsg_compose_frontend(int, pid_t, void *, uint16_t);
+int            main_imsg_compose_frontend_fd(int, pid_t, int);
+int            main_imsg_compose_engine(int, pid_t, void *, uint16_t);
 
 struct imsgev          *iev_frontend;
 struct imsgev          *iev_engine;
@@ -144,13 +151,17 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-       struct event     ev_sigint, ev_sigterm, ev_sighup;
-       int              ch;
-       int              debug = 0, engine_flag = 0, frontend_flag = 0;
-       int              verbose = 0;
-       char            *saved_argv0;
-       int              pipe_main2frontend[2];
-       int              pipe_main2engine[2];
+       struct event             ev_sigint, ev_sigterm, ev_sighup;
+       struct icmp6_filter      filt;
+       int                      ch;
+       int                      debug = 0, engine_flag = 0, frontend_flag = 0;
+       int                      verbose = 0;
+       char                    *saved_argv0;
+       int                      pipe_main2frontend[2];
+       int                      pipe_main2engine[2];
+       int                      icmp6sock, on = 1;
+       int                      frontend_routesock, rtfilter;
+       int                      control_fd;
 
        csock = SLAACD_SOCKET;
 
@@ -191,7 +202,7 @@ main(int argc, char *argv[])
        if (engine_flag)
                engine(debug, verbose);
        else if (frontend_flag)
-               frontend(debug, verbose, csock);
+               frontend(debug, verbose);
 
        /* Check for root privileges. */
        if (geteuid())
@@ -218,9 +229,9 @@ main(int argc, char *argv[])
 
        /* Start children. */
        engine_pid = start_child(PROC_ENGINE, saved_argv0, pipe_main2engine[1],
-           debug, verbose, NULL);
+           debug, verbose);
        frontend_pid = start_child(PROC_FRONTEND, saved_argv0,
-           pipe_main2frontend[1], debug, verbose, csock);
+           pipe_main2frontend[1], debug, verbose);
 
        slaacd_process = PROC_MAIN;
 
@@ -274,6 +285,42 @@ BROKEN     if (pledge("rpath stdio sendfd cpath", NULL) == -1)
                fatal("pledge");
 #endif
 
+       if ((icmp6sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
+               fatal("ICMPv6 socket");
+
+       if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
+           sizeof(on)) < 0)
+               fatal("IPV6_RECVPKTINFO");
+
+       if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
+           sizeof(on)) < 0)
+               fatal("IPV6_RECVHOPLIMIT");
+
+       /* only router advertisements */
+       ICMP6_FILTER_SETBLOCKALL(&filt);
+       ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
+       if (setsockopt(icmp6sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
+           sizeof(filt)) == -1)
+               fatal("ICMP6_FILTER");
+
+       main_imsg_compose_frontend_fd(IMSG_ICMP6SOCK, 0, icmp6sock);
+
+       if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
+               fatal("route socket");
+
+       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
+           ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL);
+       if (setsockopt(frontend_routesock, PF_ROUTE, ROUTE_MSGFILTER,
+           &rtfilter, sizeof(rtfilter)) < 0)
+               fatal("setsockopt(ROUTE_MSGFILTER)");
+
+       main_imsg_compose_frontend_fd(IMSG_ROUTESOCK, 0, frontend_routesock);
+
+       if ((control_fd = control_init(csock)) == -1)
+               fatalx("control socket setup failed");
+
+       main_imsg_compose_frontend_fd(IMSG_CONTROLFD, 0, control_fd);
+
        main_imsg_compose_frontend(IMSG_STARTUP, 0, NULL, 0);
 
        event_dispatch();
@@ -318,7 +365,7 @@ main_shutdown(void)
 }
 
 static pid_t
-start_child(int p, char *argv0, int fd, int debug, int verbose, char *sockname)
+start_child(int p, char *argv0, int fd, int debug, int verbose)
 {
        char    *argv[8];
        int      argc = 0;
@@ -354,10 +401,6 @@ start_child(int p, char *argv0, int fd, int debug, int verbose, char *sockname)
                argv[argc++] = "-v";
        if (verbose > 1)
                argv[argc++] = "-v";
-       if (sockname) {
-               argv[argc++] = "-s";
-               argv[argc++] = sockname;
-       }
        argv[argc++] = NULL;
 
        execvp(argv0, argv);
@@ -530,6 +573,16 @@ main_imsg_compose_frontend(int type, pid_t pid, void *data, uint16_t datalen)
                return (-1);
 }
 
+int
+main_imsg_compose_frontend_fd(int type, pid_t pid, int fd)
+{
+       if (iev_frontend)
+               return (imsg_compose_event(iev_frontend, type, 0, pid, fd,
+                   NULL, 0));
+       else
+               return (-1);
+}
+
 int
 main_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen)
 {
index d32270a..9e2fe0f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: slaacd.h,v 1.10 2017/08/23 15:49:08 florian Exp $     */
+/*     $OpenBSD: slaacd.h,v 1.11 2017/12/10 10:07:54 florian Exp $     */
 
 /*
  * Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -55,6 +55,9 @@ enum imsg_type {
 #endif /* SMALL */
        IMSG_CTL_SEND_SOLICITATION,
        IMSG_SOCKET_IPC,
+       IMSG_ICMP6SOCK,
+       IMSG_ROUTESOCK,
+       IMSG_CONTROLFD,
        IMSG_STARTUP,
        IMSG_UPDATE_IF,
        IMSG_REMOVE_IF,
@@ -189,8 +192,6 @@ struct imsg_ra {
 };
 
 /* slaacd.c */
-int            main_imsg_compose_frontend(int, pid_t, void *, uint16_t);
-int            main_imsg_compose_engine(int, pid_t, void *, uint16_t);
 void           imsg_event_add(struct imsgev *);
 int            imsg_compose_event(struct imsgev *, uint16_t, uint32_t, pid_t,
                    int, void *, uint16_t);