SQLite

Check-in [1dfc95b867]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380
User & Date: dan 2019-05-09 18:37:37.967
Context
2019-05-10
12:06
Fix the round() SQL function so that it handles infinities correctly. (check-in: db9acef14d 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: 1dfc95b867 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: 8d2a062eb8 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/misc/dbdata.c.
76
77
78
79
80
81
82


83
84
85
86
87
88
89

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 */







>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

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 */
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
  *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;







|





>







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  *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;
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
          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 */







|

|







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
          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 */