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;        
 }

Reply via email to