/ 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 Unified Diffs Show Whitespace Changes Patch

Changes to ext/misc/dbdata.c.

76
77
78
79
80
81
82


83
84
85
86
87
88
89
...
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584

typedef unsigned char u8;

#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>



typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;

/* Cursor object */
struct DbdataCursor {
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
................................................................................
  *ppPage = 0;
  *pnPage = 0;
  sqlite3_bind_int64(pStmt, 2, pgno);
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    int nCopy = sqlite3_column_bytes(pStmt, 0);
    if( nCopy>0 ){
      u8 *pPage;
      pPage = (u8*)sqlite3_malloc64(nCopy);
      if( pPage==0 ){
        rc = SQLITE_NOMEM;
      }else{
        const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
        memcpy(pPage, pCopy, nCopy);

      }
      *ppPage = pPage;
      *pnPage = nCopy;
    }
  }
  rc2 = sqlite3_reset(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;
................................................................................
          if( bNextPage || nLocal+iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{

            /* Allocate space for payload. And a bit more to catch small buffer
            ** overruns caused by attempting to read a varint or similar from 
            ** near the end of a corrupt record.  */
            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+100);
            if( pCsr->pRec==0 ) return SQLITE_NOMEM;
            memset(pCsr->pRec, 0, nPayload+100);
            pCsr->nRec = nPayload;

            /* Load the nLocal bytes of payload */
            memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
            iOff += nLocal;

            /* Load content from overflow pages */







>
>







 







|





>







 







|

|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

typedef unsigned char u8;

#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>

#define DBDATA_PADDING_BYTES 100 

typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;

/* Cursor object */
struct DbdataCursor {
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
................................................................................
  *ppPage = 0;
  *pnPage = 0;
  sqlite3_bind_int64(pStmt, 2, pgno);
  if( SQLITE_ROW==sqlite3_step(pStmt) ){
    int nCopy = sqlite3_column_bytes(pStmt, 0);
    if( nCopy>0 ){
      u8 *pPage;
      pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
      if( pPage==0 ){
        rc = SQLITE_NOMEM;
      }else{
        const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
        memcpy(pPage, pCopy, nCopy);
        memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
      }
      *ppPage = pPage;
      *pnPage = nCopy;
    }
  }
  rc2 = sqlite3_reset(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;
................................................................................
          if( bNextPage || nLocal+iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{

            /* Allocate space for payload. And a bit more to catch small buffer
            ** overruns caused by attempting to read a varint or similar from 
            ** near the end of a corrupt record.  */
            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
            if( pCsr->pRec==0 ) return SQLITE_NOMEM;
            memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
            pCsr->nRec = nPayload;

            /* Load the nLocal bytes of payload */
            memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
            iOff += nLocal;

            /* Load content from overflow pages */