Description of problem: Trying to split off a portion of a large (2.5GB) pcap. [jgh@lap h2]$ tcpdump -r ../host-2 -w initial.pcap -c 10000 reading from file ../host-2, link-type EN10MB (Ethernet) Segmentation fault (core dumped) [jgh@lap h2]$ ls -l ../host-2 -rw-rw-r--. 1 jgh jgh 2685327820 May 20 00:00 ../host-2 [jgh@lap h2]$ file ../host-2 ../host-2: pcap-ng capture file - version 1.0 [jgh@lap h2]$ Version-Release number of selected component: tcpdump-4.7.4-1.fc21 Additional info: reporter: libreport-2.3.0 backtrace_rating: 4 cmdline: tcpdump -r ../host-2 -w initial.pcap -c 10000 crash_function: _nss_files_getpwnam_r executable: /usr/sbin/tcpdump kernel: 3.19.7-200.fc21.x86_64 runlevel: N 5 type: CCpp uid: 1000 var_log_messages: [System Logs]:\n-- Logs begin at Thu 2013-07-11 14:04:34 BST, end at Wed 2015-05-20 11:49:12 BST. -- Truncated backtrace: Thread no. 1 (3 frames) #0 _nss_files_getpwnam_r at nss_files/files-pwd.c:32 #1 __getpwnam_r at ../nss/getXXbyYY_r.c:266 #2 getpwnam at ../nss/getXXbyYY.c:116
Created attachment 1027624 [details] File: backtrace
Created attachment 1027625 [details] File: cgroup
Created attachment 1027626 [details] File: core_backtrace
Created attachment 1027627 [details] File: dso_list
Created attachment 1027628 [details] File: environ
Created attachment 1027629 [details] File: exploitable
Created attachment 1027630 [details] File: limits
Created attachment 1027631 [details] File: maps
Created attachment 1027632 [details] File: open_fds
Created attachment 1027633 [details] File: proc_pid_status
I see the exact same problem, with any pcap, whenever I use -w. Any comments here? Bizarre. -C.
Here's a backtrace with symbols. getpwnam() is called with a null pointer. Casual reading of the source suggests chown_flag might be uninitialized. -C. (gdb) run -nn -r udp.trace -w foo Starting program: /usr/sbin/tcpdump -nn -r udp.trace -w foo reading from file udp.trace, link-type EN10MB (Ethernet) Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7769f09 in _nss_files_getpwnam_r (name=0x0, result=0x3f85dba120 <resbuf>, buffer=0xaee0c0 "root", buflen=1024, errnop=0x7ffff799b690) at nss_files/files-pwd.c:32 32 DB_LOOKUP (pwnam, '.', 0, ("%s", name), Missing separate debuginfos, use: debuginfo-install zlib-1.2.8-7.fc21.x86_64 (gdb) bt #0 0x00007ffff7769f09 in _nss_files_getpwnam_r (name=0x0, result=0x3f85dba120 <resbuf>, buffer=0xaee0c0 "root", buflen=1024, errnop=0x7ffff799b690) at nss_files/files-pwd.c:32 #1 0x0000003f85ac32ed in __getpwnam_r (name=name@entry=0x0, resbuf=resbuf@entry=0x3f85dba120 <resbuf>, buffer=0xaee0c0 "root", buflen=buflen@entry=1024, result=result@entry=0x7fffffffc668) at ../nss/getXXbyYY_r.c:266 #2 0x0000003f85ac2d3f in getpwnam (name=name@entry=0x0) at ../nss/getXXbyYY.c:116 #3 0x0000000000405258 in main (argc=<optimized out>, argv=<optimized out>) at ./tcpdump.c:1895
Interesting that (in the source code version I'm looking at, at least) "chown_flag" is declared (with an initialiser) C++-style, embedded in the code rather than traditional-C style at the top of a block. Perhaps this has triggered a compiler bug. 1460 1461 capng_apply(CAPNG_SELECT_BOTH); 1462 } 1463 } 1464 #endif /* HAVE_CAP_NG_H */ 1465 1466 /* If user is running tcpdump as root and wants to write to the savefile, 1467 * we will check if -C is set and if it is, we will drop root 1468 * privileges right away and consequent call to pcap_dump_open() 1469 * will most likely fail for the first file. If -C flag is not set we 1470 * will create file as root then change ownership of file to proper 1471 * user(default tcpdump) and drop root privileges. 1472 */ 1473 int chown_flag = 0; 1474 1475 if (WFileName && (getuid() == 0 || geteuid() == 0)) 1476 if (Cflag && (username || chroot_dir)) 1477 droproot(username, chroot_dir); 1478 else 1479 chown_flag = 1; 1480 else 1481 if ((getuid() == 0 || geteuid() == 0) && (username || chroot_dir)) 1482 droproot(username, chroot_dir); 1483 1484 #endif /* WIN32 */ 1485 1486 if (pcap_setfilter(pd, &fcode) < 0) 1487 error("%s", pcap_geterr(pd)); 1488 if (WFileName) { 1489 pcap_dumper_t *p; 1490 /* Do not exceed the default PATH_MAX for files. */ 1491 dumpinfo.CurrentFileName = (char *)malloc(PATH_MAX + 1); 1492 1493 if (dumpinfo.CurrentFileName == NULL) 1494 error("malloc of dumpinfo.CurrentFileName"); 1495 1496 /* We do not need numbering for dumpfiles if Cflag isn't set. */ 1497 if (Cflag != 0) 1498 MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars); 1499 else 1500 MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); 1501 1502 p = pcap_dump_open(pd, dumpinfo.CurrentFileName); 1503 1504 /* Change ownership of file and drop root privileges */ 1505 if (chown_flag) { 1506 struct passwd *pwd; 1507 1508 pwd = getpwnam(username);
By the way, the #ifdef WIN32 will presumably break the compilation for Windows. Unless it's been somehow defined for us... and still managed to compile but fail at runtime. My head just exploded.
(In reply to Christian from comment #12) > Here's a backtrace with symbols. getpwnam() is called with a null pointer. > Casual reading of the source suggests chown_flag might be uninitialized. chwon_flag maybe used uninitialized, good catch. I must have dropped out proper initialization when I was rebasing to newer upstream. I will fix that. What puzzles me though is the fact that SEGV was caused by calling getpwnam() with NULL passed as an argument. getpwnam() is called in two places, both in tcdpump.c always with username pointer as an argument. During rpm build we configure tcpdump as follows, %configure --with-crypto --with-user=tcpdump --without-smi Thus following code must have caused that pointee of username is string "tcpdump", unless -Z is given as an argument. #ifdef WITH_USER /* if run as root, prepare for dropping root privileges */ if (getuid() == 0 || geteuid() == 0) { /* Run with '-Z root' to restore old behaviour */ if (!username) username = WITH_USER; } #endif AFAICT, username is newer assigned NULL again. Thus I can not see how it can be NULL at line 1895. I will run static analysis tools, maybe I am overlooking something, dunno.
Hint: This only triggers when you're NOT running as root ;-)
(In reply to Pekka Pietikäinen from comment #16) > Hint: This only triggers when you're NOT running as root ;-) Yeah, I've reread the report again and already figured that out also. Thanks anyway.
Yup, looks like it's just interesting undefined behaviour from the undefined chown_flag. If chown_flag is undefined, the assignment "happens" even if the conditions for it never happen (simplified original code): printf("chown, %d\n",chown_flag); if (getuid() == 0 || geteuid() == 0) { printf("getuidcheck, %d\n",chown_flag); if (WFileName) { printf("I am here but not really %d\n",getuid()); chown_flag = 5; } } printf("chown2, %d\n",chown_flag); -> chown, 0 chown2, 5
tcpdump-4.7.4-2.fc22 has been submitted as an update for Fedora 22. https://admin.fedoraproject.org/updates/tcpdump-4.7.4-2.fc22
tcpdump-4.7.4-2.fc21 has been submitted as an update for Fedora 21. https://admin.fedoraproject.org/updates/tcpdump-4.7.4-2.fc21
Package tcpdump-4.7.4-2.fc21: * should fix your issue, * was pushed to the Fedora 21 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing tcpdump-4.7.4-2.fc21' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2015-10988/tcpdump-4.7.4-2.fc21 then log in and leave karma (feedback).
tcpdump-4.7.4-2.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.
tcpdump-4.7.4-2.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report.