summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/httpd/config.c16
-rw-r--r--usr.sbin/httpd/httpd.h3
-rw-r--r--usr.sbin/httpd/proc.c31
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);
+}