diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2015-10-02 13:13:06 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2015-10-02 13:13:06 +0000 |
commit | b06b2ea67d222340d2e40aeff851389a75603ac4 (patch) | |
tree | 7054ca0693baa9bc4d4cd0c8e9881b23e92bd073 | |
parent | 1f8d5025b9e8267e9705d1aa74204150cb5c70c5 (diff) |
Adopt smtpd's imsg_read_nofd() to mitigate the risk of user-injected
file descriptor leakage from the optional world-writable _restricted_
control socket.
OK gilles@ blambert@
-rw-r--r-- | usr.sbin/snmpd/control.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c index 43468ab69c3..77915764f5b 100644 --- a/usr.sbin/snmpd/control.c +++ b/usr.sbin/snmpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.29 2015/05/28 17:08:09 florian Exp $ */ +/* $OpenBSD: control.c,v 1.30 2015/10/02 13:13:05 reyk Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -47,6 +47,7 @@ void control_dispatch_imsg(int, short, void *); void control_dispatch_agentx(int, short, void *); void control_imsg_forward(struct imsg *); void control_event_add(struct ctl_conn *, int, int, struct timeval *); +ssize_t imsg_read_nofd(struct imsgbuf *); int control_init(struct privsep *ps, struct control_sock *cs) @@ -231,7 +232,7 @@ control_dispatch_imsg(int fd, short event, void *arg) int n, v, i; if (event & EV_READ) { - if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { + if ((n = imsg_read_nofd(&c->iev.ibuf)) == -1 || n == 0) { control_close(c); return; } @@ -663,3 +664,26 @@ control_event_add(struct ctl_conn *c, int fd, int wflag, struct timeval *tv) event_set(&c->iev.ev, fd, EV_READ|wflag, control_dispatch_agentx, c); event_add(&c->iev.ev, tv); } + +/* This should go into libutil, from smtpd/mproc.c */ +ssize_t +imsg_read_nofd(struct imsgbuf *ibuf) +{ + ssize_t n; + char *buf; + size_t len; + + buf = ibuf->r.buf + ibuf->r.wpos; + len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + + again: + if ((n = recv(ibuf->fd, buf, len, 0)) == -1) { + if (errno != EINTR && errno != EAGAIN) + goto fail; + goto again; + } + + ibuf->r.wpos += n; + fail: + return (n); +} |