Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Guard against attacks from deliberately corrupted database files. (CVS 6021) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
da2ec96422b1f9de2e47d3b8c19ed205 |
User & Date: | drh 2008-12-11 16:17:04.000 |
Context
2008-12-11
| ||
19:50 | Make sure the OP_ForceInt vdbe opcode does not cause a rowid overflow. Ticket #3536. Tests to verify this change will be checked in separately. (CVS 6022) (check-in: 6a049c6595 user: drh tags: trunk) | |
16:17 | Guard against attacks from deliberately corrupted database files. (CVS 6021) (check-in: da2ec96422 user: drh tags: trunk) | |
13:08 | Increase the version number to 3.6.7. (CVS 6020) (check-in: 7c367515f8 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.799 2008/12/11 16:17:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
4096 4097 4098 4099 4100 4101 4102 | ** P1>1. Write the root page number of the new table into ** register P2. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ | | < | | < | 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 | ** P1>1. Write the root page number of the new table into ** register P2. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ int pgno = 0; int flags; Db *pDb; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ /* flags = BTREE_INTKEY; */ flags = BTREE_LEAFDATA|BTREE_INTKEY; }else{ flags = BTREE_ZERODATA; } rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); pOut->u.i = pgno; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: ParseSchema P1 P2 * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 ** that match the WHERE clause P4. P2 is the "force" flag. Always do |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.427 2008/12/11 16:17:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" |
︙ | ︙ | |||
2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 | } /* ** pCur points at an index entry created using the OP_MakeRecord opcode. ** Read the rowid (the last field in the record) and store it in *rowid. ** Return SQLITE_OK if everything works, or an error code otherwise. */ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ Mem m, v; sqlite3BtreeKeySize(pCur, &nCellKey); | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 | } /* ** pCur points at an index entry created using the OP_MakeRecord opcode. ** Read the rowid (the last field in the record) and store it in *rowid. ** Return SQLITE_OK if everything works, or an error code otherwise. ** ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ Mem m, v; /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption */ sqlite3BtreeKeySize(pCur, &nCellKey); if( unlikely(nCellKey<=0 || nCellKey>0x7fffffff) ){ return SQLITE_CORRUPT_BKPT; } /* Read in the complete content of the index entry */ m.flags = 0; m.db = 0; m.zMalloc = 0; rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m); if( rc ){ return rc; } /* The index entry must begin with a header size */ (void)getVarint32((u8*)m.z, szHdr); testcase( szHdr==2 ); testcase( szHdr==m.n ); if( unlikely(szHdr<2 || szHdr>m.n) ){ goto idx_rowid_corruption; } /* The last field of the index should be an integer - the ROWID. ** Verify that the last entry really is an integer. */ (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid); testcase( typeRowid==1 ); testcase( typeRowid==2 ); testcase( typeRowid==3 ); testcase( typeRowid==4 ); testcase( typeRowid==5 ); testcase( typeRowid==6 ); testcase( typeRowid==8 ); testcase( typeRowid==9 ); if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ goto idx_rowid_corruption; } lenRowid = sqlite3VdbeSerialTypeLen(typeRowid); testcase( m.n-lenRowid==szHdr ); if( unlikely(m.n-lenRowid<szHdr) ){ goto idx_rowid_corruption; } /* Fetch the integer off the end of the index record */ sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v); *rowid = v.u.i; sqlite3VdbeMemRelease(&m); return SQLITE_OK; /* Jump here if database corruption is detected after m has been ** allocated. Free the m object and return SQLITE_CORRUPT. */ idx_rowid_corruption: testcase( m.zMalloc!=0 ); sqlite3VdbeMemRelease(&m); return SQLITE_CORRUPT_BKPT; } /* ** Compare the key of the index entry that cursor pC is point to against ** the key string in pKey (of length nKey). Write into *pRes a number ** that is negative, zero, or positive if pC is less than, equal to, ** or greater than pKey. Return SQLITE_OK on success. |
︙ | ︙ |