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:
15
manifest
15
manifest
@@ -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.
|
||||
|
||||
@@ -1 +1 @@
|
||||
7bfd5c810c6f04ddfd275457a2a03b4da0c3e7d4ee5acb61a54d805e2e67f819
|
||||
6ba9e19430092aef59f2a7ab6fb7bdacacbb85988f41c155a5af490b0d8a8270
|
||||
|
||||
94
src/pager.c
94
src/pager.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user