Hello,
I guess #921959 describes also the same problem.

Attached patch tries to workaround that issue by not
using the the original buf pointer increased by the
offset of member th_msg.

That way at least the warning "overflows the destination"
is not written anymore at build time and a package built
with it could deliver the error message to the client.

The disassembly shows still a call to __strcpy_chk,
but now with "mov    $0x200,%edx" instead of a
"xor    %edx,%edx" like before.

Kind regards,
Bernhard


# Buster/stable amd64 qemu VM 2019-08-26


apt update
apt dist-upgrade


apt install systemd-coredump mc psmisc net-tools strace gdb tftp tftpd 
tftpd-dbgsym
apt build-dep tftpd





mkdir /home/benutzer/source/tftpd/orig -p
cd    /home/benutzer/source/tftpd/orig
apt source tftpd
cd




# tftp localhost  --> does not trigger a crash

tftp 10.0.2.15
get test


###########


benutzer@debian:~$ tftp localhost
tftp> get test
Transfer timed out.

tftp> 


# nothing in 'coredumpctl list' or 'dmesg'


###########


enutzer@debian:~$ tftp 10.0.2.15
tftp> get test
Transfer timed out.

tftp> 


root@debian:~# coredumpctl list
TIME                            PID   UID   GID SIG COREFILE  EXE
...
Mon 2019-08-26 22:53:56 CEST   2558 65534 65534   6 present   /usr/sbin/in.tftpd


root@debian:~# coredumpctl gdb 2558
           PID: 2558 (in.tftpd)
           UID: 65534 (nobody)
           GID: 65534 (nogroup)
        Signal: 6 (ABRT)
     Timestamp: Mon 2019-08-26 22:53:56 CEST (5min ago)
  Command Line: in.tftpd /srv/tftp
    Executable: /usr/sbin/in.tftpd
 Control Group: /system.slice/inetd.service
          Unit: inetd.service
         Slice: system.slice
       Boot ID: 90010229fa5c4bad91f686460281c7bd
    Machine ID: 33f18f39d2a9438eb75b0ed52848afcd
      Hostname: debian
       Storage: 
/var/lib/systemd/coredump/core.in\x2etftpd.65534.90010229fa5c4bad91f686460281c7bd.2558.1566852836000000.lz4
       Message: Process 2558 (in.tftpd) of user 65534 dumped core.
                
                Stack trace of thread 2558:
                #0  0x00007f1c5997a7bb __GI_raise (libc.so.6)
                #1  0x00007f1c59965535 __GI_abort (libc.so.6)
                #2  0x00007f1c599bc508 __libc_message (libc.so.6)
                #3  0x00007f1c59a4d80d __GI___fortify_fail_abort (libc.so.6)
                #4  0x00007f1c59a4d841 __GI___fortify_fail (libc.so.6)
                #5  0x00007f1c59a4b940 __GI___chk_fail (libc.so.6)
                #6  0x00007f1c59a4ad52 __strcpy_chk (libc.so.6)
                #7  0x0000558db2f4b94f strcpy (in.tftpd)
                #8  0x0000558db2f4b7a2 tftp (in.tftpd)
                #9  0x00007f1c5996709b __libc_start_main (libc.so.6)
                #10 0x0000558db2f4b7fa _start (in.tftpd)

GNU gdb (Debian 8.2.1-2) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/sbin/in.tftpd...Reading symbols from 
/usr/lib/debug/.build-id/71/ec94654597b3b11d2d01a17ce776065786a694.debug...done.
done.
[New LWP 2558]
Core was generated by `in.tftpd /srv/tftp'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht 
gefunden.
(gdb) set width 0
(gdb) set pagination off
(gdb) directory /home/benutzer/source/tftpd/orig/netkit-tftp-0.17
Source directories searched: 
/home/benutzer/source/tftpd/orig/netkit-tftp-0.17:$cdir:$cwd
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007f1c59965535 in __GI_abort () at abort.c:79
#2  0x00007f1c599bc508 in __libc_message (action=<optimized out>, 
fmt=fmt@entry=0x7f1c59ac707b "*** %s ***: %s terminated\n") at 
../sysdeps/posix/libc_fatal.c:181
#3  0x00007f1c59a4d80d in __GI___fortify_fail_abort 
(need_backtrace=need_backtrace@entry=true, msg=msg@entry=0x7f1c59ac6ff8 "buffer 
overflow detected") at fortify_fail.c:28
#4  0x00007f1c59a4d841 in __GI___fortify_fail (msg=msg@entry=0x7f1c59ac6ff8 
"buffer overflow detected") at fortify_fail.c:44
#5  0x00007f1c59a4b940 in __GI___chk_fail () at chk_fail.c:28
#6  0x00007f1c59a4ad52 in __strcpy_chk (dest=0x558db2f4f724 <buf+4> "st", 
src=0x558db2f4d0f8 "Access violation", destlen=0) at strcpy_chk.c:30
#7  0x0000558db2f4b94f in strcpy (__src=<optimized out>, __dest=0x558db2f4f724 
<buf+4> "st") at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:90
#8  nak (error=<optimized out>) at ./tftpd/tftpd.c:624
#9  0x0000558db2f4b7a2 in tftp (tp=<optimized out>, size=<optimized out>) at 
./tftpd/tftpd.c:317
#10 main (ac=<optimized out>, av=<optimized out>) at ./tftpd/tftpd.c:255






set width 0
set pagination off
directory /home/benutzer/source/tftpd/orig/netkit-tftp-0.17





#########

gdb -q --pid $(pidof /usr/sbin/inetd) \
    -ex 'set width 0' \
    -ex 'set pagination off' \
    -ex 'set follow-fork-mode child' \
    -ex 'set follow-exec-mode child' \
    -ex 'b writev' \
    -ex cont
Description: Workaround FORTIFY_SOURCE in struct tftphdr

Bug-Debian: https://bugs.debian.org/935826
Bug-Debian: https://bugs.debian.org/931848
Bug-Debian: https://bugs.debian.org/921959
Last-Update: 2019-08-26

--- netkit-tftp-0.17.orig/tftp/tftp.c
+++ netkit-tftp-0.17/tftp/tftp.c
@@ -373,7 +373,7 @@ nak(int error)
 		pe->e_msg = strerror(error - 100);
 		tp->th_code = EUNDEF;
 	}
-	strcpy(tp->th_msg, pe->e_msg);
+	strcpy(ackbuf + ((char*)tp->th_msg - (char*)tp), pe->e_msg);
 	length = strlen(pe->e_msg) + 4;
 	if (trace)
 		tpacket("sent", tp, length);
--- netkit-tftp-0.17.orig/tftpd/tftpd.c
+++ netkit-tftp-0.17/tftpd/tftpd.c
@@ -621,7 +621,7 @@ nak(int error)
 		pe->e_msg = strerror(error - 100);
 		tp->th_code = EUNDEF;   /* set 'undef' errorcode */
 	}
-	strcpy(tp->th_msg, pe->e_msg);
+	strcpy(buf + ((char*)&tp->th_msg - (char*)tp), pe->e_msg);
 	length = strlen(pe->e_msg);
 	tp->th_msg[length] = '\0';
 	length += 5;

Reply via email to