DATA RACE 2: Found in sqlite3.c
(1) By Zu-Ming Jiang (jiang446079653) on 2020-04-29 03:32:30 [link] [source]
Dear SQLite developers:
I used my fuzz-testing tool, connzer, to detect data race in SQLite. Here is a data race found by connzer. I wish you can help me check whether it is a real race, thanks!!
The following is the race report.
Race report
Version: 3.30.1
Race object: pShmNode->pShmMutex
Thread 1:
Access: pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
Line number: sqlite3.c, 37258
Call stack:
unixOpenSharedMemory()
unixShmMap()
sqlite3OsShmMap()
walIndexPageRealloc()
walIndexPage()
walIndexReadHdr()
walTryBeginRead()
sqlite3WalBeginReadTransaction()
pagerBeginReadTransaction()
sqlite3PagerSharedLock()
lockBtree()
sqlite3BtreeBeginTrans()
sqlite3VdbeExec()
sqlite3Step()
sqlite3_step()
sqlite3_exec()
sql_script_x()
walthread2_thread()
launch_thread_main()
Lock: unixEnterMutex()
Thread 2:
Access: sqlite3_mutex_enter(pShmNode->pShmMutex);
Line number: sqlite3.c; 37305
Call stack:
unixOpenSharedMemory()
unixShmMap()
sqlite3OsShmMap()
walIndexPageRealloc()
walIndexPage()
walIndexReadHdr()
walTryBeginRead()
sqlite3WalBeginReadTransaction()
pagerBeginReadTransaction()
sqlite3PagerSharedLock()
lockBtree()
sqlite3BtreeBeginTrans()
sqlite3BtreeSetVersion()
sqlite3VdbeExec()
sqlite3Step()
sqlite3_step()
sqlite3_exec()
sql_script_x()
walthread2_thread()
launch_thread_main()
Lock: sqlite3_mutex_enter(pShmNode->pShmMutex)
Impact: This race may cause serious consequence: if the race access in thread 2 is executed before the race access in thread 1, pShmNode->pShmMutex
in unixOpenSharedMemory()
in thread 2 will be uninitialized, and sqlite3_mutex_enter(pShmNode->pShmMutex)
will cause crash.
My fuzzer finds that these 2 accesses can be executed concurrently, and they are protected by different locks, so my fuzzer report this race.
(2) By Zu-Ming Jiang (jiang446079653) on 2020-05-02 07:29:53 in reply to 1 [link] [source]
What do you think about this data race?
(3) By Richard Hipp (drh) on 2020-05-02 11:24:17 in reply to 2 [link] [source]
Your analysis is incorrect.
This is no code path that reaches line sqlite3.c:37305 with pShmNode->pShmMutex uninitialized in a thread-safe build. Every path to sqlite3.c:37305 must traverse this code:
unixEnterMutex();
pInode = pDbFd->pInode;
pShmNode = pInode->pShmNode;
if( pShmNode==0 ){
/*...*/
if( sqlite3GlobalConfig.bCoreMutex ){
pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
}
/*...*/
}
unixLeaveMutex();
Assuming the sqlite3GlobalConfig.bCoreMutex
global variable is true,
that means that pShmNode->pShmMutex
must be initialized prior to use.
Your tool is perhaps confused because it assumes that
sqlite3GlobalConfig.bCoreMutex
might be false. But that is only
true if SQLite is running in "single-threaded mode".
I suppose your tool is technically correct - there is a data race if you have configured SQLite for single-threaded mode. But that does not really count, since the documentation clearly states that in single-threaded mode, SQLite is not threadsafe.
(4) By Zu-Ming Jiang (jiang446079653) on 2020-05-03 02:00:03 in reply to 3 [source]
Yes, you are right.
Thanks for your response!!