Hello,
tried to reproduce this issue.

The exact location where the stack smashing detector bytes get overwritten is 
below.

Looks like an upstream bug where the size of
the out parameter ("decoded" variable) is not respected.

Kind regards,
Bernhard






(gdb) cont
Continuing.

Watchpoint 4: *0xbfffdbac

Old value = -1150217040
New value = -1150164048
decode_streamname (in=0x425350 '〰' <repeats 24 times>, out=0xbfffdb6e '〰' 
<repeats 21 times>, "\343q\273\b") at table.c:218
218     in table.c
1: x/i $pc
=> 0xb7fb4c29 <decode_streamname+105>:  movzbl 0x1(%eax),%ecx
(gdb) bt
#0  decode_streamname (in=0x425350 '〰' <repeats 24 times>, out=0xbfffdb6e '〰' 
<repeats 21 times>, "\343q\273\b") at table.c:218
#1  0xb7fb1472 in create_stream (sv=sv@entry=0x4258a0, name=name@entry=0x425350 
'〰' <repeats 24 times>, encoded=encoded@entry=true, stm=0x414ab8) at 
streams.c:73
#2  0xb7fb17af in add_stream_to_table (name=0x425350 '〰' <repeats 24 times>, 
stm=0x414ab8, opaque=0x4258a0) at streams.c:370
#3  0xb7fa6aa1 in msi_enum_db_streams (db=0x415c00, fn=0xb7fb1780 
<add_stream_to_table>, opaque=0x4258a0) at libmsi-database.c:434
#4  0xb7fb1b67 in add_streams_to_table (sv=0x4258a0) at streams.c:391
#5  streams_view_create (db=0x415c00, view=0x425884) at streams.c:407
#6  0xb7fb606c in table_view_create (db=0x415c00, name=<optimized out>, 
view=0x425884) at table.c:1993
#7  0xb7fb9f35 in where_view_create (db=0x415c00, view=0xbfffdd30, 
tables=0x425298 "_Streams", cond=0x425828) at where.c:1125
#8  0xb7fb055a in sql_parse (info=<optimized out>) at sql-parser.y:520
#9  0xb7fb0ba4 in _libmsi_parse_sql (db=0x415c00, command=0x40d7c0 "SELECT 
`Data` FROM `_Streams` WHERE `Name` = ?", phview=0x425e0c, mem=0x425e1c) at 
sql-parser.y:1016
#10 0xb7fab888 in init (error=0xbffff628, self=0x425e00) at libmsi-query.c:141
#11 libmsi_query_new (database=0x415c00, query=0x4030e4 "SELECT `Data` FROM 
`_Streams` WHERE `Name` = ?", error=0xbffff628) at libmsi-query.c:670
#12 0x0040282e in cmd_extract (cmd=0x406068 <cmds+72>, argc=3, argv=0xbffff6f8, 
error=0xbffff628) at tools/msiinfo.c:369
#13 0x00401241 in main (argc=4, argv=0xbffff6f4) at tools/msiinfo.c:770





(gdb) directory /home/benutzer/msitools/msitools-0.97/libmsi
Source directories searched: 
/home/benutzer/msitools/msitools-0.97/libmsi:$cdir:$cwd
(gdb) list
191     void decode_streamname(const char *in, char *out)
192     {
193         unsigned count = 0;
194         const uint8_t *p = (const uint8_t *)in;
195         uint8_t *q = (uint8_t *)out;
196
197         while ( *p )
198         {
199             uint8_t ch = *p;
200             if( (ch == 0xe3 && p[1] >= 0xa0) || (ch == 0xe4 && p[1] < 0xa0) 
)
201             {
202                 /* UTF-8 encoding of 0x3800..0x47ff.  */
203                 *q++ = mime2utf(p[2]&0x7f);
204                 *q++ = mime2utf(p[1]^0xa0);
205                 p += 3;
206                 count += 2;
207                 continue;
208             }
209             if( ch == 0xe4 && p[1] == 0xa0 ) {
210                 /* UTF-8 encoding of 0x4800..0x483f.  */
211                 *q++ = mime2utf(p[2]&0x7f);
212                 p += 3;
213                 count++;
214                 continue;
215             }
216             *q++ = *p++;
217             if( ch >= 0xc1) {
218                 *q++ = *p++;
219             }
220             if( ch >= 0xe0) {
221                 *q++ = *p++;
222             }

(gdb) print out
$3 = 0xbfffdb6e '〰' <repeats 21 times>, "\343q\273\b"



wget 
"https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=871503;filename=overflow.msi.gz;msg=3";
 -O overflow.msi.gz

export PKG="msitools gdb msitools msitools-dbgsym libmsi0-dbgsym dpkg-dev"; apt 
install $PKG; apt-mark auto $PKG


(mkdir msitools; cd msitools; apt source msitools)





root@debian:/home/benutzer# gdb -q --args msiinfo extract overflow.msi Property
Reading symbols from msiinfo...(no debugging symbols found)...done.
(gdb) run
...
*** stack smashing detected ***: <unknown> terminated

Program received signal SIGABRT, Aborted.
0xb7fd5d39 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fd5d39 in __kernel_vsyscall ()
#1  0xb7843112 in __libc_signal_restore_set (set=0xbfffd78c) at 
../sysdeps/unix/sysv/linux/nptl-signals.h:80
#2  __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:48
#3  0xb7844531 in __GI_abort () at abort.c:79
#4  0xb7884e83 in __libc_message (action=do_abort, fmt=<optimized out>) at 
../sysdeps/posix/libc_fatal.c:181
#5  0xb791ddea in __GI___fortify_fail_abort (need_backtrace=false, 
msg=0xb7994093 "stack smashing detected") at fortify_fail.c:33
#6  0xb791dd9b in __stack_chk_fail () at stack_chk_fail.c:29
#7  0xb7fba1d4 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#8  0xb7fb1489 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#9  0xb7fb17af in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#10 0xb7fa6aa1 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#11 0xb7fb1b67 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#12 0xb7fb9f35 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#13 0xb7fb055a in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#14 0xb7fb0ba4 in ?? () from /usr/lib/i386-linux-gnu/libmsi.so.0
#15 0xb7fab888 in libmsi_query_new () from /usr/lib/i386-linux-gnu/libmsi.so.0
#16 0x0040282e in ?? ()
#17 0x00401241 in ?? ()
#18 0xb782e9a1 in __libc_start_main (main=0x4011d0, argc=4, argv=0xbffff724, 
init=0x402b40, fini=0x402ba0, rtld_fini=0xb7fe6f60 <_dl_fini>, 
stack_end=0xbffff71c) at ../csu/libc-start.c:310
#19 0x00401451 in ?? ()







root@debian:/home/benutzer# gdb -q --args msiinfo extract overflow.msi Property
Reading symbols from msiinfo...Reading symbols from 
/usr/lib/debug/.build-id/ad/b7fa83ffaf2b8ae87296f95bdd1ef4c322b093.debug...done.
done.
(gdb) run
...
*** stack smashing detected ***: <unknown> terminated

Program received signal SIGABRT, Aborted.
0xb7fd5d39 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fd5d39 in __kernel_vsyscall ()
#1  0xb7843112 in __libc_signal_restore_set (set=0xbfffd75c) at 
../sysdeps/unix/sysv/linux/nptl-signals.h:80
#2  __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:48
#3  0xb7844531 in __GI_abort () at abort.c:79
#4  0xb7884e83 in __libc_message (action=do_abort, fmt=<optimized out>) at 
../sysdeps/posix/libc_fatal.c:181
#5  0xb791ddea in __GI___fortify_fail_abort (need_backtrace=false, 
msg=0xb7994093 "stack smashing detected") at fortify_fail.c:33
#6  0xb791dd9b in __stack_chk_fail () at stack_chk_fail.c:29
#7  0xb7fba1d4 in __stack_chk_fail_local () from 
/usr/lib/i386-linux-gnu/libmsi.so.0
#8  0xb7fb1489 in create_stream (sv=sv@entry=0x4258a0, name=0xbfffdb6e '〰' 
<repeats 24 times>, name@entry=0x425350 '〰' <repeats 24 times>, 
encoded=encoded@entry=true, stm=0x414ab8) at streams.c:84
#9  0xb7fb17af in add_stream_to_table (name=0x425350 '〰' <repeats 24 times>, 
stm=0x414ab8, opaque=0x4258a0) at streams.c:370
#10 0xb7fa6aa1 in msi_enum_db_streams (db=0x415c00, fn=0xb7fb1780 
<add_stream_to_table>, opaque=0x4258a0) at libmsi-database.c:434
#11 0xb7fb1b67 in add_streams_to_table (sv=0x4258a0) at streams.c:391
#12 streams_view_create (db=0x415c00, view=0x425884) at streams.c:407
#13 0xb7fb606c in table_view_create (db=0x415c00, name=<optimized out>, 
view=0x425884) at table.c:1993
#14 0xb7fb9f35 in where_view_create (db=0x415c00, view=0xbfffdd30, 
tables=0x425298 "_Streams", cond=0x425828) at where.c:1125
#15 0xb7fb055a in sql_parse (info=<optimized out>) at sql-parser.y:520
#16 0xb7fb0ba4 in _libmsi_parse_sql (db=0x415c00, command=0x40d7c0 "SELECT 
`Data` FROM `_Streams` WHERE `Name` = ?", phview=0x425e0c, mem=0x425e1c) at 
sql-parser.y:1016
#17 0xb7fab888 in init (error=0xbffff628, self=0x425e00) at libmsi-query.c:141
#18 libmsi_query_new (database=0x415c00, query=0x4030e4 "SELECT `Data` FROM 
`_Streams` WHERE `Name` = ?", error=0xbffff628) at libmsi-query.c:670
#19 0x0040282e in cmd_extract (cmd=0x406068 <cmds+72>, argc=3, argv=0xbffff6f8, 
error=0xbffff628) at tools/msiinfo.c:369
#20 0x00401241 in main (argc=4, argv=0xbffff6f4) at tools/msiinfo.c:770








How often create_stream gets executed?

root@debian:/home/benutzer# gdb -q --args msiinfo extract overflow.msi Property
Reading symbols from msiinfo...Reading symbols from 
/usr/lib/debug/.build-id/ad/b7fa83ffaf2b8ae87296f95bdd1ef4c322b093.debug...done.
done.
(gdb) b create_stream
Function "create_stream" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (create_stream) pending.
(gdb) ignore 1 100000
Will ignore next 100000 crossings of breakpoint 1.
(gdb) run
...
*** stack smashing detected ***: <unknown> terminated

Program received signal SIGABRT, Aborted.
0xb7fd5d39 in __kernel_vsyscall ()
(gdb) info bt
Undefined info command: "bt".  Try "help info".
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0xb7fb13c0 in create_stream at streams.c:63
        breakpoint already hit 4 times
        ignore next 99996 hits
.










Stopp at the 4th exection, record and continue until __stack_chk_fail:

(gdb) ignore 1 3
Will ignore next 3 crossings of breakpoint 1.
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) run
...
Breakpoint 1, create_stream (sv=sv@entry=0x4258a0, name=name@entry=0x425350 '〰' 
<repeats 24 times>, encoded=encoded@entry=true, stm=0x414ab8) at streams.c:63
63      streams.c: Datei oder Verzeichnis nicht gefunden.
(gdb) b __stack_chk_fail
Breakpoint 2 at 0xb791dd80: file stack_chk_fail.c, line 28.
(gdb) record
(gdb) cont










Continuing.

Breakpoint 2, __stack_chk_fail () at stack_chk_fail.c:28
28      stack_chk_fail.c: Datei oder Verzeichnis nicht gefunden.
(gdb) display/i $pc
1: x/i $pc
=> 0xb791dd80 <__stack_chk_fail>:       call   0xb794aba9 
<__x86.get_pc_thunk.ax>
(gdb) reverse-nexti
0xb7fba1cf in __stack_chk_fail_local () from /usr/lib/i386-linux-gnu/libmsi.so.0
1: x/i $pc
=> 0xb7fba1cf <__stack_chk_fail_local+15>:      call   0xb7fa3520 
<__stack_chk_fail@plt>
(gdb) 
0xb7fba1cc in __stack_chk_fail_local () from /usr/lib/i386-linux-gnu/libmsi.so.0
1: x/i $pc
=> 0xb7fba1cc <__stack_chk_fail_local+12>:      sub    $0x8,%esp
(gdb) 
0xb7fba1c6 in __stack_chk_fail_local () from /usr/lib/i386-linux-gnu/libmsi.so.0
1: x/i $pc
=> 0xb7fba1c6 <__stack_chk_fail_local+6>:       add    $0xfbc2,%ebx
(gdb) 
0xb7fba1c1 in __stack_chk_fail_local () from /usr/lib/i386-linux-gnu/libmsi.so.0
1: x/i $pc
=> 0xb7fba1c1 <__stack_chk_fail_local+1>:       call   0xb7fa37b0 
<__x86.get_pc_thunk.bx>
(gdb) 
0xb7fba1c0 in __stack_chk_fail_local () from /usr/lib/i386-linux-gnu/libmsi.so.0
1: x/i $pc
=> 0xb7fba1c0 <__stack_chk_fail_local>: push   %ebx
(gdb) 
create_stream (sv=sv@entry=0x4258a0, name=0xbfffdb6e '〰' <repeats 24 times>, 
name@entry=0x425350 '〰' <repeats 24 times>, encoded=encoded@entry=true, 
stm=0x414ab8) at streams.c:84
84      streams.c: Datei oder Verzeichnis nicht gefunden.
1: x/i $pc
=> 0xb7fb1484 <create_stream+196>:      call   0xb7fba1c0 
<__stack_chk_fail_local>
(gdb) 
0xb7fb1453      84      in streams.c
1: x/i $pc
=> 0xb7fb1453 <create_stream+147>:      jne    0xb7fb1484 <create_stream+196>
(gdb) 
0xb7fb1451      84      in streams.c
1: x/i $pc
=> 0xb7fb1451 <create_stream+145>:      mov    %edi,%eax
(gdb) 
0xb7fb144a      84      in streams.c
1: x/i $pc
=> 0xb7fb144a <create_stream+138>:      xor    %gs:0x14,%edx
(gdb) 
84      in streams.c
1: x/i $pc
=> 0xb7fb1446 <create_stream+134>:      mov    0x5c(%esp),%edx







The stack smashing detector bytes are located at 0x5c(%esp):

(gdb) print/x $esp+0x5c
$2 = 0xbfffdbac






Continue back to start of create_stream function:

(gdb) reverse-cont
Continuing.

No more reverse-execution history.
create_stream (sv=sv@entry=0x4258a0, name=name@entry=0x425350 '〰' <repeats 24 
times>, encoded=encoded@entry=true, stm=0x414ab8) at streams.c:63
63      in streams.c
1: x/i $pc
=> 0xb7fb13c0 <create_stream>:  push   %ebp








Stop at every change of the stack smashing detector bytes:

(gdb) set can-use-hw-watchpoints 0
(gdb) watch *0xbfffdbac
Watchpoint 4: *0xbfffdbac

(gdb) cont
Continuing.

Watchpoint 4: *0xbfffdbac

Old value = -1150217216
New value = -1150217040
0xb7fb4c40 in decode_streamname (in=0x425350 '〰' <repeats 24 times>, 
out=0xbfffdb6e '〰' <repeats 21 times>, "\024q\273\b") at table.c:221
221     table.c: Datei oder Verzeichnis nicht gefunden.
1: x/i $pc
=> 0xb7fb4c40 <decode_streamname+128>:  mov    (%esp),%eax

-> This is the initialization






(gdb) cont
Continuing.

Watchpoint 4: *0xbfffdbac

Old value = -1150217040
New value = -1150164048
decode_streamname (in=0x425350 '〰' <repeats 24 times>, out=0xbfffdb6e '〰' 
<repeats 21 times>, "\343q\273\b") at table.c:218
218     in table.c
1: x/i $pc
=> 0xb7fb4c29 <decode_streamname+105>:  movzbl 0x1(%eax),%ecx
(gdb) bt
#0  decode_streamname (in=0x425350 '〰' <repeats 24 times>, out=0xbfffdb6e '〰' 
<repeats 21 times>, "\343q\273\b") at table.c:218
#1  0xb7fb1472 in create_stream (sv=sv@entry=0x4258a0, name=name@entry=0x425350 
'〰' <repeats 24 times>, encoded=encoded@entry=true, stm=0x414ab8) at 
streams.c:73
#2  0xb7fb17af in add_stream_to_table (name=0x425350 '〰' <repeats 24 times>, 
stm=0x414ab8, opaque=0x4258a0) at streams.c:370
#3  0xb7fa6aa1 in msi_enum_db_streams (db=0x415c00, fn=0xb7fb1780 
<add_stream_to_table>, opaque=0x4258a0) at libmsi-database.c:434
#4  0xb7fb1b67 in add_streams_to_table (sv=0x4258a0) at streams.c:391
#5  streams_view_create (db=0x415c00, view=0x425884) at streams.c:407
#6  0xb7fb606c in table_view_create (db=0x415c00, name=<optimized out>, 
view=0x425884) at table.c:1993
#7  0xb7fb9f35 in where_view_create (db=0x415c00, view=0xbfffdd30, 
tables=0x425298 "_Streams", cond=0x425828) at where.c:1125
#8  0xb7fb055a in sql_parse (info=<optimized out>) at sql-parser.y:520
#9  0xb7fb0ba4 in _libmsi_parse_sql (db=0x415c00, command=0x40d7c0 "SELECT 
`Data` FROM `_Streams` WHERE `Name` = ?", phview=0x425e0c, mem=0x425e1c) at 
sql-parser.y:1016
#10 0xb7fab888 in init (error=0xbffff628, self=0x425e00) at libmsi-query.c:141
#11 libmsi_query_new (database=0x415c00, query=0x4030e4 "SELECT `Data` FROM 
`_Streams` WHERE `Name` = ?", error=0xbffff628) at libmsi-query.c:670
#12 0x0040282e in cmd_extract (cmd=0x406068 <cmds+72>, argc=3, argv=0xbffff6f8, 
error=0xbffff628) at tools/msiinfo.c:369
#13 0x00401241 in main (argc=4, argv=0xbffff6f4) at tools/msiinfo.c:770

-> That one.






(gdb) directory /home/benutzer/msitools/msitools-0.97/libmsi
Source directories searched: 
/home/benutzer/msitools/msitools-0.97/libmsi:$cdir:$cwd
(gdb) list
191     void decode_streamname(const char *in, char *out)
192     {
193         unsigned count = 0;
194         const uint8_t *p = (const uint8_t *)in;
195         uint8_t *q = (uint8_t *)out;
196
197         while ( *p )
198         {
199             uint8_t ch = *p;
200             if( (ch == 0xe3 && p[1] >= 0xa0) || (ch == 0xe4 && p[1] < 0xa0) 
)
201             {
202                 /* UTF-8 encoding of 0x3800..0x47ff.  */
203                 *q++ = mime2utf(p[2]&0x7f);
204                 *q++ = mime2utf(p[1]^0xa0);
205                 p += 3;
206                 count += 2;
207                 continue;
208             }
209             if( ch == 0xe4 && p[1] == 0xa0 ) {
210                 /* UTF-8 encoding of 0x4800..0x483f.  */
211                 *q++ = mime2utf(p[2]&0x7f);
212                 p += 3;
213                 count++;
214                 continue;
215             }
216             *q++ = *p++;
217             if( ch >= 0xc1) {
218                 *q++ = *p++;
219             }
220             if( ch >= 0xe0) {
221                 *q++ = *p++;
222             }

(gdb) print out
$3 = 0xbfffdb6e '〰' <repeats 21 times>, "\343q\273\b"





(gdb) up
#1  0xb7fb1472 in create_stream (sv=sv@entry=0x4258a0, name=name@entry=0x425350 
'〰' <repeats 24 times>, encoded=encoded@entry=true, stm=0x414ab8) at 
streams.c:73
73              decode_streamname(name, decoded);
(gdb) list
61
62      static STREAM *create_stream(LibmsiStreamsView *sv, const char *name, 
bool encoded, GsfInput *stm)
63      {
64          STREAM *stream;
65          char decoded[MAX_STREAM_NAME_LEN];
66
67          stream = msi_alloc(sizeof(STREAM));
68          if (!stream)
69              return NULL;
70
71          if (encoded)
72          {
73              decode_streamname(name, decoded);
74              TRACE("stream -> %s %s\n", debugstr_a(name), 
debugstr_a(decoded));
75              name = decoded;
76          }
77
(gdb) print sizeof(decoded)
$5 = 62

Reply via email to