summaryrefslogtreecommitdiff
path: root/usr.sbin/tcpdump
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2016-07-21 07:22:39 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2016-07-21 07:22:39 +0000
commit105bddf0dddfe4923f1b2700036f62b47f2c4171 (patch)
treefab7beffff2f415be941d471ac95f0e1a6d5dd37 /usr.sbin/tcpdump
parent0352472fa23071429725465bbd7d940366443676 (diff)
2004 privsep caused "tcpdump -r" to became a priviledged operation because
we felt chroot-containment was also necessary for off-line analysis. Today use of pledge "stdio" for the packet parser acts as an even better sandbox. We can therefore silently ignore chroot setup failure, and regain tcpdump -r support. Result of a discussion with tedu -- which probably happened because we became aware of the laughable retarded -Z option in upstream tcpdump. ok tedu sthen guenther stsp
Diffstat (limited to 'usr.sbin/tcpdump')
-rw-r--r--usr.sbin/tcpdump/privsep.c52
1 files changed, 20 insertions, 32 deletions
diff --git a/usr.sbin/tcpdump/privsep.c b/usr.sbin/tcpdump/privsep.c
index bd23597f338..8bc37b65795 100644
--- a/usr.sbin/tcpdump/privsep.c
+++ b/usr.sbin/tcpdump/privsep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.c,v 1.40 2015/12/05 19:27:17 mmcc Exp $ */
+/* $OpenBSD: privsep.c,v 1.41 2016/07/21 07:22:38 deraadt Exp $ */
/*
* Copyright (c) 2003 Can Erkin Acar
@@ -136,16 +136,11 @@ priv_init(int argc, char **argv)
int bpfd = -1;
int i, socks[2], cmd, nflag = 0;
struct passwd *pw;
- uid_t uid;
- gid_t gid;
char *cmdbuf, *infile = NULL;
char *RFileName = NULL;
char *WFileName = NULL;
sigset_t allsigs, oset;
- if (geteuid() != 0)
- errx(1, "need root privileges");
-
closefrom(STDERR_FILENO + 1);
for (i = 1; i < _NSIG; i++)
signal(i, SIG_DFL);
@@ -162,31 +157,33 @@ priv_init(int argc, char **argv)
err(1, "fork() failed");
if (child_pid) {
- /* Parent, drop privileges to _tcpdump */
+ close(socks[0]);
+ priv_fd = socks[1];
+
+ set_slave_signals();
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ /*
+ * Parent, attempt to drop privs and chroot. If any of this
+ * fails that is OK, safety is still provided by pledge(2).
+ */
pw = getpwnam("_tcpdump");
if (pw == NULL)
- errx(1, "unknown user _tcpdump");
+ return (0);
- /* chroot, drop privs and return */
- if (chroot(pw->pw_dir) != 0)
- err(1, "unable to chroot");
- if (chdir("/") != 0)
- err(1, "unable to chdir");
+ /* Attempt to chroot */
+ if (chroot(pw->pw_dir) == -1)
+ return (0);
+ if (chdir("/") == -1)
+ return (0);
/* drop to _tcpdump */
if (setgroups(1, &pw->pw_gid) == -1)
- err(1, "setgroups() failed");
+ return (0);
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
- err(1, "setresgid() failed");
+ return (0);
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
- err(1, "setresuid() failed");
- endpwent();
-
- close(socks[0]);
- priv_fd = socks[1];
-
- set_slave_signals();
- sigprocmask(SIG_SETMASK, &oset, NULL);
+ return (0);
return (0);
}
@@ -194,15 +191,6 @@ priv_init(int argc, char **argv)
sigprocmask(SIG_SETMASK, &oset, NULL);
signal(SIGINT, SIG_IGN);
- /* Child - drop suid privileges */
- gid = getgid();
- uid = getuid();
-
- if (setresgid(gid, gid, gid) == -1)
- err(1, "setresgid() failed");
- if (setresuid(uid, uid, uid) == -1)
- err(1, "setresuid() failed");
-
/* parse the arguments for required options */
opterr = 0;
while ((i = getopt(argc, argv,