-
Notifications
You must be signed in to change notification settings - Fork 829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
-G drops packets if not enough traffic is recorded #1170
Comments
Does |
yes |
Had a look at the code: You don't execute #1171 fixes the problem. Tested on Ubuntu |
Given that Given that, according to C90, section 7.9.5.1 "The
that would indicate a bug in your C library. What am I missing here? Is there a bug in the GNU libc in Ubuntu 24.04.4, such that |
Thanks for your elaborate response! After browsing through more libpcap and Ubuntu's glibc code (which does indeed correctly flush), a colleague noticed that we were seeing 2 distinct "permission denied" errors in our strace output, one from -z (which failed on some systems due to apparmor fun, which is tolerated), and one from tcpdump proper, which failed to create the subsequent files due to insufficient permissions on the directory. Last night I probably did chmod 777 out of desparation at some point, "fixing" the issue without realizing it, and attributed it to my patch. Is the first .pcap file created before the privilege drop, unlike the subsequent files? We have a systemd unit that happily restarted tcpdump, rendering us oblivious to the fact that it kept crashing every 30s, because every new tcpdump process did create a new .pcap file, and thus only a few packets went missing (either during super low load, or during rotation while tcpdump crashed). tl;dr I am a fool and should catch more sleep, sorry for bothering you :( I did read through other code that uses libpcap directly, and it called flush before close, and thus I jumped to conclusions. |
If that didn't get printed to the standard error by tcpdump, with tcpdump then exiting, that's a tcpdump bug.
If so, that's a tcpdump bug, too; the only thing that should be done with elevated privileges is opening the capture device, as that's the only thing that should require elevated privileges. |
Don't worry, it did, that was just my tunnel vision after too many hours of development.
That's interesting, the behaviour on ubuntu is somewhat known (cc @ali-foroughi). I had a closer look today:
Description: Drop root privileges after opening savefile
Forwarded: no
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
@@ -267,6 +267,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
@@ -962,12 +965,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
@@ -1492,6 +1492,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;
@@ -2320,6 +2321,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);
@@ -2377,6 +2391,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
Sorry again for bothering you with problems not caused by you. I'll just raise an issue there, and hope for the best :( |
We are invoking tcpdump as follows:
tcpdump -i router -G 30 -w '%Y_%m_%d-%H_%M_%S.pcap' -s 0 -z touch src net 10.0.0.0/16 and dst net 10.0.0.0/16
After causing some traffic, we get an (unfinished) pcap file as we'd expect:
If we now wait some time (probably >30s, we waited about a minute in our tests) before causing some more traffic, then the previous file is finished without the packets that tcpdump has received, and a new (unfinished) pcap file is created:
As you can see,
2024_04_06-12_53_30.pcap
is only 24 bytes long, which should be the pcap file header size without any packets.The problem perpetuates, as long as our traffic is spurious we never see any packets in any of our files:
cc @ldruschk
The text was updated successfully, but these errors were encountered: