mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-21 21:30:48 -05:00
macOS: prepare APFS formatter device aliases
When creating an APFS filesystem inside a newly created device-hosted volume, VeraCrypt prepared only the raw hdiutil device path before invoking newfs_apfs. On macOS, newfs_apfs may resolve or reopen the corresponding block device path, which can fail with Permission denied for non-root GUI runs. Prepare both raw and block aliases for the temporary formatter device, restore changed owners afterward, and share the helper between GUI and text-mode volume creation. Restore each changed alias independently so one restore failure does not skip the rest.
This commit is contained in:
@@ -22,6 +22,9 @@
|
|||||||
#include "Core/VolumeCreator.h"
|
#include "Core/VolumeCreator.h"
|
||||||
#include "Main/Application.h"
|
#include "Main/Application.h"
|
||||||
#include "Main/GraphicUserInterface.h"
|
#include "Main/GraphicUserInterface.h"
|
||||||
|
#ifdef TC_MACOSX
|
||||||
|
#include "Main/MacOSXFormatterDevice.h"
|
||||||
|
#endif
|
||||||
#include "Main/Resources.h"
|
#include "Main/Resources.h"
|
||||||
#include "VolumeCreationWizard.h"
|
#include "VolumeCreationWizard.h"
|
||||||
#include "EncryptionOptionsWizardPage.h"
|
#include "EncryptionOptionsWizardPage.h"
|
||||||
@@ -194,20 +197,6 @@ namespace VeraCrypt
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string GetMacOSXRawDevicePath (const string &deviceIdentifier)
|
|
||||||
{
|
|
||||||
if (deviceIdentifier.find ("/dev/rdisk") == 0)
|
|
||||||
return deviceIdentifier;
|
|
||||||
|
|
||||||
if (deviceIdentifier.find ("/dev/disk") == 0)
|
|
||||||
return string ("/dev/r") + deviceIdentifier.substr (5);
|
|
||||||
|
|
||||||
if (deviceIdentifier.find ("disk") == 0)
|
|
||||||
return string ("/dev/r") + deviceIdentifier;
|
|
||||||
|
|
||||||
return deviceIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
static string GetMacOSXDiskutilInfo (const VolumePath &devicePath)
|
static string GetMacOSXDiskutilInfo (const VolumePath &devicePath)
|
||||||
{
|
{
|
||||||
list <string> args;
|
list <string> args;
|
||||||
@@ -844,14 +833,20 @@ namespace VeraCrypt
|
|||||||
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
|
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
|
||||||
|
|
||||||
// Temporarily take ownership of the device if the user is not an administrator
|
// Temporarily take ownership of the device if the user is not an administrator
|
||||||
UserId origDeviceOwner ((uid_t) -1);
|
|
||||||
|
|
||||||
DevicePath virtualDevice = volume->VirtualDevice;
|
DevicePath virtualDevice = volume->VirtualDevice;
|
||||||
#ifdef TC_MACOSX
|
#ifdef TC_MACOSX
|
||||||
string virtualDeviceStr = virtualDevice;
|
string virtualDeviceStr = virtualDevice;
|
||||||
if (virtualDeviceStr.find ("/dev/rdisk") != 0)
|
virtualDevice = GetMacOSXRawDevicePath (virtualDeviceStr);
|
||||||
virtualDevice = "/dev/r" + virtualDeviceStr.substr (5);
|
|
||||||
#endif
|
MacOSXFormatterDeviceOwnerRestoreList changedDeviceOwners;
|
||||||
|
finally_do_arg (MacOSXFormatterDeviceOwnerRestoreList *, &changedDeviceOwners,
|
||||||
|
{
|
||||||
|
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
|
||||||
|
});
|
||||||
|
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||||
|
#else
|
||||||
|
UserId origDeviceOwner ((uid_t) -1);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File file;
|
File file;
|
||||||
@@ -871,6 +866,7 @@ namespace VeraCrypt
|
|||||||
if (finally_arg2.SystemId != (uid_t) -1)
|
if (finally_arg2.SystemId != (uid_t) -1)
|
||||||
Core->SetFileOwner (finally_arg, finally_arg2);
|
Core->SetFileOwner (finally_arg, finally_arg2);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create filesystem
|
// Create filesystem
|
||||||
list <string> args;
|
list <string> args;
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
VeraCrypt source code
|
||||||
|
Copyright (c) 2026 AM Crypto
|
||||||
|
|
||||||
|
This file is part of VeraCrypt and is governed by the Apache License 2.0
|
||||||
|
the full text of which is contained in the file License.txt included in
|
||||||
|
VeraCrypt binary and source code distribution packages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VC_HEADER_Main_MacOSXFormatterDevice
|
||||||
|
#define VC_HEADER_Main_MacOSXFormatterDevice
|
||||||
|
|
||||||
|
#include "Main/Main.h"
|
||||||
|
|
||||||
|
#ifdef TC_MACOSX
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace VeraCrypt
|
||||||
|
{
|
||||||
|
inline bool IsMacOSXDiskDevicePath (const string &deviceIdentifier, const string &prefix)
|
||||||
|
{
|
||||||
|
return deviceIdentifier.find (prefix) == 0
|
||||||
|
&& deviceIdentifier.size() > prefix.size()
|
||||||
|
&& deviceIdentifier[prefix.size()] >= '0'
|
||||||
|
&& deviceIdentifier[prefix.size()] <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
inline string GetMacOSXRawDevicePath (const string &deviceIdentifier)
|
||||||
|
{
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "/dev/rdisk"))
|
||||||
|
return deviceIdentifier;
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "/dev/disk"))
|
||||||
|
return string ("/dev/rdisk") + deviceIdentifier.substr (9);
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "rdisk"))
|
||||||
|
return string ("/dev/") + deviceIdentifier;
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "disk"))
|
||||||
|
return string ("/dev/r") + deviceIdentifier;
|
||||||
|
|
||||||
|
return deviceIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline string GetMacOSXBlockDevicePath (const string &deviceIdentifier)
|
||||||
|
{
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "/dev/disk"))
|
||||||
|
return deviceIdentifier;
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "/dev/rdisk"))
|
||||||
|
return string ("/dev/disk") + deviceIdentifier.substr (10);
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "disk"))
|
||||||
|
return string ("/dev/") + deviceIdentifier;
|
||||||
|
|
||||||
|
if (IsMacOSXDiskDevicePath (deviceIdentifier, "rdisk"))
|
||||||
|
return string ("/dev/disk") + deviceIdentifier.substr (5);
|
||||||
|
|
||||||
|
return deviceIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MacOSXFormatterDeviceOwnerRestore
|
||||||
|
{
|
||||||
|
MacOSXFormatterDeviceOwnerRestore (const FilesystemPath &path, const UserId &owner)
|
||||||
|
: Path (path), Owner (owner) { }
|
||||||
|
|
||||||
|
FilesystemPath Path;
|
||||||
|
UserId Owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef list <MacOSXFormatterDeviceOwnerRestore> MacOSXFormatterDeviceOwnerRestoreList;
|
||||||
|
|
||||||
|
inline void AddUniqueMacOSXDevicePath (list <FilesystemPath> &paths, const string &path)
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (const FilesystemPath &existingPath, paths)
|
||||||
|
{
|
||||||
|
if (string (existingPath) == path)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paths.push_back (FilesystemPath (path));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrepareMacOSXFormatterDevice (const DevicePath &devicePath, MacOSXFormatterDeviceOwnerRestoreList &changedDeviceOwners)
|
||||||
|
{
|
||||||
|
if (Core->HasAdminPrivileges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const string devicePathStr = devicePath;
|
||||||
|
list <FilesystemPath> paths;
|
||||||
|
// APFS formatters may resolve /dev/rdiskN back to /dev/diskN internally.
|
||||||
|
AddUniqueMacOSXDevicePath (paths, devicePathStr);
|
||||||
|
AddUniqueMacOSXDevicePath (paths, GetMacOSXRawDevicePath (devicePathStr));
|
||||||
|
AddUniqueMacOSXDevicePath (paths, GetMacOSXBlockDevicePath (devicePathStr));
|
||||||
|
|
||||||
|
foreach (const FilesystemPath &path, paths)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file;
|
||||||
|
file.Open (path, File::OpenReadWrite);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
UserId origDeviceOwner = path.GetOwner();
|
||||||
|
// Register before chown so service-side success followed by
|
||||||
|
// an IPC failure can still be restored.
|
||||||
|
changedDeviceOwners.push_back (MacOSXFormatterDeviceOwnerRestore (path, origDeviceOwner));
|
||||||
|
Core->SetFileOwner (path, UserId (getuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RestoreMacOSXFormatterDeviceOwners (const MacOSXFormatterDeviceOwnerRestoreList &changedDeviceOwners)
|
||||||
|
{
|
||||||
|
foreach (const MacOSXFormatterDeviceOwnerRestore &restore, changedDeviceOwners)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Core->SetFileOwner (restore.Path, restore.Owner);
|
||||||
|
}
|
||||||
|
catch (...) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TC_MACOSX
|
||||||
|
|
||||||
|
#endif // VC_HEADER_Main_MacOSXFormatterDevice
|
||||||
@@ -26,6 +26,9 @@
|
|||||||
#include "Common/EMVToken.h"
|
#include "Common/EMVToken.h"
|
||||||
#include "Core/RandomNumberGenerator.h"
|
#include "Core/RandomNumberGenerator.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#ifdef TC_MACOSX
|
||||||
|
#include "Main/MacOSXFormatterDevice.h"
|
||||||
|
#endif
|
||||||
#include "TextUserInterface.h"
|
#include "TextUserInterface.h"
|
||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
@@ -1065,14 +1068,20 @@ namespace VeraCrypt
|
|||||||
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
|
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
|
||||||
|
|
||||||
// Temporarily take ownership of the device if the user is not an administrator
|
// Temporarily take ownership of the device if the user is not an administrator
|
||||||
UserId origDeviceOwner ((uid_t) -1);
|
|
||||||
|
|
||||||
DevicePath virtualDevice = volume->VirtualDevice;
|
DevicePath virtualDevice = volume->VirtualDevice;
|
||||||
#ifdef TC_MACOSX
|
#ifdef TC_MACOSX
|
||||||
string virtualDeviceStr = virtualDevice;
|
string virtualDeviceStr = virtualDevice;
|
||||||
if (virtualDeviceStr.find ("/dev/rdisk") != 0)
|
virtualDevice = GetMacOSXRawDevicePath (virtualDeviceStr);
|
||||||
virtualDevice = "/dev/r" + virtualDeviceStr.substr (5);
|
|
||||||
#endif
|
MacOSXFormatterDeviceOwnerRestoreList changedDeviceOwners;
|
||||||
|
finally_do_arg (MacOSXFormatterDeviceOwnerRestoreList *, &changedDeviceOwners,
|
||||||
|
{
|
||||||
|
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
|
||||||
|
});
|
||||||
|
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||||
|
#else
|
||||||
|
UserId origDeviceOwner ((uid_t) -1);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File file;
|
File file;
|
||||||
@@ -1092,6 +1101,7 @@ namespace VeraCrypt
|
|||||||
if (finally_arg2.SystemId != (uid_t) -1)
|
if (finally_arg2.SystemId != (uid_t) -1)
|
||||||
Core->SetFileOwner (finally_arg, finally_arg2);
|
Core->SetFileOwner (finally_arg, finally_arg2);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create filesystem
|
// Create filesystem
|
||||||
list <string> args;
|
list <string> args;
|
||||||
|
|||||||
Reference in New Issue
Block a user