gnu gcc address sanitizer finds stack-use-after-scope in sqlite3VdbeExec

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

gnu gcc address sanitizer finds stack-use-after-scope in sqlite3VdbeExec

Vitti
Hi there, I just downloaded version 3.18 and after compiling it with
the following command

gcc shell.c sqlite3.c -g -fsanitize=address -DSQLITE_DEBUG -o sqlite
-ldl -pthread

running sqlite command

.selftest --init

I get a sanitizer error message.
In my opinion this is probably due to erroneous usage of variable res
in the branches
of the huge switch in sqlite3VdbeExec

I have Linux Fedora 25 on an x86-64 hardware.
gnu gcc 7.0.1
This one occurred also in 3.16 from Qt 5.9 where I found it initially.
Best regards
Vitti

=================================================================
==3045==ERROR: AddressSanitizer: stack-use-after-scope on address
0x7ffca9d69510 at pc 0x000000529307 bp 0x7ffca9d68bf0 sp
0x7ffca9d68be8
WRITE of size 4 at 0x7ffca9d69510 thread T0
    #0 0x529306 in sqlite3VdbeExec /home/vitti/sqlite/sqlite3.c:82355
    #1 0x5087c2 in sqlite3Step /home/vitti/sqlite/sqlite3.c:76607
    #2 0x508e38 in sqlite3_step /home/vitti/sqlite/sqlite3.c:76668
    #3 0x5bbe71 in sqlite3_exec /home/vitti/sqlite/sqlite3.c:110900
    #4 0x40dc26 in createSelftestTable /home/vitti/sqlite/shell.c:2102
    #5 0x424347 in do_meta_command /home/vitti/sqlite/shell.c:5867
    #6 0x429f00 in process_input /home/vitti/sqlite/shell.c:6730
    #7 0x42c8a2 in main /home/vitti/sqlite/shell.c:7365
    #8 0x2ae9ef525400 in __libc_start_main (/usr/lib64/libc.so.6+0x20400)
    #9 0x402ef9 in _start
(/home/vitti/sqlite-amalgamation-3180000/sqlite+0x402ef9)

Address 0x7ffca9d69510 is located in stack of thread T0 at offset 672 in frame
    #0 0x510037 in sqlite3VdbeExec /home/vitti/sqlite/sqlite3.c:78743

  This frame has 47 object(s):
    [32, 36) 'p2'
    [96, 100) 'offset'
    [160, 164) 'avail'
    [224, 228) 't'
    [288, 292) 'len'
    [352, 356) 'iMeta'
    [416, 420) 'iMeta'
    [480, 484) 'pgno'
    [544, 548) 'res'
    [608, 612) 'res'
    [672, 676) 'res' <== Memory access at offset 672 is inside this variable
    [736, 740) 'res'
    [800, 804) 'res'
    [864, 868) 'res'
    [928, 932) 'res'
    [992, 996) 'res'
    [1056, 1060) 'res'
    [1120, 1124) 'res'
    [1184, 1188) 'res'
    [1248, 1252) 'iMoved'
    [1312, 1316) 'nChange'
    [1376, 1380) 'pgno'
    [1440, 1444) 'nErr'
    [1504, 1512) 'iB'
    [1568, 1576) 'iA'
    [1632, 1640) 'uA'
    [1696, 1704) 'pC'
    [1760, 1768) 'nEntry'
    [1824, 1832) 'v'
    [1888, 1896) 'v'
    [1952, 1960) 'rowid'
    [2016, 2024) 'val'
    [2080, 2088) 'x'
    [2144, 2152) 'pVCur'
    [2208, 2216) 'rowid'
    [2272, 2284) 'aRes'
    [2336, 2360) 'r'
    [2400, 2424) 'r'
    [2464, 2488) 'r'
    [2528, 2552) 'r'
    [2592, 2616) 'initData'
    [2656, 2704) 'x'
    [2752, 2800) 'x'
    [2848, 2904) 'sContext'
    [2944, 3016) 'sMem'
    [3072, 3144) 't'
    [3200, 3272) 'sMem'
HINT: this may be a false positive if your program uses some custom
stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope
/home/vitti/sqlite/sqlite3.c:82355 in sqlite3VdbeExec
Shadow bytes around the buggy address:
  0x1000153a5250: f1 f1 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
  0x1000153a5260: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
  0x1000153a5270: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
  0x1000153a5280: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
  0x1000153a5290: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
=>0x1000153a52a0: f2 f2[f8]f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
  0x1000153a52b0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
  0x1000153a52c0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
  0x1000153a52d0: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
  0x1000153a52e0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
  0x1000153a52f0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==3045==ABORTING
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: gnu gcc address sanitizer finds stack-use-after-scope in sqlite3VdbeExec

Dan Kennedy-4
On 04/18/2017 07:12 PM, Vitti wrote:
> Hi there, I just downloaded version 3.18 and after compiling it with
> the following command
>
> gcc shell.c sqlite3.c -g -fsanitize=address -DSQLITE_DEBUG -o sqlite
> -ldl -pthread

Hi,

Thanks for reporting this. I haven't been able to reproduce it with any
of the released versions of gcc so far. Does it not like us using a
switch() to jump into the middle of a block that contains variable
declarations?

If you compile the code below with gcc 7.0.1:

   gcc code.c -fsantitize=address -o tst

and then run:

  ./tst 2

Does the sanitizer make the same complaint?

Thanks,
Dan.

/**********************************************/

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv){
   int a, b, c;

   if( argc!=2 ) return -1;

   a = atoi(argv[1]);
   b = 2;
   c = 0;

   switch( a ){
     case 1: {
       int res;
       b = 1;

     case 2:
       res = b;
       c = res;
       break;
     }
   }

   printf("c=%d\n", c);
   return 0;
}

/**********************************************/















>
> running sqlite command
>
> .selftest --init
>
> I get a sanitizer error message.
> In my opinion this is probably due to erroneous usage of variable res
> in the branches
> of the huge switch in sqlite3VdbeExec
>
> I have Linux Fedora 25 on an x86-64 hardware.
> gnu gcc 7.0.1
> This one occurred also in 3.16 from Qt 5.9 where I found it initially.
> Best regards
> Vitti
>
> =================================================================
> ==3045==ERROR: AddressSanitizer: stack-use-after-scope on address
> 0x7ffca9d69510 at pc 0x000000529307 bp 0x7ffca9d68bf0 sp
> 0x7ffca9d68be8
> WRITE of size 4 at 0x7ffca9d69510 thread T0
>      #0 0x529306 in sqlite3VdbeExec /home/vitti/sqlite/sqlite3.c:82355
>      #1 0x5087c2 in sqlite3Step /home/vitti/sqlite/sqlite3.c:76607
>      #2 0x508e38 in sqlite3_step /home/vitti/sqlite/sqlite3.c:76668
>      #3 0x5bbe71 in sqlite3_exec /home/vitti/sqlite/sqlite3.c:110900
>      #4 0x40dc26 in createSelftestTable /home/vitti/sqlite/shell.c:2102
>      #5 0x424347 in do_meta_command /home/vitti/sqlite/shell.c:5867
>      #6 0x429f00 in process_input /home/vitti/sqlite/shell.c:6730
>      #7 0x42c8a2 in main /home/vitti/sqlite/shell.c:7365
>      #8 0x2ae9ef525400 in __libc_start_main (/usr/lib64/libc.so.6+0x20400)
>      #9 0x402ef9 in _start
> (/home/vitti/sqlite-amalgamation-3180000/sqlite+0x402ef9)
>
> Address 0x7ffca9d69510 is located in stack of thread T0 at offset 672 in frame
>      #0 0x510037 in sqlite3VdbeExec /home/vitti/sqlite/sqlite3.c:78743
>
>    This frame has 47 object(s):
>      [32, 36) 'p2'
>      [96, 100) 'offset'
>      [160, 164) 'avail'
>      [224, 228) 't'
>      [288, 292) 'len'
>      [352, 356) 'iMeta'
>      [416, 420) 'iMeta'
>      [480, 484) 'pgno'
>      [544, 548) 'res'
>      [608, 612) 'res'
>      [672, 676) 'res' <== Memory access at offset 672 is inside this variable
>      [736, 740) 'res'
>      [800, 804) 'res'
>      [864, 868) 'res'
>      [928, 932) 'res'
>      [992, 996) 'res'
>      [1056, 1060) 'res'
>      [1120, 1124) 'res'
>      [1184, 1188) 'res'
>      [1248, 1252) 'iMoved'
>      [1312, 1316) 'nChange'
>      [1376, 1380) 'pgno'
>      [1440, 1444) 'nErr'
>      [1504, 1512) 'iB'
>      [1568, 1576) 'iA'
>      [1632, 1640) 'uA'
>      [1696, 1704) 'pC'
>      [1760, 1768) 'nEntry'
>      [1824, 1832) 'v'
>      [1888, 1896) 'v'
>      [1952, 1960) 'rowid'
>      [2016, 2024) 'val'
>      [2080, 2088) 'x'
>      [2144, 2152) 'pVCur'
>      [2208, 2216) 'rowid'
>      [2272, 2284) 'aRes'
>      [2336, 2360) 'r'
>      [2400, 2424) 'r'
>      [2464, 2488) 'r'
>      [2528, 2552) 'r'
>      [2592, 2616) 'initData'
>      [2656, 2704) 'x'
>      [2752, 2800) 'x'
>      [2848, 2904) 'sContext'
>      [2944, 3016) 'sMem'
>      [3072, 3144) 't'
>      [3200, 3272) 'sMem'
> HINT: this may be a false positive if your program uses some custom
> stack unwind mechanism or swapcontext
>        (longjmp and C++ exceptions *are* supported)
> SUMMARY: AddressSanitizer: stack-use-after-scope
> /home/vitti/sqlite/sqlite3.c:82355 in sqlite3VdbeExec
> Shadow bytes around the buggy address:
>    0x1000153a5250: f1 f1 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
>    0x1000153a5260: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
>    0x1000153a5270: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
>    0x1000153a5280: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
>    0x1000153a5290: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
> =>0x1000153a52a0: f2 f2[f8]f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
>    0x1000153a52b0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
>    0x1000153a52c0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2
>    0x1000153a52d0: f2 f2 f8 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
>    0x1000153a52e0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
>    0x1000153a52f0: f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2
> Shadow byte legend (one shadow byte represents 8 application bytes):
>    Addressable:           00
>    Partially addressable: 01 02 03 04 05 06 07
>    Heap left redzone:       fa
>    Freed heap region:       fd
>    Stack left redzone:      f1
>    Stack mid redzone:       f2
>    Stack right redzone:     f3
>    Stack after return:      f5
>    Stack use after scope:   f8
>    Global redzone:          f9
>    Global init order:       f6
>    Poisoned by user:        f7
>    Container overflow:      fc
>    Array cookie:            ac
>    Intra object redzone:    bb
>    ASan internal:           fe
>    Left alloca redzone:     ca
>    Right alloca redzone:    cb
> ==3045==ABORTING
> _______________________________________________
> sqlite-users mailing list
> [hidden email]
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: gnu gcc address sanitizer finds stack-use-after-scope in sqlite3VdbeExec

Cezary H. Noweta
On 2017-04-19 19:31, Dan Kennedy wrote:
> On 04/18/2017 07:12 PM, Vitti wrote:
>> In my opinion this is probably due to erroneous usage of variable res
>> in the branches
>> of the huge switch in sqlite3VdbeExec

What's wrong with ``{ int res; res = 0; }''? The sanitizer should alert
in the following code: ``int *p; { int res; p = &res; } p[0] = 0;''.

> Does it not like us using a
> switch() to jump into the middle of a block that contains variable
> declarations?

If it had been true in general, then it would have tripped on earlier
``pC = p->apCsr[pOp->p1];'' or ``pCrsr = pC->uc.pCursor;'' (both ``pC''
and ``pCrsr'' are local to the block). It is too simple to be not
detected. I would bet on a bug in the sanitizer triggered by a
composition of (a) successive blocks conataining ``res'', (b) switch
into the place just after a declaration in the middle of a block, (c) an
using of a pointer to ``res'', and (d) a huge size of ``switch(...)''.

- best regards

Cezary H. Noweta
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: gnu gcc address sanitizer finds stack-use-after-scope in sqlite3VdbeExec

Cezary H. Noweta
In reply to this post by Dan Kennedy-4
Hello,

On 2017-04-19 19:31, Dan Kennedy wrote:

> If you compile the code below with gcc 7.0.1:
>
>    gcc code.c -fsantitize=address -o tst
>
> and then run:
>
>   ./tst 2
>
> Does the sanitizer make the same complaint?

> [...]

> /**********************************************/
> [...]
>    switch( a ){
>      case 1: {
>        int res;
>        b = 1;
>
>      case 2:
>        res = b;
>        c = res;
>        break;
>      }
>    }
> [...]
> /**********************************************/
IMHO, ``res'' will not be even protruded to the sanitizer. ``vdbe.c''s
code is using a pointer to ``res'', passing it as a parameter -- thus
SQLite's ``res'' is handled by use-after-scope sanitizer, while ``pC''
and ``pCrsr'' are not.

It looks that GCC forgets to unpoison ``res'' for some reason. Looking
at the GCC's test cases I would suggest: (a) to place label
``OP_SeekRowid'' just after declarations (i.e. after ``u64 iKey;'',
and/or (b) to enclose ``case OP_NotExists:''...``break;'' into a nested,
inner block, and/or (c) to open the block _before_ ``case OP_SeekRowid:''.

Unfortunately, ``gcc-7-branch'' still is decompressing on my hardware,
so I cannot check which one(s) of above (a), (b), (c) will help.
Regardless of all, the original problem concerns GCC rather then SQLite
itself.

-- best regards

Cezary H. Noweta
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users