1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-10-23 21:49:02 +03:00

Check super-journal names for validity earlier, as this simplifies

verification that the logic is correct.

FossilOrigin-Name: 6ba9e19430092aef59f2a7ab6fb7bdacacbb85988f41c155a5af490b0d8a8270
This commit is contained in:
drh
2026-06-25 20:26:17 +00:00
parent 426c44c0a4
commit 02ea41d524
3 changed files with 59 additions and 52 deletions

View File

@@ -1,5 +1,5 @@
C Have\sAPI\sfunctions\ssqlite3_serialize,\ssqlite3_limit,\ssqlite3_busy_timeout,\ssqlite3_error_offset,\ssqlite3_db_name,\ssqlite3_get_autocommit,\ssqlite3_errcode,\ssqlite3_total_changes64,\ssqlite3_changes64,\ssqlite3_last_insert_rowid\sand\ssqlite3_expired\stake\sand\shold\sthe\sdatabase\smutex\swhile\srunning.
D 2026-06-25T17:07:53.090
C Check\ssuper-journal\snames\sfor\svalidity\searlier,\sas\sthis\ssimplifies\nverification\sthat\sthe\slogic\sis\scorrect.
D 2026-06-25T20:26:17.638
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -725,7 +725,7 @@ F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae
F src/os_unix.c 83759942d1ea8d59daed50901c123016f845fada74caf3496b8a2537c9a08838
F src/os_win.c 1227a3e962b017d676d985a8aec0d64f273991931ea0a0b99773651102f62df4
F src/os_win.h c06ccc3a090cf54202ea58981c298817f3309d4c9e4d52ad0a02927346493721
F src/pager.c 927713c6cc3033268f2c440f3ccc45081266fe956e018ce6c04092f1776215e7
F src/pager.c 678ee3b68638ee427cc1b071b11181d0f2a827f6cb4d6ec7c12d5fa5f6a752d0
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
F src/parse.y d5a3c5b0277a441c38b35071c05e2b61ff5fc918a63309c809f4b6706179c320
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
@@ -2208,9 +2208,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P c30ea3cefe346a3d87b57710a51b059371543c5abc75d08c4ca827bbe3b3f622 46509e48d3049a1ca52d9cc3f023634a651cd633d36bd9056ca0172759ba201e
R bf72fafaea2070ac4d3be5ad21ee93ea
T +closed 46509e48d3049a1ca52d9cc3f023634a651cd633d36bd9056ca0172759ba201e
U dan
Z 8ba48b9154271fe0d84b01609d2c1867
P 7bfd5c810c6f04ddfd275457a2a03b4da0c3e7d4ee5acb61a54d805e2e67f819
R fcb35e9d64943876915ecd53a38bf408
U drh
Z a532ffc4f25f92a370d40bff92615b32
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
7bfd5c810c6f04ddfd275457a2a03b4da0c3e7d4ee5acb61a54d805e2e67f819
6ba9e19430092aef59f2a7ab6fb7bdacacbb85988f41c155a5af490b0d8a8270

View File

@@ -1280,6 +1280,41 @@ static void freeSuperJournal(char *zSuper){
}
}
/*
** Check if zSuper is a valid super-journal name. There are two valid
** formats:
**
** + The 3rd and 4th last bytes of the filename are ".9", and the
** following 2 bytes are hex digits. This is a file created in 8.3
** filenames mode.
**
** + The 3rd last byte of the filename is "9" and the filename
** contains the string "-mj" starting at the 12th last byte.
** All bytes following the "-mj" are hex digits.
**
** If the filename matches either of these patterns, return non-zero.
** Otherwise, return zero.
*/
static int pagerIsSuperJrnlName(const char *zSuper){
const int nSuper = sqlite3Strlen30(zSuper);
int ii;
#ifdef SQLITE_ENABLE_8_3_NAMES
if( nSuper<4 ) return 0;
if( zSuper[nSuper-3]!='9' ) return 0;
if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0;
if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0;
if( zSuper[nSuper-4]=='.' ) return 1;
#endif
if( nSuper<12 ) return 0;
if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0;
if( zSuper[nSuper-3]!='9' ) return 0;
for(ii=nSuper-9; ii<nSuper; ii++){
if( sqlite3Isxdigit(zSuper[ii])==0 ) return 0;
}
return 1;
}
/*
** Parameter pJrnl is a file-handle open on a journal file. This function
** attempts to read a super-journal file name from the end of the journal
@@ -1317,14 +1352,13 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
|| len==0
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
|| memcmp(aMagic, aJournalMagic, 8)
){
return rc;
}
zOut = (char*)sqlite3MallocZero(4 + len + 2);
if( !zOut ){
rc = SQLITE_NOMEM_BKPT;
rc = memcmp(aMagic,aJournalMagic,8) ? SQLITE_OK : SQLITE_NOMEM_BKPT;
}else{
zOut = &zOut[4];
if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){
@@ -1334,11 +1368,14 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
cksum -= zOut[u];
}
}
if( rc!=SQLITE_OK || cksum ){
/* If the checksum doesn't add up, then one or more of the disk sectors
** containing the super-journal filename is corrupted. This means
** definitely roll back, so just return SQLITE_OK and report a (nul)
** super-journal filename. */
if( rc!=SQLITE_OK /* Couldn't read the name */
|| !pagerIsSuperJrnlName(zOut) /* Name is not valid */
|| cksum /* checksum is incorrect */
|| memcmp(aMagic, aJournalMagic, 8)!=0 /* Bad magic number */
){
/* If any validity checks fail, that means the super-journal filename
** is corrupted, so rollback. Return SQLITE_K and a NULL super-journal
** name */
freeSuperJournal(zOut);
zOut = 0;
}
@@ -1721,6 +1758,7 @@ static int writeSuperJournal(Pager *pPager, const char *zSuper){
assert( pPager->setSuper==0 );
assert( !pagerUseWal(pPager) );
assert( zSuper==0 || pagerIsSuperJrnlName(zSuper) );
if( !zSuper
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
@@ -2499,40 +2537,6 @@ static int pager_playback_one_page(
return rc;
}
/*
** Check if zSuper is a valid super-journal name. There are two valid
** formats:
**
** + The 3rd and 4th last bytes of the filename are ".9", and the
** following 2 bytes are hex digits. This is a file created in 8.3
** filenames mode.
**
** + The 3rd last byte of the filename is "9" and the filename
** contains the string "-mj" starting at the 12th last byte.
** All bytes following the "-mj" are hex digits.
**
** If the filename matches either of these patterns, return non-zero.
** Otherwise, return zero.
*/
static int pagerIsSuperJrnlName(const char *zSuper){
const int nSuper = sqlite3Strlen30(zSuper);
int ii;
if( nSuper<4 ) return 0;
if( zSuper[nSuper-3]!='9' ) return 0;
#ifdef SQLITE_ENABLE_8_3_NAMES
if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0;
if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0;
if( zSuper[nSuper-4]=='.' ) return 1;
#endif
if( nSuper<12 ) return 0;
if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0;
for(ii=nSuper-9; ii<nSuper; ii++){
if( sqlite3Isxdigit(zSuper[ii])==0 ) return 0;
}
return 1;
}
/*
** Parameter zSuper is the name of a super-journal file. A single journal
** file that referred to the super-journal file has just been rolled back.
@@ -2590,8 +2594,12 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
/* Check if this looks like a real super-journal name. If it does not,
** return SQLITE_OK without attempting to delete it. This is to limit
** the degree to which a crafted journal file can be used to cause
** SQLite to delete arbitrary files. */
if( pagerIsSuperJrnlName(zSuper)==0 ){
** SQLite to delete arbitrary files.
**
** This test never fails, becaue the super journal name is checked
** by readSuperJournal().
*/
if( NEVER(pagerIsSuperJrnlName(zSuper)==0) ){
return SQLITE_OK;
}