diff options
-rw-r--r-- | usr.sbin/httpd/config.c | 16 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/httpd/proc.c | 31 |
3 files changed, 42 insertions, 8 deletions
diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index 621c2fee1c6..66fde6fea6d 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.48 2016/09/01 16:07:55 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.49 2016/10/12 10:57:30 reyk Exp $ */ /* * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -210,6 +210,14 @@ config_setserver(struct httpd *env, struct server *srv) __func__, srv->srv_conf.name); return (-1); } + + /* Prevent fd exhaustion in the parent. */ + if (proc_flush_imsg(ps, id, n) == -1) { + log_warn("%s: failed to flush " + "IMSG_CFG_SERVER imsg for `%s'", + __func__, srv->srv_conf.name); + return (-1); + } } /* Configure TLS if necessary. */ @@ -225,6 +233,12 @@ config_setserver(struct httpd *env, struct server *srv) } } + /* Close server socket early to prevent fd exhaustion in the parent. */ + if (srv->srv_s != -1) { + close(srv->srv_s); + srv->srv_s = -1; + } + return (0); } diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index 68836c83083..6cf9b4c763a 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.121 2016/10/05 16:58:19 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.122 2016/10/12 10:57:30 reyk Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -724,6 +724,7 @@ struct imsgbuf * proc_ibuf(struct privsep *, enum privsep_procid, int); struct imsgev * proc_iev(struct privsep *, enum privsep_procid, int); +int proc_flush_imsg(struct privsep *, enum privsep_procid, int); void imsg_event_add(struct imsgev *); int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, pid_t, int, void *, uint16_t); diff --git a/usr.sbin/httpd/proc.c b/usr.sbin/httpd/proc.c index 395fe3f21f4..7f88461a852 100644 --- a/usr.sbin/httpd/proc.c +++ b/usr.sbin/httpd/proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.c,v 1.33 2016/10/10 21:53:46 rzalamena Exp $ */ +/* $OpenBSD: proc.c,v 1.34 2016/10/12 10:57:30 reyk Exp $ */ /* * Copyright (c) 2010 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -434,12 +434,9 @@ proc_open(struct privsep *ps, int src, int dst) * We have to flush to send the descriptors and close * them to avoid the fd ramp on startup. */ - if (imsg_flush(&ps->ps_ievs[src][i].ibuf) == -1 || - imsg_flush(&ps->ps_ievs[dst][j].ibuf) == -1) + if (proc_flush_imsg(ps, src, i) == -1 || + proc_flush_imsg(ps, dst, j) == -1) fatal("%s: imsg_flush", __func__); - - imsg_event_add(&ps->ps_ievs[src][i]); - imsg_event_add(&ps->ps_ievs[dst][j]); } } } @@ -821,3 +818,25 @@ proc_iev(struct privsep *ps, enum privsep_procid id, int n) proc_range(ps, id, &n, &m); return (&ps->ps_ievs[id][n]); } + +/* This function should only be called with care as it breaks async I/O */ +int +proc_flush_imsg(struct privsep *ps, enum privsep_procid id, int n) +{ + struct imsgbuf *ibuf; + int m, ret = 0; + + proc_range(ps, id, &n, &m); + for (; n < m; n++) { + if ((ibuf = proc_ibuf(ps, id, n)) == NULL) + return (-1); + do { + ret = imsg_flush(ibuf); + } while (ret == -1 && errno == EAGAIN); + if (ret == -1) + break; + imsg_event_add(&ps->ps_ievs[id][n]); + } + + return (ret); +} |