Description: Drop root privileges after opening savefile Forwarded: not-needed Bug-Debian: https://bugs.debian.org/935112 Origin: https://src.fedoraproject.org/rpms/tcpdump/raw/master/f/0003-Drop-root-priviledges-before-opening-first-savefile-.patch --- tcpdump.1.in | 7 ++++++- tcpdump.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) --- a/tcpdump.1.in +++ b/tcpdump.1.in @@ -269,6 +269,9 @@ flag, with a number after it, starting at 1 and continuing upward. The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, not 1,048,576 bytes). + +Note that when used with \fB\-Z\fR option (enabled by default), privileges +are dropped before opening first savefile. .TP .B \-d Dump the compiled packet-matching code in a human readable form to @@ -966,12 +969,14 @@ If .I tcpdump is running as root, after opening the capture device or input savefile, -but before opening any savefiles for output, change the user ID to +change the user ID to .I user and the group ID to the primary group of .IR user . .IP -This behavior can also be enabled by default at compile time. +This behavior is enabled by default (\fB\-Z tcpdump\fR), and can +be disabled by \fB\-Z root\fR. + .IP "\fI expression\fP" .RS selects which packets will be dumped. --- a/tcpdump.c +++ b/tcpdump.c @@ -1510,6 +1510,7 @@ cap_rights_t rights; int cansandbox; #endif /* HAVE_CAPSICUM */ + int chown_flag = 0; int Oflag = 1; /* run filter code optimizer */ int yflag_dlt = -1; const char *yflag_dlt_name = NULL; @@ -2338,6 +2339,19 @@ } capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ + /* If user is running tcpdump as root and wants to write to the savefile, + * we will check if -C is set and if it is, we will drop root + * privileges right away and consequent call to>pcap_dump_open() + * will most likely fail for the first file. If -C flag is not set we + * will create file as root then change ownership of file to proper + * user(default tcpdump) and drop root privileges. + */ + if (WFileName) + if (Cflag && (username || chroot_dir)) + droproot(username, chroot_dir); + else + chown_flag = 1; + else if (username || chroot_dir) droproot(username, chroot_dir); @@ -2395,6 +2409,22 @@ #endif /* HAVE_LIBCAP_NG */ if (pdd == NULL) error("%s", pcap_geterr(pd)); + + /* Change ownership of file and drop root privileges */ + if (chown_flag) { + struct passwd *pwd; + + pwd = getpwnam(username); + if (!pwd) + error("Couldn't find user '%s'", username); + + if (strcmp(WFileName, "-") && chown(dumpinfo.CurrentFileName, pwd->pw_uid, pwd->pw_gid) < 0) + error("Couldn't change ownership of savefile"); + + if (username || chroot_dir) + droproot(username, chroot_dir); + } + #ifdef HAVE_CAPSICUM set_dumper_capsicum_rights(pdd); #endif