diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-07-21 07:22:39 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-07-21 07:22:39 +0000 |
commit | 105bddf0dddfe4923f1b2700036f62b47f2c4171 (patch) | |
tree | fab7beffff2f415be941d471ac95f0e1a6d5dd37 /usr.sbin/tcpdump | |
parent | 0352472fa23071429725465bbd7d940366443676 (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.c | 52 |
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, |