From 6553a5d6a69bcfd261d1055dfd86f37b7b851e27 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Sep 2025 11:45:13 +0000 Subject: [PATCH] Fix some integer overflow problems when handling corrupt hexdb dumps in the shell tool. [forum:/forumpost/82b513b116 | Forum post 82b513b116]. FossilOrigin-Name: 730323f95d126162fd2867dbee1e1f1fc1d6e05b8a905a6767c4ab1cb43dacff --- manifest | 17 +++++---- manifest.uuid | 2 +- src/shell.c.in | 25 ++++++------- test/shell2.test | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 0d50d1be64..2c932d7751 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stable-valued\sfunctions\sjsonb_each()\sand\sjsonb_tree()\sthat\swork\sjust\nlike\sjson_each()\sand\sjson_tree()\sexcept\sthat\sthe\s"value"\scolumn\sis\sJSONB\ninstead\sof\sJSON\stext\swhen\sthe\s"type"\sis\s'object'\sor\s'array'. -D 2025-09-26T11:36:10.296 +C Fix\ssome\sinteger\soverflow\sproblems\swhen\shandling\scorrupt\shexdb\sdumps\sin\sthe\sshell\stool.\s[forum:/forumpost/82b513b116\s|\sForum\spost\s82b513b116]. +D 2025-09-26T11:45:13.976 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -738,7 +738,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c f8d1d011aba0964ff1bdccd049d4d2c2fec217efd90d202a4bb775e926b2c25d F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c b95181711d59c36d9789e67f76c4cfec64b99f9629a50be5e6566e117b87d957 -F src/shell.c.in 175630658a5fce0277cddf4991c56931ed061b3af36061be3e56ef113588452f +F src/shell.c.in 3b3782d9143eb54a9acf66bc48e0ba459c226a646076f4090ece9b9860204c6e F src/sqlite.h.in 5732519a2acb09066032ceac21f25996eb3f28f807a4468e30633c7c70faae1c F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 3f0c4ed6934e7309a61c6f3c30f70a30a5b869f785bb3d9f721a36c5e4359126 @@ -1601,7 +1601,7 @@ F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test d41257103cf762e1d43f1d07286ac65ed32c5430a19851029bfe06671f5e19fe -F test/shell2.test ac102ebc0a9ec166257600c4ee8bdefec242163afced295f10b004f4af3fc9dd +F test/shell2.test ab23f01ea2347e4b72bb2399af7ee82aa00f9c059141749f7c4064abca5ad728 F test/shell3.test 603b448e917537cf77be0f265c05c6f63bc677c63a533c8e96aae923b56f4a0e F test/shell4.test ad7eee983b5e7f1dd92d8c87bc0f39474086bc32c980c00f3934c54aabc636a2 F test/shell5.test d17e7927ab8b7f720efbdd9b5d05fceb6c3c56c25917901b315400214bf24ef4 @@ -2170,9 +2170,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P df9ab8a35517e3a2baf4b19d07d46ce3f8b48043ccdeadef22bffc12e80461c3 c50a3c45a20e5b9d48e749818bea06dfa99b729535e0617347c6ece1d277a447 -R 31c139330d7eefdf010cffbd7465fd3c -T +closed c50a3c45a20e5b9d48e749818bea06dfa99b729535e0617347c6ece1d277a447 -U drh -Z fd0622101369a3b80a24218729fa1f33 +P dfc41cb3aad7fedd834baaaba0d8e3aeb55a249af4f0934397652ea9c59dc9fc +R bfd736fdadafc7a2e091ac2f8e9afb8f +U dan +Z 38301d6866f451ade983b3377617b51b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cada5560b7..d3cf5bdbc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfc41cb3aad7fedd834baaaba0d8e3aeb55a249af4f0934397652ea9c59dc9fc +730323f95d126162fd2867dbee1e1f1fc1d6e05b8a905a6767c4ab1cb43dacff diff --git a/src/shell.c.in b/src/shell.c.in index fc315d07e5..d7f11c9737 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5644,10 +5644,10 @@ int deduceDatabaseType(const char *zName, int dfltZip){ static unsigned char *readHexDb(ShellState *p, int *pnData){ unsigned char *a = 0; int nLine; - int n = 0; + int n = 0; /* Size of db per first line of hex dump */ + i64 sz = 0; /* n rounded up to nearest page boundary */ int pgsz = 0; - int iOffset = 0; - int j, k; + i64 iOffset = 0; int rc; FILE *in; const char *zDbFilename = p->pAuxDb->zDbFilename; @@ -5671,16 +5671,17 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<0 ) goto readHexDb_error; - if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; - n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ - a = sqlite3_malloc( n ? n : 1 ); - shell_check_oom(a); - memset(a, 0, n); if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ sqlite3_fputs("invalid pagesize\n", stderr); goto readHexDb_error; } + sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */ + a = sqlite3_malloc( sz ? sz : 1 ); + shell_check_oom(a); + memset(a, 0, sz); for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ + int j = 0; /* Page number from "| page" line */ + int k = 0; /* Offset from "| page" line */ rc = sscanf(zLine, "| page %d offset %d", &j, &k); if( rc==2 ){ iOffset = k; @@ -5693,14 +5694,14 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); if( rc==17 ){ - k = iOffset+j; - if( k+16<=n && k>=0 ){ + i64 iOff = iOffset+j; + if( iOff+16<=sz && iOff>=0 ){ int ii; - for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; + for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff; } } } - *pnData = n; + *pnData = sz; if( in!=p->in ){ fclose(in); }else{ diff --git a/test/shell2.test b/test/shell2.test index 3f9fec9efa..5f700a9a1d 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -276,5 +276,97 @@ do_test shell2-1.4.12 { .sha3sum}]] } {0 ca08bc02b7e95c7df431a3a4b1cc0f8d8743914793473f55b5558e03} +#------------------------------------------------------------------------- + +foreach {tn hexdump expect} { + 0 { +| size 8192 pagesize 4096 filename my.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 03 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| 96: 00 2e 8d f8 0d 00 00 00 01 0f df 00 0f df 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1f ................ +| 4064: 01 06 17 0f 0f 01 2f 74 61 62 6c 65 74 74 02 43 ....../tablett.C +| 4080: 52 45 41 54 45 20 54 41 42 4c 45 20 74 28 78 29 REATE TABLE t(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 02 0f ee 00 0f f7 0f ee 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 02 ................ +| 4080: 02 17 77 6f 72 6c 64 07 01 02 17 68 65 6c 6c 6f ..world....hello +| end my.db + } + {0 {}} + + 1 { +| size 2147483647 pagesize 4096 filename my.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 03 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| 96: 00 2e 8d f8 0d 00 00 00 01 0f df 00 0f df 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1f ................ +| 4064: 01 06 17 0f 0f 01 2f 74 61 62 6c 65 74 74 02 43 ....../tablett.C +| 4080: 52 45 41 54 45 20 54 41 42 4c 45 20 74 28 78 29 REATE TABLE t(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 02 0f ee 00 0f f7 0f ee 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 02 ................ +| 4080: 02 17 77 6f 72 6c 64 07 01 02 17 68 65 6c 6c 6f ..world....hello +| end my.db + } + {1 {Error: out of memory}} + + 2 { +| size 8192 pagesize 4096 filename my.db +| page 1 offset 2147483647 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 03 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| 96: 00 2e 8d f8 0d 00 00 00 01 0f df 00 0f df 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1f ................ +| 4064: 01 06 17 0f 0f 01 2f 74 61 62 6c 65 74 74 02 43 ....../tablett.C +| 4080: 52 45 41 54 45 20 54 41 42 4c 45 20 74 28 78 29 REATE TABLE t(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 02 0f ee 00 0f f7 0f ee 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 02 ................ +| 4080: 02 17 77 6f 72 6c 64 07 01 02 17 68 65 6c 6c 6f ..world....hello +| end my.db + } + {0 {}} + + 3 { +| size 8192 pagesize 4096 filename my.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 03 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| 96: 00 2e 8d f8 0d 00 00 00 01 0f df 00 0f df 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1f ................ +| 4064: 01 06 17 0f 0f 01 2f 74 61 62 6c 65 74 74 02 43 ....../tablett.C +| 4080: 52 45 41 54 45 20 54 41 42 4c 45 20 74 28 78 29 REATE TABLE t(x) +| page 2 offset 4096 +| 2147483647: 0d 00 00 00 02 0f ee 00 0f f7 0f ee 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 02 ................ +| 4080: 02 17 77 6f 72 6c 64 07 01 02 17 68 65 6c 6c 6f ..world....hello +| end my.db +} + {0 {}} + +} { + set fd [open dump.txt w] + puts $fd [string trim $hexdump] + close $fd + do_test shell2-2.$tn.1 { + set rc [ catchcmd "" ".open --hexdb dump.txt"] + } $expect +} + finish_test -- 2.47.3