summaryrefslogtreecommitdiff
path: root/usr.sbin/tcpdump/privsep.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2015-07-14 20:23:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2015-07-14 20:23:41 +0000
commit7fb8f0be32af74edc554b2aaf1f3b53ce7fd39d1 (patch)
tree1cf5f960053323d31d9eaa99052152e51b3efec7 /usr.sbin/tcpdump/privsep.c
parent7b266653de7693c101e88bab13bf257f555bc1f0 (diff)
Move the BIOCGSTATS ioctl operation done by the tcpdump process
(at ^C time) into a services provided by the privsep monitor. ok canacar
Diffstat (limited to 'usr.sbin/tcpdump/privsep.c')
-rw-r--r--usr.sbin/tcpdump/privsep.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/usr.sbin/tcpdump/privsep.c b/usr.sbin/tcpdump/privsep.c
index c416eadb456..6f0c0861a36 100644
--- a/usr.sbin/tcpdump/privsep.c
+++ b/usr.sbin/tcpdump/privsep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.c,v 1.33 2015/03/15 00:41:28 millert Exp $ */
+/* $OpenBSD: privsep.c,v 1.34 2015/07/14 20:23:40 deraadt Exp $ */
/*
* Copyright (c) 2003 Can Erkin Acar
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
+#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -59,7 +60,8 @@ enum priv_state {
STATE_INIT, /* initial state */
STATE_BPF, /* input file/device opened */
STATE_FILTER, /* filter applied */
- STATE_RUN /* running and accepting network traffic */
+ STATE_RUN, /* running and accepting network traffic */
+ STATE_EXIT /* in the process of dying */
};
#define ALLOW(action) (1 << (action))
@@ -76,7 +78,8 @@ static const int allowed_max[] = {
ALLOW(PRIV_ETHER_NTOHOST) | ALLOW(PRIV_INIT_DONE),
/* RUN */ ALLOW(PRIV_GETHOSTBYADDR) | ALLOW(PRIV_ETHER_NTOHOST) |
ALLOW(PRIV_GETRPCBYNUMBER) | ALLOW(PRIV_GETLINES) |
- ALLOW(PRIV_LOCALTIME)
+ ALLOW(PRIV_LOCALTIME) | ALLOW(PRIV_PCAP_STATS),
+ /* EXIT */ 0
};
/*
@@ -87,7 +90,9 @@ static int allowed_ext[] = {
/* INIT */ ALLOW(PRIV_SETFILTER),
/* BPF */ ALLOW(PRIV_SETFILTER),
/* FILTER */ ALLOW(PRIV_GETSERVENTRIES),
- /* RUN */ ALLOW(PRIV_GETLINES) | ALLOW(PRIV_LOCALTIME)
+ /* RUN */ ALLOW(PRIV_GETLINES) | ALLOW(PRIV_LOCALTIME) |
+ ALLOW(PRIV_PCAP_STATS),
+ /* EXIT */ 0
};
struct ftab {
@@ -120,6 +125,7 @@ static void impl_getserventries(int);
static void impl_getprotoentries(int);
static void impl_localtime(int fd);
static void impl_getlines(int);
+static void impl_pcap_stats(int, int *);
static void test_state(int, int);
static void logmsg(int, const char *, ...);
@@ -186,6 +192,7 @@ priv_init(int argc, char **argv)
}
sigprocmask(SIG_SETMASK, &oset, NULL);
+ signal(SIGINT, SIG_IGN);
/* Child - drop suid privileges */
gid = getgid();
@@ -303,6 +310,10 @@ priv_init(int argc, char **argv)
test_state(cmd, STATE_RUN);
impl_getlines(socks[0]);
break;
+ case PRIV_PCAP_STATS:
+ test_state(cmd, STATE_RUN);
+ impl_pcap_stats(socks[0], &bpfd);
+ break;
default:
logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);
_exit(1);
@@ -390,8 +401,6 @@ impl_setfilter(int fd, char *cmdbuf, int *bpfd)
if (setfilter(*bpfd, fd, cmdbuf))
logmsg(LOG_DEBUG, "[priv]: setfilter() failed");
- close(*bpfd); /* done with bpf descriptor */
- *bpfd = -1;
}
static void
@@ -401,8 +410,6 @@ impl_init_done(int fd, int *bpfd)
logmsg(LOG_DEBUG, "[priv]: msg PRIV_INIT_DONE received");
- close(*bpfd); /* done with bpf descriptor */
- *bpfd = -1;
ret = 0;
must_write(fd, &ret, sizeof(ret));
}
@@ -581,6 +588,19 @@ impl_getlines(int fd)
fclose(fp);
}
+static void
+impl_pcap_stats(int fd, int *bpfd)
+{
+ struct pcap_stat stats;
+
+ logmsg(LOG_DEBUG, "[priv]: msg PRIV_PCAP_STATS received");
+
+ if (ioctl(*bpfd, BIOCGSTATS, &stats) == -1)
+ write_zero(fd);
+ else
+ must_write(fd, &stats, sizeof(stats));
+}
+
void
priv_init_done(void)
{
@@ -740,6 +760,17 @@ priv_getlines(size_t sz)
must_write(priv_fd, &sz, sizeof(size_t));
}
+int
+priv_pcap_stats(struct pcap_stat *ps)
+{
+ if (priv_fd < 0)
+ errx(1, "%s: called from privileged portion", __func__);
+
+ write_command(priv_fd, PRIV_PCAP_STATS);
+ must_read(priv_fd, ps, sizeof(*ps));
+ return (0);
+}
+
/* retrieve a line from a file, should be called repeatedly after calling
priv_getlines(), until it returns zero. */
size_t