aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-07-22 18:03:56 +0000
committerdrh <drh@noemail.net>2020-07-22 18:03:56 +0000
commit3b3ddbae36ea40bf0f7d7ef707e722fdad8aa9c0 (patch)
tree060f77c2f36e9517d2c867c575861803e378ce6a /src
parent584e8b76303ff2146c5eb831ace29993f00ef510 (diff)
downloadsqlite-3b3ddbae36ea40bf0f7d7ef707e722fdad8aa9c0.tar.gz
sqlite-3b3ddbae36ea40bf0f7d7ef707e722fdad8aa9c0.zip
When parsing the schema, detect out-of-bounds rootpage values and throw an
error. FossilOrigin-Name: 6c3a2727dc912ed800146e07db5d15d0f3468d13701165ba763c4b114c3e18e8
Diffstat (limited to 'src')
-rw-r--r--src/prepare.c7
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/vdbe.c1
3 files changed, 9 insertions, 0 deletions
diff --git a/src/prepare.c b/src/prepare.c
index dab57682f..84f2ee8a2 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -116,6 +116,10 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
assert( db->init.busy );
db->init.iDb = iDb;
sqlite3GetUInt32(argv[3], &db->init.newTnum);
+ if( db->init.newTnum>pData->mxPage && pData->mxPage!=0 ){
+ corruptSchema(pData, argv[1], "invalid rootpage");
+ return 0;
+ }
db->init.orphanTrigger = 0;
db->init.azInit = argv;
pStmt = 0;
@@ -151,6 +155,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
if( pIndex==0
|| sqlite3GetUInt32(argv[3],&pIndex->tnum)==0
|| pIndex->tnum<2
+ || (pIndex->tnum>pData->mxPage && pData->mxPage!=0)
|| sqlite3IndexHasDuplicateRootPage(pIndex)
){
corruptSchema(pData, argv[1], pIndex?"invalid rootpage":"orphan index");
@@ -207,6 +212,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
initData.nInitRow = 0;
+ initData.mxPage = 0;
sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
db->mDbFlags &= mask;
if( initData.rc ){
@@ -329,6 +335,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
/* Read the schema information out of the schema tables
*/
assert( db->init.busy );
+ initData.mxPage = sqlite3BtreeLastPage(pDb->pBt);
{
char *zSql;
zSql = sqlite3MPrintf(db,
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 32155892f..f2a26109c 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3629,6 +3629,7 @@ typedef struct {
int rc; /* Result code stored here */
u32 mInitFlags; /* Flags controlling error messages */
u32 nInitRow; /* Number of rows processed */
+ Pgno mxPage; /* Maximum page number. 0 for no limit. */
} InitData;
/*
diff --git a/src/vdbe.c b/src/vdbe.c
index c86b54c8f..5134da4b3 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -6122,6 +6122,7 @@ case OP_ParseSchema: {
initData.iDb = iDb;
initData.pzErrMsg = &p->zErrMsg;
initData.mInitFlags = 0;
+ initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
zSql = sqlite3MPrintf(db,
"SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zSchema, pOp->p4.z);