]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved detection of corrupt freelist chains on btree pages.
authordrh <>
Fri, 26 Jun 2026 10:02:37 +0000 (10:02 +0000)
committerdrh <>
Fri, 26 Jun 2026 10:02:37 +0000 (10:02 +0000)
Plus, add assert()s to verify that the min-heap does not overflow
inside of PRAGMA integrity_check.

FossilOrigin-Name: 1a888ea60be20a80e85a108a74dab0dd9faf72ca89389defeeb9c99ecafb3ea4

manifest
manifest.uuid
src/btree.c
src/btreeInt.h
test/fts3corrupt4.test

index 6f25cdbc05c33f39e34f9c1a435a3c51b66be7c0..5c7ce212bf4c8626dd0d42c5dce8c37cb6a9b4db 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\scompiler\swarnings.
-D 2026-06-26T02:03:54.975
+C Improved\sdetection\sof\scorrupt\sfreelist\schains\son\sbtree\spages.\nPlus,\sadd\sassert()s\sto\sverify\sthat\sthe\smin-heap\sdoes\snot\soverflow\ninside\sof\sPRAGMA\sintegrity_check.
+D 2026-06-26T10:02:37.615
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -675,9 +675,9 @@ F src/auth.c ebec42df26b34a62b6750d30d9c2c03554a1c522020182476f7729a439fef04f
 F src/backup.c a3181d1a979bca40dd2b60393cf664c9659e71c25938661c1d3a786e489880f0
 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
-F src/btree.c c69601aac556129f64d9e8221441572c89479b720a51cbf738658fe0797d7107
+F src/btree.c e6d1e255bc951713f3f08b9f613fac2348211f61d181bb17e21865e3a653bd92
 F src/btree.h ddc9e4a17d3cf501f4d3d25b2a5bbdd15c464d457276bd98c5600f7c5f0607b9
-F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
+F src/btreeInt.h a16a409833ce532d9e3adc7abc74a303fc3ead191a60e97e4f08ae2f93d706a8
 F src/build.c 8581de0af3b6c448f5d64e2d18a91ac1e7057b3bcb8b8827e1240f80d87486a4
 F src/callback.c 3605bbf02bd7ed46c79cd48346db4a32fc51d67624400539c0532f4eead804ad
 F src/carray.c 3efe3982d5fb323334c29328a4e189ccaef6b95612a6084ad5fa124fd5db1179
@@ -1163,7 +1163,7 @@ F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d
 F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57
 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
-F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8
+F test/fts3corrupt4.test b0a69267a2a4aa76349364c9948ec5ad078562bce55675d6691563164e9ffbca
 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
 F test/fts3corrupt6.test 9ea944e3cd17a36c64451059022fabff53bd338a43356d1f49264ce8aa9477ad
 F test/fts3corrupt7.test 8564d278801a7947d1c74d8819adee7dfed18b81574d0c42f8a1acc6759fc65a
@@ -2200,11 +2200,9 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 7927329d25caab7f607c8857bc6b6fc56a9ba99fbd15087076a7983b2369b4eb
-Q +4247c5d9afb162a3e9f334b5121f0df2bfddb916054fa1e6fadb65b1983a7ed8
-Q +dae75754693143603c8fc9df3f0046dec3577e17a2858e877d238dd0f46899f4
-Q +dd0c161fcd1619518cd4671d64afb6afeec44c140ec176ccb8616d381a88f42f
-R ed61d53092abc225b0843853d792b3d6
+P 512d9449451c883a68a543f5ab8372b31324baf6216de7f71f7fc7589f2e1aab
+Q +942498724f5bb83b9a7d9bbbea662d152a46a0ccaee26e4b291f090cc6e7d178
+R 92a221b595cb4f6bdfd67a89ac6a3107
 U drh
-Z 8af0967ef593777dd5ea14bcfbf03b4b
+Z 346e1b4d1fc82104440a01c935b49eae
 # Remove this line to create a well-formed Fossil manifest.
index af4020c6d2152b581af9c8ddb00cb0361ee0aa95..2292167bc50b662b5da28b3e880ea454bae18cf3 100644 (file)
@@ -1 +1 @@
-512d9449451c883a68a543f5ab8372b31324baf6216de7f71f7fc7589f2e1aab
+1a888ea60be20a80e85a108a74dab0dd9faf72ca89389defeeb9c99ecafb3ea4
index 7cc3760cf67bd367a850148e787a4a49a13f50ac..049fe5c71793f842b52bf1ad5b17818311206807 100644 (file)
@@ -2138,8 +2138,12 @@ static int btreeComputeFreeSpace(MemPage *pPage){
       }
       next = get2byte(&data[pc]);
       size = get2byte(&data[pc+2]);
+      if( size<4 ){
+        /* Minimum freeblock size is 4 */
+        return SQLITE_CORRUPT_PAGE(pPage);
+      }
       nFree = nFree + size;
-      if( next<=pc+size+3 ) break;
+      if( next<pc+size+4 ) break;
       pc = next;
     }
     if( next>0 ){
@@ -11016,6 +11020,7 @@ static int checkTreePage(
       }
     }else{
       /* Populate the coverage-checking heap for leaf pages */
+      assert( heap[0] < pCheck->mxHeap );
       btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1));
     }
   }
@@ -11035,6 +11040,7 @@ static int checkTreePage(
         u32 size;
         pc = get2byteAligned(&data[cellStart+i*2]);
         size = pPage->xCellSize(pPage, &data[pc]);
+        assert( heap[0] < pCheck->mxHeap );
         btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
       }
     }
@@ -11051,6 +11057,7 @@ static int checkTreePage(
       assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */
       size = get2byte(&data[i+2]);
       assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */
+      assert( heap[0] < pCheck->mxHeap );
       btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
       /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
       ** big-endian integer which is the offset in the b-tree page of the next
@@ -11185,6 +11192,9 @@ int sqlite3BtreeIntegrityCheck(
     goto integrity_ck_cleanup;
   }
   sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
+#ifdef SQLITE_DEBUG
+  sCheck.mxHeap = pBt->pageSize/4 - 1;
+#endif
   if( sCheck.heap==0 ){
     checkOom(&sCheck);
     goto integrity_ck_cleanup;
index 17e3a1add55bcd3fc93019d88472d77e43c64633..e7be8268fe31391c9b683cb2c54b0e4f770adcd6 100644 (file)
@@ -714,6 +714,9 @@ struct IntegrityCk {
   u32 *heap;        /* Min-heap used for analyzing cell coverage */
   sqlite3 *db;      /* Database connection running the check */
   i64 nRow;         /* Number of rows visited in current tree */
+#ifdef SQLITE_DEBUG
+  u32 mxHeap;       /* Maximum number of entries in the Min-heap */
+#endif
 };
 
 /*
index 01effa085016fa3dd97fcff2202f8dd90db7e2ac..a23a24b4a569302b19937e8cec9cc4d5969d9876 100644 (file)
@@ -4159,7 +4159,7 @@ do_catchsql_test 24.5 {
 
 do_catchsql_test 24.7 {
   INSERT INTO t1(t1) SELECT x FROM t2;
-} {0 {}}
+} {1 {database disk image is malformed}}
 
 #-------------------------------------------------------------------------
 #-------------------------------------------------------------------------
@@ -5124,7 +5124,7 @@ do_catchsql_test 28.7 {
 
 do_catchsql_test 28.8 {
   INSERT INTO t1(t1) SELECT x FROM t2;
-} {0 {}}
+} {1 {database disk image is malformed}}
 
 #-------------------------------------------------------------------------
 #