/ Check-in [1dfc95b8]
Login

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

Overview
Comment:Fix another small buffer overread in sqlite_dbdata triggered by a corrupt database page.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380
User & Date: dan 2019-05-09 18:37:37
Context
2019-05-10
12:06
Fix the round() SQL function so that it handles infinities correctly. check-in: db9acef1 user: drh tags: trunk
2019-05-09
18:37
Fix another small buffer overread in sqlite_dbdata triggered by a corrupt database page. check-in: 1dfc95b8 user: dan tags: trunk
18:33
Fix a problem in the ".recover" command allowing a circular loop of b-tree pages in a database file to cause an infinite loop. check-in: 8d2a062e user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/dbdata.c.

    76     76   
    77     77   typedef unsigned char u8;
    78     78   
    79     79   #endif
    80     80   SQLITE_EXTENSION_INIT1
    81     81   #include <string.h>
    82     82   #include <assert.h>
           83  +
           84  +#define DBDATA_PADDING_BYTES 100 
    83     85   
    84     86   typedef struct DbdataTable DbdataTable;
    85     87   typedef struct DbdataCursor DbdataCursor;
    86     88   
    87     89   /* Cursor object */
    88     90   struct DbdataCursor {
    89     91     sqlite3_vtab_cursor base;       /* Base class.  Must be first */
................................................................................
   330    332     *ppPage = 0;
   331    333     *pnPage = 0;
   332    334     sqlite3_bind_int64(pStmt, 2, pgno);
   333    335     if( SQLITE_ROW==sqlite3_step(pStmt) ){
   334    336       int nCopy = sqlite3_column_bytes(pStmt, 0);
   335    337       if( nCopy>0 ){
   336    338         u8 *pPage;
   337         -      pPage = (u8*)sqlite3_malloc64(nCopy);
          339  +      pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
   338    340         if( pPage==0 ){
   339    341           rc = SQLITE_NOMEM;
   340    342         }else{
   341    343           const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
   342    344           memcpy(pPage, pCopy, nCopy);
          345  +        memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
   343    346         }
   344    347         *ppPage = pPage;
   345    348         *pnPage = nCopy;
   346    349       }
   347    350     }
   348    351     rc2 = sqlite3_reset(pStmt);
   349    352     if( rc==SQLITE_OK ) rc = rc2;
................................................................................
   568    571             if( bNextPage || nLocal+iOff>pCsr->nPage ){
   569    572               bNextPage = 1;
   570    573             }else{
   571    574   
   572    575               /* Allocate space for payload. And a bit more to catch small buffer
   573    576               ** overruns caused by attempting to read a varint or similar from 
   574    577               ** near the end of a corrupt record.  */
   575         -            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+100);
          578  +            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
   576    579               if( pCsr->pRec==0 ) return SQLITE_NOMEM;
   577         -            memset(pCsr->pRec, 0, nPayload+100);
          580  +            memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
   578    581               pCsr->nRec = nPayload;
   579    582   
   580    583               /* Load the nLocal bytes of payload */
   581    584               memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
   582    585               iOff += nLocal;
   583    586   
   584    587               /* Load content from overflow pages */