Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 260637 - net-ftp/atftp-0.7-r1 SIGSEGV on ill-formed TFTP ERROR reply lacking the message string.
Summary: net-ftp/atftp-0.7-r1 SIGSEGV on ill-formed TFTP ERROR reply lacking the messa...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: High critical (vote)
Assignee: Tobias Klausmann (RETIRED)
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 323883
  Show dependency tree
 
Reported: 2009-02-28 17:08 UTC by André Gillibert
Modified: 2011-04-04 09:10 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description André Gillibert 2009-02-28 17:08:55 UTC
When recieving a ill-formed ERROR TFTP packet, with Opcode=05, any ErrorCode, but a zero-length ErrMsg and no zero terminator, which is illegal according to RFC-1350, see page 7, then atftpd (either launched as a standalone daemon or from inetd) crashes with a SIGSEGV in strncpy (as seen by gdb) in GLIBC.
Example of invalid ethernet packet (as sent by the buggy OpenBSD pxeboot):
0000  00 48 54 3d cd 88 00 90  90 70 70 70 08 00 45 00   .HT=.... .ppp..E.
0010  00 20 00 00 00 00 3c 11  f9 d6 c0 a8 01 db c0 a8   . ....<. ........
0020  01 cb 08 06 c9 68 00 0c  a9 68 00 05 00 03 00 00   .....h.. .h......
0030  00 00 00 00 00 00 00 00  00 00 00 00               ........ ....    
Note: The zeroes are a trailer not belonging to the IP packet. The actual IP data ends at 03.
In short, the TFTP packet is:
00 05 00 03
Sample segfault:
segfault at b7dfe000 ip b7e988a0 sp b7dfc900 error 7 in libc-2.5.s [b7e2e000+123000]


Reproducible: Always

Steps to Reproduce:
1. atftpd --daemon --no-fork
2. Launch OpenBSD 4.2 pxeboot.

Actual Results:  
OpenBSD pxeboot (that's an OpenBSD bug) sends an ill-formed 00 05 00 03 error packet in reply to data packet #8, and atftpd crashes with a SIGSEGV.

Expected Results:  
atftpd should ignore the ill-formed packet.

The invalid packet is recieved and returned by tftp_get_packet to tftpd_send_file (in tftpd_file.c).
Its size is 4, the opcode is 05 and tftpd_get_packet returns GET_ERROR.
There's a switch case in tftpd_send_file, and it copies the RFC-1350 error message with Strncpy, at line 905.
                    Strncpy(string, tftphdr->th_msg,
                            (((data_size - 4) > MAXLEN) ? MAXLEN :
                             (data_size - 4)));
data_size is 4, and so, 0 is passed as size to Strncpy.
Strncpy is defined in tftp_def.c.
It assumes that size>=1 by 
to[size-1] = '\000';
return strncpy(to, from, size - 1);

But, size-1 is converted to size_t 0xFFFFFFFF when passed to strncpy, which crashes with a SIGSEGV soon or later.

Quick fix:
Add:
if (size <= 0) {*to=0;return to;}
As the first line of Strncpy in tftp_def.c
It assumes that the destination buffer is at least one byte sized, but I'm pretty sure the buffer is always MAXLEN sized, so, it should be ok.

Scope:
This bug isn't specific to Gentoo.
It is found in Debian binaries and sources (AFAIK, Debian is the main maintainer of this package) atftp_0.7.dfsg.orig.tar.gz + atftp_0.7.dfsg-6.diff.gz.

Patch:
$ diff -c tftp_def.old.c tftp_def.c
*** tftp_def.old.c      2009-02-28 17:56:12.000000000 +0100
--- tftp_def.c  2009-02-28 17:57:02.000000000 +0100
***************
*** 141,146 ****
--- 141,147 ----
   */
  inline char *Strncpy(char *to, const char *from, size_t size)
  {
+      if (size <= 0) { *to = '\000'; return to; }
       to[size-1] = '\000';
       return strncpy(to, from, size - 1);
  }
Comment 1 Tobias Klausmann (RETIRED) gentoo-dev 2011-04-04 09:10:55 UTC
The fix has been integrated into net-ftp/atftp-0.7-r2