From e5fba7f09453cde794827a65508ba94fc4514f97 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 14 Jan 2026 13:43:32 +0000 Subject: [PATCH] Guard against oversized index entries in databases larger than 2GiB. FossilOrigin-Name: ed17a878e5a2e0cd1e9b69d528f5ac2ba8452d7c83deaf3cc72ecbff054f5ca3 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btree.c | 2 +- src/malloc.c | 24 +----------------------- src/sqliteLimit.h | 21 +++++++++++++++++++++ src/vdbeapi.c | 2 +- src/vdbemem.c | 7 ++++++- test/corruptL.test | 2 +- 8 files changed, 43 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index 55548438f8..209ed95f43 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sinteger\soverflow\sproblems\sand\serror\sreporting\smemory\sleaks\sin\nthe\szipfile\sextension.\n[forum:/forumpost/2026-01-13T00:09:06Z|Forum\spost\s2026-01-13T00:09:06Z]. -D 2026-01-13T02:35:19.807 +C Guard\sagainst\soversized\sindex\sentries\sin\sdatabases\slarger\sthan\s2GiB. +D 2026-01-14T13:43:32.416 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -677,7 +677,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 8850125300b9780fa54bc45a41af88eb2796b90f2f97942279094beef9b0e971 +F src/btree.c 917b0a802af5b89705f599d9ab2e291276b8409518597893ad9449ceb5c39ee1 F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 4e1afafc56504ed6253e1b115c1502de4243c2287a0c799f4967fcd2d7716ad9 @@ -702,7 +702,7 @@ F src/json.c fb031340edee159c07ad37dbe668ffe945ed86f525b0eb3822e4a67cbc498a72 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d6559d2b39c9bde6b104b83adeafbe5db3a514aae4d3d40afc58de522a03043b F src/main.c 21fb86045bbf6b6329251a0ce6771735b6c71287cc9fcda1f2005d4ac5f25b52 -F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e +F src/malloc.c 422f7e0498e1c9ef967f06283b6f2c0b16db6b905d8e06f6dbc8baaa3e4e6c5a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 @@ -743,7 +743,7 @@ F src/sqlite.h.in 476f3efeb5dd26ad94dcbce262ca7eb9d042d797a92d624059c67ef37d5b3a F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h f590cd8cb4c36fc727632c9b5fbbafc85f7efe2c6890f9958d7e711dc26ec01e F src/sqliteInt.h af67bc95fa6b66cd3c7f3d18d2d040ad386e4cbb02965ee318cc721ee9d5fa45 -F src/sqliteLimit.h 7e705474d59912388832cc5465edbc0dbb552872e23452812846e90d280987f3 +F src/sqliteLimit.h 904a3f520362c7065c18165aaabd504fb13cc1b76cb411f38bd41ac219e4af1e F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 85b5a20df96016e5d1d8fdc68c8a4c279c5b93e2049b77cd806c2cc50b9d8c56 @@ -807,10 +807,10 @@ F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82 F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964 F src/vdbe.h 966d0677a540b7ea6549b7c4e1312fc0d830fce3a235a58c801f2cc31cf5ecf9 F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49 -F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938 +F src/vdbeapi.c c7c8477fa2d4fca015a0b1d555f771153ebf088c8e4b7ca878d31bd974cf0735 F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692 -F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021 +F src/vdbemem.c fdd023e357ad3129e1dcae46df47fccceeb8bd1ffa6c5d43a1e3f04460bb59b7 F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70 F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 @@ -1006,7 +1006,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 9d8cbf6214e492abe9e822e759b9751ae336cec0a6fe3ff3b37bfbd8ff9c22ca F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test ac13504593d89d69690d45479547616ed12644d42b5cb7eeb2e759a76fc23dcb -F test/corruptL.test 652fc8ac0763a6fd3eb28b951d481924167b2d9936083bcc68253b2274a0c8fe +F test/corruptL.test f15de2b4729c0851ea89916a26766b094d74bac79f9f9f2b0191935aa3b344c9 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test a034bb217bebd8d007625dfb078e76ec3d53515052dbceb68bd47b2c27674d5c F test/cost.test cc434a026b1e9d0d98137a147e24e5daf1b1ad09e9ff7da63b34c83ddd136d92 @@ -2191,8 +2191,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 3c46295487f089a891f566cae43b67ce97794bb60645d5806285600e05eff456 -R c623b963bbca2289b18e8c5d97b1c493 +P 8e656a483557bc5385219d560b9155c232e7dc9d62642249abc879fb37bacd2a +R e4a21a4b0c8374195b8c7e4077a8aa5c U drh -Z a89509cb585e252fe4fa68c4af455284 +Z 3811ba8eb57fe99f7ac42f617514bf6f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4e98151349..1b6d714e0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e656a483557bc5385219d560b9155c232e7dc9d62642249abc879fb37bacd2a +ed17a878e5a2e0cd1e9b69d528f5ac2ba8452d7c83deaf3cc72ecbff054f5ca3 diff --git a/src/btree.c b/src/btree.c index a3cbc6e3f8..67e78035da 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5144,7 +5144,7 @@ static int accessPayload( getCellInfo(pCur); aPayload = pCur->info.pPayload; - assert( offset+amt <= pCur->info.nPayload ); + assert( (u64)offset+(u64)amt <= (u64)pCur->info.nPayload ); assert( aPayload > pPage->aData ); if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ diff --git a/src/malloc.c b/src/malloc.c index 9a635e7162..942934644b 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -289,27 +289,6 @@ static void mallocWithAlarm(int n, void **pp){ *pp = p; } -/* -** Maximum size of any single memory allocation. -** -** This is not a limit on the total amount of memory used. This is -** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). -** -** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 -** This provides a 256-byte safety margin for defense against 32-bit -** signed integer overflow bugs when computing memory allocation sizes. -** Paranoid applications might want to reduce the maximum allocation size -** further for an even larger safety margin. 0x3fffffff or 0x0fffffff -** or even smaller would be reasonable upper bounds on the size of a memory -** allocations for most applications. -*/ -#ifndef SQLITE_MAX_ALLOCATION_SIZE -# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 -#endif -#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 -# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 -#endif - /* ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. @@ -533,8 +512,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){ sqlite3_free(pOld); /* IMP: R-26507-47431 */ return 0; } - if( nBytes>=0x7fffff00 ){ - /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + if( nBytes>SQLITE_MAX_ALLOCATION_SIZE ){ return 0; } nOld = sqlite3MallocSize(pOld); diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index ea49d6ba05..ecbd0858ef 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -25,6 +25,27 @@ #endif #define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ +/* +** Maximum size of any single memory allocation. +** +** This is not a limit on the total amount of memory used. This is +** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). +** +** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 +** This provides a 256-byte safety margin for defense against 32-bit +** signed integer overflow bugs when computing memory allocation sizes. +** Paranoid applications might want to reduce the maximum allocation size +** further for an even larger safety margin. 0x3fffffff or 0x0fffffff +** or even smaller would be reasonable upper bounds on the size of a memory +** allocations for most applications. +*/ +#ifndef SQLITE_MAX_ALLOCATION_SIZE +# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 +#endif +#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 +# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 +#endif + /* ** This is the maximum number of ** diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f1a195ff40..844d2f75c1 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1045,7 +1045,7 @@ static int valueFromValueList( Mem sMem; /* Raw content of current row */ memset(&sMem, 0, sizeof(sMem)); sz = sqlite3BtreePayloadSize(pRhs->pCsr); - rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,sz,&sMem); if( rc==SQLITE_OK ){ u8 *zBuf = (u8*)sMem.z; u32 iSerial; diff --git a/src/vdbemem.c b/src/vdbemem.c index 2c4d1c5681..144f889363 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1277,7 +1277,12 @@ int sqlite3VdbeMemFromBtree( ){ int rc; pMem->flags = MEM_Null; - if( sqlite3BtreeMaxRecordSize(pCur)=SQLITE_MAX_ALLOCATION_SIZE ){ + return SQLITE_NOMEM_BKPT; + } + if( (u64)amt + (u64)offset > (u64)sqlite3BtreeMaxRecordSize(pCur) ){ return SQLITE_CORRUPT_BKPT; } if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ diff --git a/test/corruptL.test b/test/corruptL.test index 52adf6fd72..8e3dd60124 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -234,7 +234,7 @@ do_execsql_test 2.1 { do_catchsql_test 2.2 { SELECT b,c FROM t1 ORDER BY a; -} {1 {database disk image is malformed}} +} {1 {out of memory}} #------------------------------------------------------------------------- reset_db -- 2.47.3