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.
This commit is contained in:
Mounir IDRASSI
2026-09-26 05:24:34 +02:00
parent 1b9be65296
commit ff81ade403
3 changed files with 25 additions and 0 deletions
+14
View File
@@ -823,6 +823,12 @@ namespace VeraCrypt
uint64 FuseService::Mount (shared_ptr <Volume> 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 <string> 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));
+3
View File
@@ -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)); }
+8
View File
@@ -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());