/ Check-in [5cd728fb]
Login

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

Overview
Comment:Fix another corruption related buffer overread in the sqlite_dbdata module.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a
User & Date: dan 2019-05-09 15:51:27
Context
2019-05-09
16:22
Improved debugging output from the OP_MakeRecord opcode. check-in: ac790729 user: drh tags: trunk
15:51
Fix another corruption related buffer overread in the sqlite_dbdata module. check-in: 5cd728fb user: dan tags: trunk
15:07
Fix further buffer overreads triggered by passing corrupt records to the sqlite_dbdata module. check-in: dbc6a9f7 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/dbdata.c.

   274    274       sqlite3_finalize(pCsr->pStmt);
   275    275     }
   276    276     pCsr->pStmt = 0;
   277    277     pCsr->iPgno = 1;
   278    278     pCsr->iCell = 0;
   279    279     pCsr->iField = 0;
   280    280     pCsr->bOnePage = 0;
          281  +  sqlite3_free(pCsr->aPage);
          282  +  sqlite3_free(pCsr->pRec);
          283  +  pCsr->pRec = 0;
          284  +  pCsr->aPage = 0;
   281    285   }
   282    286   
   283    287   /*
   284    288   ** Close an sqlite_dbdata or sqlite_dbptr cursor.
   285    289   */
   286    290   static int dbdataClose(sqlite3_vtab_cursor *pCursor){
   287    291     DbdataCursor *pCsr = (DbdataCursor*)pCursor;
................................................................................
   455    459     DbdataCursor *pCsr = (DbdataCursor*)pCursor;
   456    460     DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
   457    461   
   458    462     pCsr->iRowid++;
   459    463     while( 1 ){
   460    464       int rc;
   461    465       int iOff = (pCsr->iPgno==1 ? 100 : 0);
          466  +    int bNextPage = 0;
   462    467   
   463    468       if( pCsr->aPage==0 ){
   464    469         while( 1 ){
   465    470           if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
   466    471           rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
   467    472           if( rc!=SQLITE_OK ) return rc;
   468    473           if( pCsr->aPage ) break;
................................................................................
   491    496           int bHasRowid = 0;
   492    497           int nPointer = 0;
   493    498           sqlite3_int64 nPayload = 0;
   494    499           sqlite3_int64 nHdr = 0;
   495    500           int iHdr;
   496    501           int U, X;
   497    502           int nLocal;
   498         -        int bNextPage = 0;
   499    503     
   500    504           switch( pCsr->aPage[iOff] ){
   501    505             case 0x02:
   502    506               nPointer = 4;
   503    507               break;
   504    508             case 0x0a:
   505    509               break;
................................................................................
   599    603               iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
   600    604               pCsr->nHdr = nHdr;
   601    605               pCsr->pHdrPtr = &pCsr->pRec[iHdr];
   602    606               pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
   603    607               pCsr->iField = (bHasRowid ? -1 : 0);
   604    608             }
   605    609           }
   606         -
   607         -        if( bNextPage ){
   608         -          sqlite3_free(pCsr->aPage);
   609         -          pCsr->aPage = 0;
   610         -          if( pCsr->bOnePage ) return SQLITE_OK;
   611         -          pCsr->iPgno++;
   612         -          continue;
   613         -        }
   614    610         }else{
   615    611           pCsr->iField++;
   616    612           if( pCsr->iField>0 ){
   617    613             sqlite3_int64 iType;
   618         -          pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
   619         -          pCsr->pPtr += dbdataValueBytes(iType);
          614  +          if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
          615  +            bNextPage = 1;
          616  +          }else{
          617  +            pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
          618  +            pCsr->pPtr += dbdataValueBytes(iType);
          619  +          }
   620    620           }
   621    621         }
   622    622   
   623         -      if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
   624         -        return SQLITE_OK;
          623  +      if( bNextPage ){
          624  +        sqlite3_free(pCsr->aPage);
          625  +        sqlite3_free(pCsr->pRec);
          626  +        pCsr->aPage = 0;
          627  +        pCsr->pRec = 0;
          628  +        if( pCsr->bOnePage ) return SQLITE_OK;
          629  +        pCsr->iPgno++;
          630  +      }else{
          631  +        if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
          632  +          return SQLITE_OK;
          633  +        }
          634  +
          635  +        /* Advance to the next cell. The next iteration of the loop will load
          636  +        ** the record and so on. */
          637  +        sqlite3_free(pCsr->pRec);
          638  +        pCsr->pRec = 0;
          639  +        pCsr->iCell++;
   625    640         }
   626         -  
   627         -      /* Advance to the next cell. The next iteration of the loop will load
   628         -      ** the record and so on. */
   629         -      sqlite3_free(pCsr->pRec);
   630         -      pCsr->pRec = 0;
   631         -      pCsr->iCell++;
   632    641       }
   633    642     }
   634    643   
   635    644     assert( !"can't get here" );
   636    645     return SQLITE_OK;
   637    646   }
   638    647   
................................................................................
   733    742           break;
   734    743         case DBPTR_COLUMN_CHILD: {
   735    744           int iOff = pCsr->iPgno==1 ? 100 : 0;
   736    745           if( pCsr->iCell<0 ){
   737    746             iOff += 8;
   738    747           }else{
   739    748             iOff += 12 + pCsr->iCell*2;
          749  +          if( iOff>pCsr->nPage ) return SQLITE_OK;
   740    750             iOff = get_uint16(&pCsr->aPage[iOff]);
   741    751           }
   742         -        sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
          752  +        if( iOff<=pCsr->nPage ){
          753  +          sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
          754  +        }
   743    755           break;
   744    756         }
   745    757       }
   746    758     }else{
   747    759       switch( i ){
   748    760         case DBDATA_COLUMN_PGNO:
   749    761           sqlite3_result_int64(ctx, pCsr->iPgno);