mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-09-26 01:44:53 +00:00
macOS: initialize PC/SC lazily to keep fork() children clean (#1887)
SCard::manager is a static object whose constructor called
SCardLoader::Initialize(), which establishes a PC/SC context before
main() in every VeraCrypt process. On macOS this opens an XPC
connection that starts a helper thread and marks libdispatch as
fork-unsafe.
As a result, CoreService::Start() forked a multithreaded process, and
the FUSE service (which libfuse runs after fork() without exec())
inherited armed Objective-C fork-safety checks and poisoned dispatch
queues. With macFUSE >= 5.3.3 this causes:
- a SIGABRT when mounting ("+[NSNumber initialize] may have been in
progress in another thread when fork() was called"), and
- a SIGSEGV in MFChannelClose/dispatch_channel_cancel at unmount.
Load the PC/SC library on first use instead: GetReaders() now calls
loader->Initialize() itself (GetReader() already did, and Initialize()
is idempotent). PC/SC is then only touched when EMV keyfiles are used,
and never in the core service or FUSE service processes.
Tested on macOS 27.0 (arm64) with macFUSE 5.4.0: 30/30 mount/write/
remount/verify/dismount cycles with no crash reports. Previously every
mount failed.
Refs #1884, #1863, macfuse/macfuse#1193
Assisted-by: Claude Opus 5.5
This commit is contained in:
@@ -7,9 +7,13 @@ namespace VeraCrypt
|
||||
|
||||
SCardManager::SCardManager()
|
||||
{
|
||||
#ifndef TC_OPENBSD
|
||||
loader->Initialize();
|
||||
#endif
|
||||
// The PC/SC library is loaded lazily on first use (see GetReaders/GetReader).
|
||||
// SCardManager instances are static objects, so initializing here would run
|
||||
// before main(). On macOS, establishing a PC/SC context opens an XPC connection,
|
||||
// which starts a helper thread and marks libdispatch as fork-unsafe. The core
|
||||
// service fork() would then happen in a multithreaded process, and the FUSE
|
||||
// service (which libfuse runs after fork() without exec()) would inherit
|
||||
// poisoned dispatch queues and armed Objective-C fork-safety checks.
|
||||
}
|
||||
|
||||
SCardManager::~SCardManager()
|
||||
@@ -28,6 +32,8 @@ namespace VeraCrypt
|
||||
SCARDCONTEXT hScardContext = 0;
|
||||
LONG lRet = SCARD_S_SUCCESS;
|
||||
|
||||
loader->Initialize();
|
||||
|
||||
hScardContext = loader->GetSCardContext();
|
||||
lRet = loader->SCardIsValidContext(hScardContext);
|
||||
if (SCARD_S_SUCCESS != lRet)
|
||||
|
||||
Reference in New Issue
Block a user