From 617bb4659ae5ed5638e627838c9f0a172a7eb0b3 Mon Sep 17 00:00:00 2001 From: remi Date: Wed, 29 Aug 2018 08:43:16 +0000 Subject: [PATCH] Prevent ospfd from starting if another ospfd is already using the same socket. The check on the control socket happens early so that the rc scripts detect a failure. OK claudio@ florian@ --- usr.sbin/ospfd/control.c | 32 ++++++++++++++++++++++++++++---- usr.sbin/ospfd/control.h | 3 ++- usr.sbin/ospfd/ospfd.c | 17 ++++++++++++++++- usr.sbin/ospfd/ospfd.h | 4 +++- usr.sbin/ospfd/ospfe.c | 23 +++++++++++++---------- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/usr.sbin/ospfd/control.c b/usr.sbin/ospfd/control.c index 150c38c9b43..09733bc407e 100644 --- a/usr.sbin/ospfd/control.c +++ b/usr.sbin/ospfd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.44 2017/01/24 04:24:25 benno Exp $ */ +/* $OpenBSD: control.c,v 1.45 2018/08/29 08:43:16 remi Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -38,6 +38,32 @@ struct ctl_conn *control_connbyfd(int); struct ctl_conn *control_connbypid(pid_t); void control_close(int); +int +control_check(char *path) +{ + struct sockaddr_un sun; + int fd; + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + log_warn("control_check: socket check"); + return (-1); + } + + if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == 0) { + log_warnx("control_check: socket in use"); + close(fd); + return (-1); + } + + close(fd); + + return (0); +} + int control_init(char *path) { @@ -78,9 +104,7 @@ control_init(char *path) return (-1); } - control_state.fd = fd; - - return (0); + return (fd); } int diff --git a/usr.sbin/ospfd/control.h b/usr.sbin/ospfd/control.h index 27abc2278b6..ce2a6d02c1d 100644 --- a/usr.sbin/ospfd/control.h +++ b/usr.sbin/ospfd/control.h @@ -1,4 +1,4 @@ -/* $OpenBSD: control.h,v 1.6 2015/02/10 05:24:48 claudio Exp $ */ +/* $OpenBSD: control.h,v 1.7 2018/08/29 08:43:16 remi Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -34,6 +34,7 @@ struct ctl_conn { struct imsgev iev; }; +int control_check(char *); int control_init(char *); int control_listen(void); void control_accept(int, short, void *); diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c index 378bc2bfbb0..df80b65733e 100644 --- a/usr.sbin/ospfd/ospfd.c +++ b/usr.sbin/ospfd/ospfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.c,v 1.99 2018/07/11 12:09:34 remi Exp $ */ +/* $OpenBSD: ospfd.c,v 1.100 2018/08/29 08:43:17 remi Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -116,6 +116,7 @@ main(int argc, char *argv[]) int mib[4]; size_t len; char *sockname = NULL; + int control_fd; conffile = CONF_FILE; ospfd_process = PROC_MAIN; @@ -213,6 +214,9 @@ main(int argc, char *argv[]) log_init(debug, LOG_DAEMON); log_setverbose(ospfd_conf->opts & OSPFD_OPT_VERBOSE); + if ((control_check(ospfd_conf->csock)) == -1) + fatalx("control socket check failed"); + if (!debug) daemon(1, 0); @@ -270,6 +274,10 @@ main(int argc, char *argv[]) iev_rde->handler, iev_rde); event_add(&iev_rde->ev, NULL); + if ((control_fd = control_init(ospfd_conf->csock)) == -1) + fatalx("control socket setup failed"); + main_imsg_compose_ospfe_fd(IMSG_CONTROLFD, 0, control_fd); + if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE), ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix) == -1) fatalx("kr_init failed"); @@ -485,6 +493,13 @@ main_imsg_compose_ospfe(int type, pid_t pid, void *data, u_int16_t datalen) imsg_compose_event(iev_ospfe, type, 0, pid, -1, data, datalen); } +void +main_imsg_compose_ospfe_fd(int type, pid_t pid, int fd) +{ + if (iev_ospfe) + imsg_compose_event(iev_ospfe, type, 0, pid, fd, NULL, 0); +} + void main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) { diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 1b772a4acdc..3e8a5af4ab2 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.101 2018/06/25 22:16:53 remi Exp $ */ +/* $OpenBSD: ospfd.h,v 1.102 2018/08/29 08:43:17 remi Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -101,6 +101,7 @@ enum imsg_type { IMSG_CTL_IFINFO, IMSG_CTL_END, IMSG_CTL_LOG_VERBOSE, + IMSG_CONTROLFD, IMSG_KROUTE_CHANGE, IMSG_KROUTE_DELETE, IMSG_IFINFO, @@ -605,6 +606,7 @@ void rtlabel_tag(u_int16_t, u_int32_t); /* ospfd.c */ void main_imsg_compose_ospfe(int, pid_t, void *, u_int16_t); +void main_imsg_compose_ospfe_fd(int, pid_t, int); void main_imsg_compose_rde(int, pid_t, void *, u_int16_t); int ospf_redistribute(struct kroute *, u_int32_t *); void merge_config(struct ospfd_conf *, struct ospfd_conf *); diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index d222670208b..b57ae6941e5 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.101 2018/06/25 22:16:53 remi Exp $ */ +/* $OpenBSD: ospfe.c,v 1.102 2018/08/29 08:43:17 remi Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -90,10 +90,6 @@ ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], /* cleanup a bit */ kif_clear(); - /* create ospfd control socket outside chroot */ - if (control_init(xconf->csock) == -1) - fatalx("control socket setup failed"); - /* create the raw ip socket */ if ((xconf->ospf_socket = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, @@ -136,7 +132,7 @@ ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("can't drop privileges"); - if (pledge("stdio inet mcast", NULL) == -1) + if (pledge("stdio inet mcast recvfd", NULL) == -1) fatal("pledge"); event_init(); @@ -189,10 +185,6 @@ ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], } } - /* listen on ospfd control socket */ - TAILQ_INIT(&ctl_conns); - control_listen(); - if ((pkt_ptr = calloc(1, READ_BUF_SIZE)) == NULL) fatal("ospfe"); @@ -465,6 +457,17 @@ ospfe_dispatch_main(int fd, short event, void *bula) case IMSG_CTL_END: control_imsg_relay(&imsg); break; + 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(); + if (pledge("stdio inet mcast", NULL) == -1) + fatal("pledge"); + break; default: log_debug("ospfe_dispatch_main: error handling imsg %d", imsg.hdr.type); -- 2.20.1