Bug 1223329 - [abrt] tcpdump: _nss_files_getpwnam_r(): tcpdump killed by SIGSEGV
Summary: [abrt] tcpdump: _nss_files_getpwnam_r(): tcpdump killed by SIGSEGV
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: tcpdump
Version: 21
Hardware: x86_64
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Michal Sekletar
QA Contact: Fedora Extras Quality Assurance
URL: https://retrace.fedoraproject.org/faf...
Whiteboard: abrt_hash:a54ba77c9b7bae7f51bac1dee0c...
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-05-20 10:54 UTC by Jeremy Harris
Modified: 2015-07-14 15:37 UTC (History)
4 users (show)

Fixed In Version: tcpdump-4.7.4-2.fc21
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-07-13 19:12:06 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
File: backtrace (9.10 KB, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: cgroup (190 bytes, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: core_backtrace (1.27 KB, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: dso_list (823 bytes, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: environ (3.08 KB, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: exploitable (82 bytes, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: limits (1.29 KB, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: maps (4.53 KB, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: open_fds (348 bytes, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details
File: proc_pid_status (934 bytes, text/plain)
2015-05-20 10:54 UTC, Jeremy Harris
no flags Details

Description Jeremy Harris 2015-05-20 10:54:18 UTC
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

Comment 1 Jeremy Harris 2015-05-20 10:54:21 UTC
Created attachment 1027624 [details]
File: backtrace

Comment 2 Jeremy Harris 2015-05-20 10:54:22 UTC
Created attachment 1027625 [details]
File: cgroup

Comment 3 Jeremy Harris 2015-05-20 10:54:23 UTC
Created attachment 1027626 [details]
File: core_backtrace

Comment 4 Jeremy Harris 2015-05-20 10:54:25 UTC
Created attachment 1027627 [details]
File: dso_list

Comment 5 Jeremy Harris 2015-05-20 10:54:26 UTC
Created attachment 1027628 [details]
File: environ

Comment 6 Jeremy Harris 2015-05-20 10:54:27 UTC
Created attachment 1027629 [details]
File: exploitable

Comment 7 Jeremy Harris 2015-05-20 10:54:28 UTC
Created attachment 1027630 [details]
File: limits

Comment 8 Jeremy Harris 2015-05-20 10:54:30 UTC
Created attachment 1027631 [details]
File: maps

Comment 9 Jeremy Harris 2015-05-20 10:54:31 UTC
Created attachment 1027632 [details]
File: open_fds

Comment 10 Jeremy Harris 2015-05-20 10:54:32 UTC
Created attachment 1027633 [details]
File: proc_pid_status

Comment 11 Christian 2015-06-24 01:20:32 UTC
I see the exact same problem, with any pcap, whenever I use -w. Any comments here? Bizarre.

-C.

Comment 12 Christian 2015-06-26 01:09:53 UTC
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

Comment 13 Jeremy Harris 2015-06-26 16:19:17 UTC
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);

Comment 14 Jeremy Harris 2015-06-26 16:27:24 UTC
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.

Comment 15 Michal Sekletar 2015-06-29 18:50:44 UTC
(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.

Comment 16 Pekka Pietikäinen 2015-06-30 11:39:32 UTC
Hint: This only triggers when you're NOT running as root ;-)

Comment 17 Michal Sekletar 2015-06-30 11:42:50 UTC
(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.

Comment 18 Pekka Pietikäinen 2015-06-30 12:46:22 UTC
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

Comment 19 Fedora Update System 2015-06-30 13:22:43 UTC
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

Comment 20 Fedora Update System 2015-06-30 13:23:56 UTC
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

Comment 21 Fedora Update System 2015-07-02 17:05:03 UTC
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).

Comment 22 Fedora Update System 2015-07-13 19:12:06 UTC
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.

Comment 23 Fedora Update System 2015-07-14 15:37:14 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.