From: dan Date: Mon, 27 Apr 2026 11:32:43 +0000 (+0000) Subject: Fix a crash that could occur if sqlite3_deserialize() was used to overwrite a databas... X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=1fc7341ad2331b31ba5edc0160554ce4a1bef35e;p=thirdparty%2Fsqlite.git Fix a crash that could occur if sqlite3_deserialize() was used to overwrite a database with an open transaction on it. Bug introduced by [fc42d31d6fca21ab] on 2018-03-07 and first released in version 3.23.0. This is not a vulnerability as an attacker that can exploit this already has the ability to execute arbitrary code. Forum post [forum:39134ba029 | 39134ba029]. FossilOrigin-Name: 77662cce9aa452ba5820e5f1a864a802763bd83b937cdb16e7025219eff7bd08 --- diff --git a/manifest b/manifest index e7d5f68cf8..7665a425ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\suint128\stype\scheck\sto\sconsolidate\sduplicated\srules. -D 2026-04-27T06:48:07.885 +C Fix\sa\scrash\sthat\scould\soccur\sif\ssqlite3_deserialize()\swas\sused\sto\soverwrite\sa\sdatabase\swith\san\sopen\stransaction\son\sit.\sBug\sintroduced\sby\s[fc42d31d6fca21ab]\son\s2018-03-07\sand\sfirst\sreleased\sin\sversion\s3.23.0.\sThis\sis\snot\sa\svulnerability\sas\san\sattacker\sthat\scan\sexploit\sthis\salready\shas\sthe\sability\sto\sexecute\sarbitrary\scode.\sForum\spost\s[forum:39134ba029\s|\s39134ba029]. +D 2026-04-27T11:32:43.484 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -670,7 +670,7 @@ F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366 F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398 F src/alter.c 7d7ddbdc189f0e0c686e32ee170abdddc95c11f2089e40df4ffcee88f5334826 F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d -F src/attach.c 7cf07d4fa42b9fc8662237c60c40b730326c30aa90ae5fffc0b18b2d726ebf61 +F src/attach.c c58278c7d2d954785591c4fde81669ec3e4d52f348c453b028a19ae8adf4f338 F src/auth.c ebec42df26b34a62b6750d30d9c2c03554a1c522020182476f7729a439fef04f F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 @@ -706,7 +706,7 @@ F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c b7da5c10a726aacacc9ad7cdcb0667deec643e117591cc69cf9b4b9e7f3e96ff -F src/memdb.c a3feb427cdd4036ea2db0ba56d152f14c8212ca760ccb05fb7aa49ff6b897df3 +F src/memdb.c 0a0e827311cec57fdea2ed3142d6684704a1b90e7995b286f74fd7d1a6c5a62c F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0 F src/msvc.h 80b35f95d93bf996ccb3e498535255f2ef1118c78764719a7cd15ab4106ccac9 F src/mutex.c 00b8cee206a67fd764d001f3a148494331d8d0b3b9c3974ecd69ff29bb444462 @@ -1424,7 +1424,7 @@ F test/malloctraceviewer.tcl 3e3ddf11e30d2b20f53aa16aa6615082fb24a100bea61cca721 F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 -F test/memdb1.test c737ac9aa5895092332b1dde24fae7ae494b7fcbcd346d22d600891096a3836d +F test/memdb1.test 916093ae5ad097660a742890a9986d1f217a620ac95efb64884041ee4c408603 F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e @@ -2203,8 +2203,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P c4a2c20839ef75534d71d928a03ad276bdc488b0baa76c1505f48dc1ff0bcdd1 -R c0dfdd72e7d337007a1f024da0578d08 -U stephan -Z df3a4e4daedc9f7f5e24107e4c6864f6 +P 362ef7bc00eea180fb3458bd8887021aed54e321901483edc00ad6b23a33d8e5 +R 4b81212a82fc7c243c0c9962742b5e3a +U dan +Z a649995f2345608b8332c732f059e0e2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 42c0b52aa9..941fa1ce7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -362ef7bc00eea180fb3458bd8887021aed54e321901483edc00ad6b23a33d8e5 +77662cce9aa452ba5820e5f1a864a802763bd83b937cdb16e7025219eff7bd08 diff --git a/src/attach.c b/src/attach.c index f27c1e6be4..616cab296a 100644 --- a/src/attach.c +++ b/src/attach.c @@ -106,6 +106,16 @@ static void attachFunc( ** from sqlite3_deserialize() to close database db->init.iDb and ** reopen it as a MemDB */ Btree *pNewBt = 0; + + pNew = &db->aDb[db->init.iDb]; + assert( pNew->pBt!=0 ); + if( sqlite3BtreeTxnState(pNew->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pNew->pBt) + ){ + rc = SQLITE_BUSY; + goto attach_error; + } + pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); @@ -115,8 +125,7 @@ static void attachFunc( /* Both the Btree and the new Schema were allocated successfully. ** Close the old db and update the aDb[] slot with the new memdb ** values. */ - pNew = &db->aDb[db->init.iDb]; - if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); + sqlite3BtreeClose(pNew->pBt); pNew->pBt = pNewBt; pNew->pSchema = pNewSchema; }else{ diff --git a/src/memdb.c b/src/memdb.c index 61a378bb3d..6cd384fd00 100644 --- a/src/memdb.c +++ b/src/memdb.c @@ -876,10 +876,10 @@ int sqlite3_deserialize( if( rc ) goto end_deserialize; db->init.iDb = (u8)iDb; db->init.reopenMemdb = 1; - rc = sqlite3_step(pStmt); + sqlite3_step(pStmt); db->init.reopenMemdb = 0; - if( rc!=SQLITE_DONE ){ - rc = SQLITE_ERROR; + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_OK ){ goto end_deserialize; } p = memdbFromDbSchema(db, zSchema); @@ -900,7 +900,6 @@ int sqlite3_deserialize( } end_deserialize: - sqlite3_finalize(pStmt); if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ sqlite3_free(pData); } diff --git a/test/memdb1.test b/test/memdb1.test index c0510abae7..0c752ca50a 100644 --- a/test/memdb1.test +++ b/test/memdb1.test @@ -280,4 +280,41 @@ do_test 900 { } 1 dbempty close + +#------------------------------------------------------------------------- +# Make sure a database cannot be overwritten by deserialize() if +# there is an open transaction on it. +# +do_execsql_test 1000 { + CREATE TABLE t(x); + INSERT INTO t VALUES(1),(2); +} + +set blob [db serialize main] + +do_test 1010 { + set seen 0 + list [catch { + db eval {SELECT x FROM t} { + incr seen + if {$seen == 1} { + db deserialize main $blob + } + } + } msg] $msg +} {1 {unable to set MEMDB content}} + +forcedelete test.db2 +sqlite3 db2 test.db2 +do_test 1020 { + set seen 0 + sqlite3_backup B db2 main db main + B step 2 + set res [list [catch { + db deserialize main $blob + } msg] $msg] + B finish + set res +} {1 {unable to set MEMDB content}} + finish_test