From: dan Date: Mon, 13 Aug 2018 12:58:48 +0000 (+0000) Subject: Fix a heap-corruption causing race condition in os_unix.c that could occur X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Funix-lock-fix-attempt;p=thirdparty%2Fsqlite.git Fix a heap-corruption causing race condition in os_unix.c that could occur when one thread wal opening a database file while another is unlocking the same file. FossilOrigin-Name: 2447e0fd9830b4de9feeb178a0bff67a9065e3072120d4453bcdd3950d681adb --- diff --git a/manifest b/manifest index 8ba0325163..dd9d9449e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\scomment\son\sthe\sunix-nolock\sVFS\sobject.\s\sNo\sfunctional\ncode\schanges. -D 2018-08-13T11:32:07.332 +C Fix\sa\sheap-corruption\scausing\srace\scondition\sin\sos_unix.c\sthat\scould\soccur\nwhen\sone\sthread\swal\sopening\sa\sdatabase\sfile\swhile\sanother\sis\sunlocking\sthe\nsame\sfile. +D 2018-08-13T12:58:48.124 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6 @@ -482,7 +482,7 @@ F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c 4723f4d963c032b5162dd6de79c314c2f67bccfeea2e458aaefa0f3049877f2e +F src/os_unix.c c8487c06ce047779d992d2f9147a372049b697a15b4fb9bbce16fab82fe78b2c F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 76d29b8a960dcb8b67210f095899d91e4a90673a6674ea58cfd1115b705a7fb9 @@ -1754,7 +1754,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4195a3f8b5d2c2ec63771890c5aa7b5e2de60b9fa2273652730239b8577ae418 -R dc8601ab971a0e9f35b0830adc99e5ec -U drh -Z 8549fb1e42f4bc7f9d102f40d2b9a827 +P 90f7c193b42f0d8120a8e429bdea5e1cec5d3f45b901db8fc5a5c2ca3e69cba8 +R c32540ea6b445bf71ef28da5133ef44f +U dan +Z e5c617af6463d8e8b140183e45df28af diff --git a/manifest.uuid b/manifest.uuid index e2b587ab47..7df9b1b311 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90f7c193b42f0d8120a8e429bdea5e1cec5d3f45b901db8fc5a5c2ca3e69cba8 \ No newline at end of file +2447e0fd9830b4de9feeb178a0bff67a9065e3072120d4453bcdd3950d681adb \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index c6df7020a2..1717db338e 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -714,6 +714,9 @@ static void unixLeaveMutex(void){ static int unixMutexHeld(void) { return sqlite3_mutex_held(unixBigLock); } +static int unixMutexNotheld(void) { + return sqlite3_mutex_notheld(unixBigLock); +} #endif @@ -1249,7 +1252,7 @@ static void storeLastErrno(unixFile *pFile, int error){ /* ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. */ -static void closePendingFds(unixFile *pFile){ +static void closePendingFdsUnsafe(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; @@ -1262,6 +1265,12 @@ static void closePendingFds(unixFile *pFile){ pInode->pUnused = 0; } +static void closePendingFds(unixFile *pFile){ + unixEnterMutex(); + closePendingFdsUnsafe(pFile); + unixLeaveMutex(); +} + /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** @@ -1275,7 +1284,7 @@ static void releaseInodeInfo(unixFile *pFile){ pInode->nRef--; if( pInode->nRef==0 ){ assert( pInode->pShmNode==0 ); - closePendingFds(pFile); + closePendingFdsUnsafe(pFile); if( pInode->pPrev ){ assert( pInode->pPrev->pNext==pInode ); pInode->pPrev->pNext = pInode->pNext; @@ -1458,6 +1467,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ assert( pFile ); assert( pFile->eFileLock<=SHARED_LOCK ); + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ @@ -1670,6 +1680,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* @@ -1862,6 +1873,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ return SQLITE_OK; } pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ @@ -2793,6 +2805,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ *pResOut = 1; return SQLITE_OK; } + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ @@ -2881,6 +2894,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* @@ -3050,6 +3064,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { return SQLITE_OK; } pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){