From ff81ade4033f1174d4d960996c7bb542b8acb392 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 26 Sep 2026 05:18:37 +0200 Subject: [PATCH] macOS: prevent descriptor leaks into FUSE backends Set FD_CLOEXEC on the backing file and signal pipe write descriptor before launching the backend. This avoids retained volume handles and delayed signal handler exit. Apply the change only to the macOS FUSE-T path. --- src/Driver/Fuse/FuseService.cpp | 14 ++++++++++++++ src/Platform/File.h | 3 +++ src/Platform/Unix/File.cpp | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index 2df69514..812f6e87 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -823,6 +823,12 @@ namespace VeraCrypt uint64 FuseService::Mount (shared_ptr openVolume, VolumeSlotNumber slotNumber, const string &fuseMountPoint) { +#if defined(TC_MACOSX) && defined(VC_MACOSX_FUSET) + // Keep the descriptor in the service across fork, but do not let exec'd + // helpers retain the backing file after the service exits. + openVolume->GetFile()->SetCloseOnExec(); +#endif + list args; args.push_back (FuseService::GetDeviceType()); args.push_back (fuseMountPoint); @@ -1079,7 +1085,15 @@ namespace VeraCrypt _exit (0); } +#if defined(TC_MACOSX) && defined(VC_MACOSX_FUSET) + // Keep the backend from delaying EOF when the service exits. + int signalPipeWriteFd = SignalHandlerPipe->GetWriteFD(); + int signalPipeFlags = fcntl (signalPipeWriteFd, F_GETFD); + throw_sys_if (signalPipeFlags == -1); + throw_sys_if (fcntl (signalPipeWriteFd, F_SETFD, signalPipeFlags | FD_CLOEXEC) == -1); +#else SignalHandlerPipe->GetWriteFD(); +#endif #if defined(TC_MACOSX) && defined(VC_MACOSX_FUSET) _exit (fuse_service_main (argc, argv, &fuse_service_oper)); diff --git a/src/Platform/File.h b/src/Platform/File.h index 6fd6d889..39b79bd7 100644 --- a/src/Platform/File.h +++ b/src/Platform/File.h @@ -87,6 +87,9 @@ namespace VeraCrypt uint64 ReadAt (const BufferPtr &buffer, uint64 position) const; void SeekAt (uint64 position) const; void SeekEnd (int ofset) const; +#ifndef TC_WINDOWS + void SetCloseOnExec (); +#endif void SetLength (uint64 length) const; void Write (const ConstBufferPtr &buffer) const; void Write (const ConstBufferPtr &buffer, size_t length) const { Write (buffer.GetRange (0, length)); } diff --git a/src/Platform/Unix/File.cpp b/src/Platform/Unix/File.cpp index 98108afd..c1eb3461 100644 --- a/src/Platform/Unix/File.cpp +++ b/src/Platform/Unix/File.cpp @@ -412,6 +412,14 @@ namespace VeraCrypt throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path)); } + void File::SetCloseOnExec () + { + if_debug (ValidateState()); + int flags = fcntl (FileHandle, F_GETFD); + throw_sys_sub_if (flags == -1, wstring (Path)); + throw_sys_sub_if (fcntl (FileHandle, F_SETFD, flags | FD_CLOEXEC) == -1, wstring (Path)); + } + void File::SetLength (uint64 length) const { if_debug (ValidateState());