SQLite

Check-in [e436b2f4e5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a potential buffer overread in sqlite3VdbeRecordCompare() when a serial_type specifies a field that starts in bounds but is much too large for the allocated buffer. Mostly harmless. The overread is unlikely to go more than one or two bytes past the end of the buffer.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a
User & Date: drh 2013-08-01 20:26:04.768
Context
2013-08-01
22:26
Fix an incorrect expected result in a test case in corruptG.test. (check-in: 6913831ad2 user: drh tags: trunk)
20:26
Fix a potential buffer overread in sqlite3VdbeRecordCompare() when a serial_type specifies a field that starts in bounds but is much too large for the allocated buffer. Mostly harmless. The overread is unlikely to go more than one or two bytes past the end of the buffer. (check-in: e436b2f4e5 user: drh tags: trunk)
19:17
Make sure signed integer overflow does not cause a segfault while attempting to read a corrupt database where the header size varint on a record is larger than the maximum 32-bit signed integer. (check-in: c3baca99f4 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vdbeaux.c.
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
  nField = pKeyInfo->nField;
  assert( pKeyInfo->aSortOrder!=0 );
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );
    if( d1>=(u32)nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */







|







3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
  nField = pKeyInfo->nField;
  assert( pKeyInfo->aSortOrder!=0 );
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );
    if( d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 ) break;

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
Changes to test/corruptG.test.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# header-size varint on the index payload so that it maps into a
# negative number.  Try to use the database.
#

do_execsql_test 1.1 {
  PRAGMA page_size=512;
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1(rowid,a,b,c) VALUES(2,'abc','xyz','123');
  CREATE INDEX t1abc ON t1(a,b,c);
}

# Corrupt the file
db close
hexio_write test.db [expr {3*512 - 15}] 888080807f
sqlite3 db test.db







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# header-size varint on the index payload so that it maps into a
# negative number.  Try to use the database.
#

do_execsql_test 1.1 {
  PRAGMA page_size=512;
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1(rowid,a,b,c) VALUES(52,'abc','xyz','123');
  CREATE INDEX t1abc ON t1(a,b,c);
}

# Corrupt the file
db close
hexio_write test.db [expr {3*512 - 15}] 888080807f
sqlite3 db test.db
48
49
50
51
52
53
54
55














56
  }
} {0 ok}
do_test 1.4 {
  catchsql {
    SELECT c FROM t1 ORDER BY a;
  }
} {1 {database disk image is malformed}}















finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  }
} {0 ok}
do_test 1.4 {
  catchsql {
    SELECT c FROM t1 ORDER BY a;
  }
} {1 {database disk image is malformed}}

# Corrupt the same file in a slightly different way.  Make the record header
# sane, but corrupt one of the serial_type value to indicate a huge payload
# such that the payload begins in allocated space but overflows the buffer.
#
db close
hexio_write test.db [expr {3*512-15}] 0611ffff7f01
sqlite3 db test.db

do_test 2.1 {
  catchsql {
    SELECT rowid FROM t1 WHERE a='bc' and b='xyz123456789';
  }
} {0 {}}

finish_test