mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Make sure a corrupt index does not cause a buffer overread in
sqlite3VdbeRecordCompare(). FossilOrigin-Name: 471cf0d8e7857110e525e029c2d535cb518dba6a
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Expand\spassing\sof\sa\slast\serror\sargument\sto\sthe\sgetLastErrorMsg\sfunction.\s\sAlso,\sremove\sunused\sSQLITE_W32_THREADS\sdefine.
|
C Make\ssure\sa\scorrupt\sindex\sdoes\snot\scause\sa\sbuffer\soverread\sin\s\nsqlite3VdbeRecordCompare().
|
||||||
D 2011-11-10T21:45:06.907
|
D 2011-11-11T00:27:15.786
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -125,9 +125,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
|||||||
F src/backup.c 4368158da74d4711888e03264105c5c527d76caf
|
F src/backup.c 4368158da74d4711888e03264105c5c527d76caf
|
||||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||||
F src/btree.c 32199e2d939233ade25340eaba450f818b37c079
|
F src/btree.c 2521a74f04cf288497af3b318fa3a31efb272ef6
|
||||||
F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
|
F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
|
||||||
F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
|
F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b
|
||||||
F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814
|
F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814
|
||||||
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
@@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
|||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
P 32ab365715e2c50f30aa2f92a323857b9d917bf6
|
P 8f28797984c1d4700357a75815ca4b324c3ebf5c
|
||||||
R d5d8a9a49f50a40940976e300037af02
|
R 0b7ae5ff536a087fdb2c3479a3ed3d3f
|
||||||
U mistachkin
|
U drh
|
||||||
Z a0f426067c598247950f7d47f9af3362
|
Z 717b87433a48f5a306459509a02bb49f
|
||||||
|
@@ -1 +1 @@
|
|||||||
8f28797984c1d4700357a75815ca4b324c3ebf5c
|
471cf0d8e7857110e525e029c2d535cb518dba6a
|
20
src/btree.c
20
src/btree.c
@@ -859,7 +859,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
|
|||||||
** This routine works only for pages that do not contain overflow cells.
|
** This routine works only for pages that do not contain overflow cells.
|
||||||
*/
|
*/
|
||||||
#define findCell(P,I) \
|
#define findCell(P,I) \
|
||||||
((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)])))
|
((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)])))
|
||||||
#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
|
#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
|
||||||
|
|
||||||
|
|
||||||
@@ -1409,6 +1409,8 @@ static int btreeInitPage(MemPage *pPage){
|
|||||||
pPage->nOverflow = 0;
|
pPage->nOverflow = 0;
|
||||||
usableSize = pBt->usableSize;
|
usableSize = pBt->usableSize;
|
||||||
pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
|
pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
|
||||||
|
pPage->aDataEnd = &data[usableSize];
|
||||||
|
pPage->aCellIdx = &data[cellOffset];
|
||||||
top = get2byteNotZero(&data[hdr+5]);
|
top = get2byteNotZero(&data[hdr+5]);
|
||||||
pPage->nCell = get2byte(&data[hdr+3]);
|
pPage->nCell = get2byte(&data[hdr+3]);
|
||||||
if( pPage->nCell>MX_CELL(pBt) ){
|
if( pPage->nCell>MX_CELL(pBt) ){
|
||||||
@@ -1512,6 +1514,8 @@ static void zeroPage(MemPage *pPage, int flags){
|
|||||||
decodeFlags(pPage, flags);
|
decodeFlags(pPage, flags);
|
||||||
pPage->hdrOffset = hdr;
|
pPage->hdrOffset = hdr;
|
||||||
pPage->cellOffset = first;
|
pPage->cellOffset = first;
|
||||||
|
pPage->aDataEnd = &data[pBt->usableSize];
|
||||||
|
pPage->aCellIdx = &data[first];
|
||||||
pPage->nOverflow = 0;
|
pPage->nOverflow = 0;
|
||||||
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
|
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
|
||||||
pPage->maskPage = (u16)(pBt->pageSize - 1);
|
pPage->maskPage = (u16)(pBt->pageSize - 1);
|
||||||
@@ -4550,16 +4554,22 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
** 2 bytes of the cell.
|
** 2 bytes of the cell.
|
||||||
*/
|
*/
|
||||||
int nCell = pCell[0];
|
int nCell = pCell[0];
|
||||||
if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
|
if( !(nCell & 0x80)
|
||||||
|
&& nCell<=pPage->maxLocal
|
||||||
|
&& (pCell+nCell+1)<=pPage->aDataEnd
|
||||||
|
){
|
||||||
/* This branch runs if the record-size field of the cell is a
|
/* This branch runs if the record-size field of the cell is a
|
||||||
** single byte varint and the record fits entirely on the main
|
** single byte varint and the record fits entirely on the main
|
||||||
** b-tree page. */
|
** b-tree page. */
|
||||||
|
testcase( pCell+nCell+1==pPage->aDataEnd );
|
||||||
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
|
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
|
||||||
}else if( !(pCell[1] & 0x80)
|
}else if( !(pCell[1] & 0x80)
|
||||||
&& (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
|
&& (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
|
||||||
|
&& (pCell+nCell+2)<=pPage->aDataEnd
|
||||||
){
|
){
|
||||||
/* The record-size field is a 2 byte varint and the record
|
/* The record-size field is a 2 byte varint and the record
|
||||||
** fits entirely on the main b-tree page. */
|
** fits entirely on the main b-tree page. */
|
||||||
|
testcase( pCell+nCell+2==pPage->aDataEnd );
|
||||||
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
|
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
|
||||||
}else{
|
}else{
|
||||||
/* The record flows over onto one or more overflow pages. In
|
/* The record flows over onto one or more overflow pages. In
|
||||||
@@ -5454,7 +5464,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
|||||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||||
data = pPage->aData;
|
data = pPage->aData;
|
||||||
ptr = &data[pPage->cellOffset + 2*idx];
|
ptr = &pPage->aCellIdx[2*idx];
|
||||||
pc = get2byte(ptr);
|
pc = get2byte(ptr);
|
||||||
hdr = pPage->hdrOffset;
|
hdr = pPage->hdrOffset;
|
||||||
testcase( pc==get2byte(&data[hdr+5]) );
|
testcase( pc==get2byte(&data[hdr+5]) );
|
||||||
@@ -5468,7 +5478,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
|||||||
*pRC = rc;
|
*pRC = rc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2];
|
endPtr = &pPage->aCellIdx[2*pPage->nCell - 2];
|
||||||
assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
|
assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
|
||||||
while( ptr<endPtr ){
|
while( ptr<endPtr ){
|
||||||
*(u16*)ptr = *(u16*)&ptr[2];
|
*(u16*)ptr = *(u16*)&ptr[2];
|
||||||
@@ -5610,7 +5620,7 @@ static void assemblePage(
|
|||||||
assert( pPage->nCell==0 );
|
assert( pPage->nCell==0 );
|
||||||
assert( get2byteNotZero(&data[hdr+5])==nUsable );
|
assert( get2byteNotZero(&data[hdr+5])==nUsable );
|
||||||
|
|
||||||
pCellptr = &data[pPage->cellOffset + nCell*2];
|
pCellptr = &pPage->aCellIdx[nCell*2];
|
||||||
cellbody = nUsable;
|
cellbody = nUsable;
|
||||||
for(i=nCell-1; i>=0; i--){
|
for(i=nCell-1; i>=0; i--){
|
||||||
u16 sz = aSize[i];
|
u16 sz = aSize[i];
|
||||||
|
@@ -289,6 +289,8 @@ struct MemPage {
|
|||||||
} aOvfl[5];
|
} aOvfl[5];
|
||||||
BtShared *pBt; /* Pointer to BtShared that this page is part of */
|
BtShared *pBt; /* Pointer to BtShared that this page is part of */
|
||||||
u8 *aData; /* Pointer to disk image of the page data */
|
u8 *aData; /* Pointer to disk image of the page data */
|
||||||
|
u8 *aDataEnd; /* One byte past the end of usable data */
|
||||||
|
u8 *aCellIdx; /* The cell index area */
|
||||||
DbPage *pDbPage; /* Pager page handle */
|
DbPage *pDbPage; /* Pager page handle */
|
||||||
Pgno pgno; /* Page number for this page */
|
Pgno pgno; /* Page number for this page */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user