tags -1 = patch bye
Hello, just tried to reproduce the issue. With the help of the message #42 and the debug symbols in Stretch and later in a Debian Stretch i386 VM I could reproduce the issue. I think it all boils down to: (gdb) bt #0 get_port_fmt (ip=16777343, port=44081) at utils.c:81 #1 0x00407ebb in ftp_do_port (self=0x41c4a8) at ftplib.c:1003 #2 0x00408839 in ftp_establish_data_connection (self=0x41c4a8) at ftplib.c:892 #3 0x004088ac in ftp_get_list (self=0x41c4a8) at ftplib.c:667 #4 0x00408a4c in ftp_get_modification_time (self=0x41c4a8, filename=0x41c630 "test", timestamp=0x41bfd8) at ftplib.c:455 #5 0x00404885 in check_timestamp (fsession=0x41bfa8) at ftp.c:183 #6 0x00405c34 in fsession_process_file (fsession=0x41bfa8, ftp=0x0) at ftp.c:758 #7 0x0040d6be in queue_process (force=0) at queue.c:191 #8 0x00401aaa in main (argc=<optimized out>, argv=<optimized out>) at wput.c:195 (gdb) list get_port_fmt 74 75 char * get_port_fmt(int ip, unsigned int port) { 76 unsigned char b[6]; 77 static char buf[6 * 4]; 78 /* TODO USS have we got an endian problem here for the ip-address */ 79 * (int *) b = ip; 80 *(unsigned int *)(b+4) = htons(port); 81 sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); 82 return buf; 83 } 84 In line 80 the pointer is casted to an unsigned int - and therefore the compiler does exactly that: assign 4 bytes to b+4. Unfortunately at b+4 are just 2 bytes left, then the stack smashing detection bytes get overwritten. Attached are some more informations on the debugging and also a proposal patch to fix the issue. Kind regards, Bernhard
apt install gdb valgrind dpkg-dev devscripts wput git wget http://snapshot.debian.org/archive/debian/20161213T032715Z/pool/main/w/wput/wput_0.6.2%2Bgit20130413-4_i386.deb wget http://snapshot.debian.org/archive/debian-debug/20161213T030732Z/pool/main/w/wput/wput-dbgsym_0.6.2%2Bgit20130413-4_i386.deb dpkg -i *.deb root@debian:~# gdb -q --args wput Reading symbols from wput...Reading symbols from /usr/lib/debug/.build-id/13/1faf5687cad19d44a14f410f72cbebc237c9ff.debug...done. done. (gdb) set pagination off (gdb) b main Breakpoint 1 at 0x17e0: file wput.c, line 73. (gdb) run Starting program: /usr/bin/wput Breakpoint 1, main (argc=1, argv=0xbffff774) at wput.c:73 73 wput.c: Datei oder Verzeichnis nicht gefunden. ############# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=733304#42 *** stack smashing detected ***: wput terminated ======= Backtrace: ========= /lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x6c773)[0xb758a773] /lib/i386-linux-gnu/i686/cmov/libc.so.6(__fortify_fail+0x45)[0xb761a9b5] /lib/i386-linux-gnu/i686/cmov/libc.so.6(+0xfc96a)[0xb761a96a] wput(+0xf6c4)[0xb77066c4] wput(+0x906b)[0xb770006b] wput(+0x7ebb)[0xb76feebb] wput(+0x8869)[0xb76ff869] wput(+0x88ac)[0xb76ff8ac] wput(+0x8a4c)[0xb76ffa4c] wput(+0x4885)[0xb76fb885] wput(+0x5c34)[0xb76fcc34] wput(+0xd6be)[0xb77046be] wput(main+0x2ca)[0xb76f8aaa] /lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf3)[0xb7537a63] wput(+0x2017)[0xb76f9017] ======= Memory map: ======== ############## wget http://snapshot.debian.org/archive/debian/20161213T032715Z/pool/main/w/wput/wput_0.6.2%2Bgit20130413-4_i386.deb wget http://snapshot.debian.org/archive/debian-debug/20161213T030732Z/pool/main/w/wput/wput-dbgsym_0.6.2%2Bgit20130413-4_i386.deb dpkg -i *.deb gdb -q --args wput main+0x2ca: 0x00401aa5 <+709>: call 0x40d600 <queue_process> 0x00401aaa <+714>: mov -0x1c(%ebp),%edx 0xb77046be: 0x0040d6b9 <+185>: call 0x4058a0 <fsession_process_file> 0x0040d6be <+190>: add $0x10,%esp 0xb76fcc34: 0x00405c2f <+911>: call 0x404860 <check_timestamp> 0x00405c34 <+916>: add $0x10,%esp 0xb76fb885: 0x00404880 <+32>: call 0x408950 <ftp_get_modification_time> 0x00404885 <+37>: lea 0x9(%eax),%edx 0xb76ffa4c: 0x00408a47 <+247>: call 0x408880 <ftp_get_list> 0x00408a4c <+252>: lea 0x9(%eax),%edx 0xb76ff8ac: 0x004088a7 <ftp_get_list+39>: call 0x4087e0 <ftp_establish_data_connection> 0x004088ac <ftp_get_list+44>: add $0x10,%esp 0xb76ff869: 0x00408864 <+132>: call 0x407de0 <ftp_do_port> 0x00408869 <+137>: add $0x10,%esp 0xb76feebb: 0x00407eb6 <+214>: call 0x408fe0 <get_port_fmt> 0x00407ebb <+219>: add $0xc,%esp 0xb770006b: 0x00408ff4 <get_port_fmt+20>: mov %gs:0x14,%eax 0x00408ffa <get_port_fmt+26>: mov %eax,0x14(%esp) ... 0x00409051 <get_port_fmt+113>: mov 0xc(%esp),%ecx 0x00409055 <get_port_fmt+117>: xor %gs:0x14,%ecx 0x0040905c <get_port_fmt+124>: jne 0x409066 <get_port_fmt+134> 0x0040905e <get_port_fmt+126>: add $0x14,%esp 0x00409061 <get_port_fmt+129>: mov %esi,%eax 0x00409063 <get_port_fmt+131>: pop %ebx 0x00409064 <get_port_fmt+132>: pop %esi 0x00409065 <get_port_fmt+133>: ret 0x00409066 <get_port_fmt+134>: call 0x40f6b0 <__stack_chk_fail_local> 0xb77066c4: 0x0040f6bf <__stack_chk_fail_local+15>: call 0x401588 0x0040f6c4 <_fini+0>: push %ebx ############# char * get_port_fmt(int ip, unsigned int port) { unsigned char b[6]; static char buf[6 * 4]; /* TODO USS have we got an endian problem here for the ip-address */ * (int *) b = ip; *(unsigned int *)(b+4) = htons(port); sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); return buf; } ############# https://linux.die.net/man/3/htons uint16_t htons(uint16_t hostshort); ############# (gdb) disassemble /m get_port_fmt Dump of assembler code for function get_port_fmt: 75 char * get_port_fmt(int ip, unsigned int port) { 0x00008fe0 <+0>: push %esi 0x00008fe1 <+1>: push %ebx 0x00008fe2 <+2>: call 0x2020 <__x86.get_pc_thunk.bx> 0x00008fe7 <+7>: add $0x10e49,%ebx 0x00008fed <+13>: sub $0x1c,%esp 0x00008ff0 <+16>: mov 0x28(%esp),%edx 0x00008ff4 <+20>: mov %gs:0x14,%eax 0x00008ffa <+26>: mov %eax,0x14(%esp) 0x00008ffe <+30>: xor %eax,%eax 76 unsigned char b[6]; 77 static char buf[6 * 4]; 78 /* TODO USS have we got an endian problem here for the ip-address */ 79 * (int *) b = ip; 0x00009000 <+32>: mov %edx,%eax 0x00009002 <+34>: mov %edx,0xe(%esp) 0x00009006 <+38>: shr $0x10,%eax 0x00009009 <+41>: mov %eax,%ecx 80 *(unsigned int *)(b+4) = htons(port); 0x0000900b <+43>: movzwl 0x2c(%esp),%eax 0x00009010 <+48>: ror $0x8,%ax 0x00009014 <+52>: movzwl %ax,%eax 0x00009019 <+57>: mov %eax,0x12(%esp) 81 sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); 0x00009017 <+55>: mov %eax,%esi 0x0000901d <+61>: movzbl %al,%eax 0x00009020 <+64>: shr $0x8,%esi 0x00009025 <+69>: mov %edx,%eax 0x00009027 <+71>: shr $0x18,%eax 0x00009031 <+81>: movzbl %cl,%eax 0x00009035 <+85>: movzbl %dh,%eax 0x00009038 <+88>: movzbl %dl,%edx 82 return buf; 0x0000904e <+110>: add $0x30,%esp 83 } 0x00009051 <+113>: mov 0xc(%esp),%ecx 0x00009055 <+117>: xor %gs:0x14,%ecx 0x0000905c <+124>: jne 0x9066 <get_port_fmt+134> 0x0000905e <+126>: add $0x14,%esp 0x00009061 <+129>: mov %esi,%eax 0x00009063 <+131>: pop %ebx 0x00009064 <+132>: pop %esi 0x00009065 <+133>: ret 0x00009066 <+134>: call 0xf6b0 <__stack_chk_fail_local> 0x0000906b: nop 0x0000906c: lea 0x0(%esi,%eiz,1),%esi End of assembler dump. ####### apt install vsftpd ftp /etc/vsftpd.conf:write_enable=YES systemctl restart vsftpd root@debian:/home/benutzer/x# echo test > test root@debian:/home/benutzer/x# gdb -q --args wput -p -a wput-daily.log -B --timestamping --reupload --dont-continue test ftp://benutzer:xxxxx@localhost/ Reading symbols from wput...Reading symbols from /usr/lib/debug/.build-id/13/1faf5687cad19d44a14f410f72cbebc237c9ff.debug...done. done. (gdb) cont The program is not being run. (gdb) run Starting program: /usr/bin/wput -p -a wput-daily.log -B --timestamping --reupload --dont-continue test ftp://benutzer:xxxxx@localhost/ *** stack smashing detected ***: /usr/bin/wput terminated ======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x6738a)[0xb7e7e38a] /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x37)[0xb7f0eec7] /lib/i386-linux-gnu/libc.so.6(+0xf7e88)[0xb7f0ee88] /usr/bin/wput(+0xf6c4)[0x40f6c4] /usr/bin/wput(+0x906b)[0x40906b] /usr/bin/wput(+0x7ebb)[0x407ebb] /usr/bin/wput(+0x8839)[0x408839] /usr/bin/wput(+0x88ac)[0x4088ac] /usr/bin/wput(+0x8a4c)[0x408a4c] /usr/bin/wput(+0x4885)[0x404885] /usr/bin/wput(+0x5c34)[0x405c34] /usr/bin/wput(+0xd6be)[0x40d6be] /usr/bin/wput(main+0x2ca)[0x401aaa] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf6)[0xb7e2f286] /usr/bin/wput(+0x2017)[0x402017] ======= Memory map: ======== 00400000-00419000 r-xp 00000000 08:01 280451 /usr/bin/wput 00419000-0041a000 r--p 00018000 08:01 280451 /usr/bin/wput 0041a000-0041b000 rw-p 00019000 08:01 280451 /usr/bin/wput 0041b000-0043c000 rw-p 00000000 00:00 0 [heap] b7c18000-b7c34000 r-xp 00000000 08:01 131259 /lib/i386-linux-gnu/libgcc_s.so.1 b7c34000-b7c35000 r--p 0001b000 08:01 131259 /lib/i386-linux-gnu/libgcc_s.so.1 b7c35000-b7c36000 rw-p 0001c000 08:01 131259 /lib/i386-linux-gnu/libgcc_s.so.1 b7c36000-b7c5c000 r--p 00000000 08:01 264870 /usr/share/locale/de/LC_MESSAGES/libc.mo b7c5c000-b7c67000 r-xp 00000000 08:01 131283 /lib/i386-linux-gnu/libnss_files-2.24.so b7c67000-b7c68000 r--p 0000a000 08:01 131283 /lib/i386-linux-gnu/libnss_files-2.24.so b7c68000-b7c69000 rw-p 0000b000 08:01 131283 /lib/i386-linux-gnu/libnss_files-2.24.so b7c69000-b7c6f000 rw-p 00000000 00:00 0 b7c75000-b7c7c000 r--s 00000000 08:01 270023 /usr/lib/i386-linux-gnu/gconv/gconv-modules.cache b7c7c000-b7e17000 r--p 00000000 08:01 266752 /usr/lib/locale/locale-archive b7e17000-b7fc8000 r-xp 00000000 08:01 131271 /lib/i386-linux-gnu/libc-2.24.so b7fc8000-b7fca000 r--p 001b0000 08:01 131271 /lib/i386-linux-gnu/libc-2.24.so b7fca000-b7fcb000 rw-p 001b2000 08:01 131271 /lib/i386-linux-gnu/libc-2.24.so b7fcb000-b7fce000 rw-p 00000000 00:00 0 b7fce000-b7fcf000 rw-p 00000000 00:00 0 b7fcf000-b7fd4000 r--p 00000000 08:01 280454 /usr/share/locale/de/LC_MESSAGES/wput.mo b7fd4000-b7fd7000 rw-p 00000000 00:00 0 b7fd7000-b7fd9000 r--p 00000000 00:00 0 [vvar] b7fd9000-b7fdb000 r-xp 00000000 00:00 0 [vdso] b7fdb000-b7ffe000 r-xp 00000000 08:01 131261 /lib/i386-linux-gnu/ld-2.24.so b7ffe000-b7fff000 r--p 00022000 08:01 131261 /lib/i386-linux-gnu/ld-2.24.so b7fff000-b8000000 rw-p 00023000 08:01 131261 /lib/i386-linux-gnu/ld-2.24.so bffdf000-c0000000 rw-p 00000000 00:00 0 [stack] Program received signal SIGABRT, Aborted. 0xb7fd9cf9 in __kernel_vsyscall () (gdb) bt #0 0xb7fd9cf9 in __kernel_vsyscall () #1 0xb7e42dd0 in __libc_signal_restore_set (set=0xbffff050) at ../sysdeps/unix/sysv/linux/nptl-signals.h:79 #2 __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:48 #3 0xb7e44297 in __GI_abort () at abort.c:89 #4 0xb7e7e38f in __libc_message (do_abort=<optimized out>, fmt=<optimized out>) at ../sysdeps/posix/libc_fatal.c:175 #5 0xb7f0eec7 in __GI___fortify_fail (msg=0xb7f7663b "stack smashing detected") at fortify_fail.c:30 #6 0xb7f0ee88 in __stack_chk_fail () at stack_chk_fail.c:28 #7 0x0040f6c4 in __stack_chk_fail_local () #8 0x0040906b in get_port_fmt (ip=16777343, port=47865) at utils.c:83 #9 0x00407ebb in ftp_do_port (self=0x41c4a8) at ftplib.c:1003 #10 0x00408839 in ftp_establish_data_connection (self=0x41c4a8) at ftplib.c:892 #11 0x004088ac in ftp_get_list (self=0x41c4a8) at ftplib.c:667 #12 0x00408a4c in ftp_get_modification_time (self=0x41c4a8, filename=0x41c630 "test", timestamp=0x41bfd8) at ftplib.c:455 #13 0x00404885 in check_timestamp (fsession=0x41bfa8) at ftp.c:183 #14 0x00405c34 in fsession_process_file (fsession=0x41bfa8, ftp=0x0) at ftp.c:758 #15 0x0040d6be in queue_process (force=0) at queue.c:191 #16 0x00401aaa in main (argc=<optimized out>, argv=<optimized out>) at wput.c:195 root@debian:/home/benutzer/x# gdb -q --args wput -p -a wput-daily.log -B --timestamping --reupload --dont-continue test ftp://benutzer:xxxx@localhost/ Reading symbols from wput...Reading symbols from /usr/lib/debug/.build-id/13/1faf5687cad19d44a14f410f72cbebc237c9ff.debug...done. done. (gdb) directory /home/benutzer/wput/wput-0.6.2+git20130413/src Source directories searched: /home/benutzer/wput/wput-0.6.2+git20130413/src:$cdir:$cwd (gdb) b get_port_fmt Breakpoint 1 at 0x8fe0: file utils.c, line 75. (gdb) run Starting program: /usr/bin/wput -p -a wput-daily.log -B --timestamping --reupload --dont-continue test ftp://benutzer:xxxx@localhost/ Breakpoint 1, get_port_fmt (ip=16777343, port=44081) at utils.c:75 75 char * get_port_fmt(int ip, unsigned int port) { (gdb) display/i $pc 1: x/i $pc => 0x408fe0 <get_port_fmt>: push %esi (gdb) nexti 0x00408fe1 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408fe1 <get_port_fmt+1>: push %ebx (gdb) 0x00408fe2 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408fe2 <get_port_fmt+2>: call 0x402020 <__x86.get_pc_thunk.bx> (gdb) 0x00408fe7 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408fe7 <get_port_fmt+7>: add $0x10e49,%ebx (gdb) 0x00408fed 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408fed <get_port_fmt+13>: sub $0x1c,%esp (gdb) 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408ff0 <get_port_fmt+16>: mov 0x28(%esp),%edx (gdb) 0x00408ff4 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408ff4 <get_port_fmt+20>: mov %gs:0x14,%eax (gdb) 0x00408ffa 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408ffa <get_port_fmt+26>: mov %eax,0x14(%esp) (gdb) 0x00408ffe 75 char * get_port_fmt(int ip, unsigned int port) { 1: x/i $pc => 0x408ffe <get_port_fmt+30>: xor %eax,%eax (gdb) print/x $esp+0x14 $1 = 0xbffff42c (gdb) watch *0xbffff42c Hardware watchpoint 2: *0xbffff42c (gdb) nexti 79 * (int *) b = ip; 1: x/i $pc => 0x409000 <get_port_fmt+32>: mov %edx,%eax (gdb) 0x00409002 79 * (int *) b = ip; 1: x/i $pc => 0x409002 <get_port_fmt+34>: mov %edx,0xe(%esp) (gdb) 0x00409006 79 * (int *) b = ip; 1: x/i $pc => 0x409006 <get_port_fmt+38>: shr $0x10,%eax (gdb) 0x00409009 79 * (int *) b = ip; 1: x/i $pc => 0x409009 <get_port_fmt+41>: mov %eax,%ecx (gdb) 80 *(unsigned int *)(b+4) = htons(port); 1: x/i $pc => 0x40900b <get_port_fmt+43>: movzwl 0x2c(%esp),%eax (gdb) 0x00409010 80 *(unsigned int *)(b+4) = htons(port); 1: x/i $pc => 0x409010 <get_port_fmt+48>: ror $0x8,%ax (gdb) 0x00409014 80 *(unsigned int *)(b+4) = htons(port); 1: x/i $pc => 0x409014 <get_port_fmt+52>: movzwl %ax,%eax (gdb) 81 sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); 1: x/i $pc => 0x409017 <get_port_fmt+55>: mov %eax,%esi (gdb) 80 *(unsigned int *)(b+4) = htons(port); 1: x/i $pc => 0x409019 <get_port_fmt+57>: mov %eax,0x12(%esp) (gdb) Hardware watchpoint 2: *0xbffff42c Old value = -273736704 New value = -273743872 get_port_fmt (ip=16777343, port=44081) at utils.c:81 81 sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); 1: x/i $pc => 0x40901d <get_port_fmt+61>: movzbl %al,%eax (gdb) print (b+4) $2 = (unsigned char *) 0xbffff42a "\254\061" (gdb) print/x $esp+0x12 $5 = 0xbffff42a (gdb) bt #0 get_port_fmt (ip=16777343, port=44081) at utils.c:81 #1 0x00407ebb in ftp_do_port (self=0x41c4a8) at ftplib.c:1003 #2 0x00408839 in ftp_establish_data_connection (self=0x41c4a8) at ftplib.c:892 #3 0x004088ac in ftp_get_list (self=0x41c4a8) at ftplib.c:667 #4 0x00408a4c in ftp_get_modification_time (self=0x41c4a8, filename=0x41c630 "test", timestamp=0x41bfd8) at ftplib.c:455 #5 0x00404885 in check_timestamp (fsession=0x41bfa8) at ftp.c:183 #6 0x00405c34 in fsession_process_file (fsession=0x41bfa8, ftp=0x0) at ftp.c:758 #7 0x0040d6be in queue_process (force=0) at queue.c:191 #8 0x00401aaa in main (argc=<optimized out>, argv=<optimized out>) at wput.c:195 (gdb)
Description: Avoid stack smashing in get_port_fmt Author: Bernhard Ãbelacker <bernha...@mailbox.org> Bug-Debian: https://bugs.debian.org/733304 Last-Update: 2018-07-30 --- wput-0.6.2+git20130413.orig/src/utils.c +++ wput-0.6.2+git20130413/src/utils.c @@ -77,7 +77,7 @@ char * get_port_fmt(int ip, unsigned int static char buf[6 * 4]; /* TODO USS have we got an endian problem here for the ip-address */ * (int *) b = ip; - *(unsigned int *)(b+4) = htons(port); + *(uint16_t *)(b+4) = htons(port); sprintf(buf, "%d,%d,%d,%d,%d,%d", b[0], b[1], b[2], b[3], b[4], b[5]); return buf; }