Description of problem: Running tcpdump to catch some traffic (monotone, but it shouldn't matter) I get this: *** buffer overflow detected ***: tcpdump terminated ======= Backtrace: ========= /lib/libc.so.6(__chk_fail+0x41)[0x1fc2d5] /lib/libc.so.6[0x1fbd93] /lib/libc.so.6(__snprintf_chk+0x37)[0x1fbc87] tcpdump[0x804b04e] tcpdump[0x804fd32] tcpdump[0x805e60c] tcpdump[0x805eb8a] tcpdump[0x805ee69] tcpdump[0x8091824] tcpdump[0x809e6c2] tcpdump[0x80a0060] tcpdump[0x809235b] /lib/libc.so.6(__libc_start_main+0xdf)[0x13341f] tcpdump[0x804a3d1] ======= Memory map: ======== Version-Release number of selected component (if applicable): How reproducible: tcpdump-3.9.1-1.i386 Steps to Reproduce: 1. 2. 3. Actual results: see above Expected results: no message, no abort Additional info: I tried to locate the bug better but the tcpdump-debuginfo package does not contain the debuginfo for the tcpdump program (I'll file a separate bug). But the disassembled code looks like this: 804b022: 89 44 24 14 mov %eax,0x14(%esp) 804b026: c7 44 24 10 e3 0f 0b movl $0x80b0fe3,0x10(%esp) 804b02d: 08 804b02e: c7 44 24 0c 7b 00 00 movl $0x7b,0xc(%esp) 804b035: 00 804b036: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) 804b03d: 00 804b03e: c7 44 24 04 80 00 00 movl $0x80,0x4(%esp) 804b045: 00 804b046: 89 34 24 mov %esi,(%esp) 804b049: e8 5e ee ff ff call 8049eac <__snprintf_chk@plt> This translates to this call: snprintf(buf, 128, "(oui %s)", ....) (0x80b0fe3 is that string). The actual buffer is only 0x7b bytes long.
OK, this is the code (addrtoname.c): [...] #define BUFSIZE 128 [...] const char * etheraddr_string(register const u_char *ep) { [...] char buf[BUFSIZE]; [...] cp = buf; oui=EXTRACT_24BITS(ep); *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; for (i = 5; (int)--i >= 0;) { *cp++ = ':'; *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; } if (!nflag) { snprintf(cp,BUFSIZE," (oui %s)", tok2str(oui_values,"Unknown",oui)); This is of course wrong. The buffer size passed to snprintf should be BUFSIZE-17.
I've checked that fix into the tcpdump main and x.9 branches (calculating "17" as "2+3*5"), but I'm not sure how the string was large enough to cause this problem - there should be plenty of room in the buffer for a 17-character MAC address, the " (oui " and ")", and the longest of the OUI names in current tcpdump or a 24-bit numerical OUI. (Or does Red Hat's tcpdump have some additional OUI names, some of which are Really Long?)
Read section 2.6 in http://people.redhat.com/drepper/defprogramming.pdf. This problem has not been found due to an actual buffer overrun. The fortified snprintf function just makes sure that none can ever happen. This wasn't the case here.