SQLite

Check-in [8fa0937a2f]
Login

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

Overview
Comment:Fix a couple of btree asserts that would fail when encountering 32-bit rollover in cell payload size fields (cell payloads this large always indicate corruption).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8fa0937a2f3476dd280259e252d6f422c33d38ee
User & Date: dan 2015-05-25 18:47:26.960
Context
2015-05-25
19:24
Have the b-tree layer return SQLITE_CORRUPT to any attempt to open a cursor with a root page number less than 1. (check-in: aa18c8e9d1 user: dan tags: trunk)
18:47
Fix a couple of btree asserts that would fail when encountering 32-bit rollover in cell payload size fields (cell payloads this large always indicate corruption). (check-in: 8fa0937a2f user: dan tags: trunk)
17:07
Fix a case where database corruption may cause SQLite to write past the end of a buffer. (check-in: 97806a7814 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
5746
5747
5748
5749
5750
5751
5752
5753


5754
5755
5756
5757
5758
5759
5760
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  assert( ovflPgno==0 || nOvfl>0 );


  while( nOvfl-- ){
    Pgno iNext = 0;
    MemPage *pOvfl = 0;
    if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
      /* 0 is not a legal page number and page 1 cannot be an 
      ** overflow page. Therefore if ovflPgno<2 or past the end of the 
      ** file the database must be corrupt. */







|
>
>







5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  assert( nOvfl>0 || 
    (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
  );
  while( nOvfl-- ){
    Pgno iNext = 0;
    MemPage *pOvfl = 0;
    if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
      /* 0 is not a legal page number and page 1 cannot be an 
      ** overflow page. Therefore if ovflPgno<2 or past the end of the 
      ** file the database must be corrupt. */
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
  u8 *ptr;        /* Used to move bytes around within data[] */
  int rc;         /* The return code */
  int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */

  if( *pRC ) return;

  assert( idx>=0 && idx<pPage->nCell );
  assert( sz==cellSize(pPage, idx) );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  data = pPage->aData;
  ptr = &pPage->aCellIdx[2*idx];
  pc = get2byte(ptr);
  hdr = pPage->hdrOffset;
  testcase( pc==get2byte(&data[hdr+5]) );







|







6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
  u8 *ptr;        /* Used to move bytes around within data[] */
  int rc;         /* The return code */
  int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */

  if( *pRC ) return;

  assert( idx>=0 && idx<pPage->nCell );
  assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  data = pPage->aData;
  ptr = &pPage->aCellIdx[2*idx];
  pc = get2byte(ptr);
  hdr = pPage->hdrOffset;
  testcase( pc==get2byte(&data[hdr+5]) );
Changes to test/corruptI.test.
179
180
181
182
183
184
185





















186
187
} {12}

do_test 5.3 {
  sqlite3 db test.db
  catchsql { CREATE TABLE tx(x); }
} {1 {database disk image is malformed}}























finish_test







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


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
} {12}

do_test 5.3 {
  sqlite3 db test.db
  catchsql { CREATE TABLE tx(x); }
} {1 {database disk image is malformed}}


#-------------------------------------------------------------------------
# Set the payload size of a cell to just less than 2^32 bytes (not
# possible in an uncorrupted db). Then try to delete the cell. At one
# point this led to an integer overflow that caused an assert() to fail.
#
reset_db
do_execsql_test 6.0 {
  PRAGMA page_size = 512;
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(zeroblob(300));
  INSERT INTO t1 VALUES(zeroblob(600));
} {}
do_test 6.1 {
  db close
  hexio_write test.db 616 EAFFFFFF0202
  sqlite3 db test.db
  breakpoint
  execsql { DELETE FROM t1 WHERE rowid=2 }
} {}


finish_test