mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-17 10:06:06 -05:00
macOS: run APFS formatter elevated
APFS volume creation can still fail with Permission denied after preparing the raw and block device aliases because newfs_apfs performs privileged APFS container and volume operations beyond opening the device nodes. Route APFS formatting through the elevated CoreService path for non-root macOS runs. Keep the elevated interface narrow by sending only the target device and invoking user UID/GID, validate the device path on the privileged side, rebuild the formatter arguments there, and execute /sbin/newfs_apfs by absolute path to avoid PATH shadowing. Pass -U/-G so the created filesystem preserves the invoking user ownership. Apply the same path to GUI and text-mode creation.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "Platform/SystemLog.h"
|
||||
#include "Platform/Thread.h"
|
||||
#include "Platform/Unix/Poller.h"
|
||||
#include "Platform/Unix/Process.h"
|
||||
#include "Core/Core.h"
|
||||
#include "CoreUnix.h"
|
||||
#include "CoreServiceRequest.h"
|
||||
@@ -27,6 +28,66 @@
|
||||
|
||||
namespace VeraCrypt
|
||||
{
|
||||
#ifdef TC_MACOSX
|
||||
static bool IsMacOSXDevicePathWithPrefix (const string &path, const string &prefix)
|
||||
{
|
||||
if (path.find (prefix) != 0 || path.size() <= prefix.size())
|
||||
return false;
|
||||
|
||||
size_t index = prefix.size();
|
||||
while (index < path.size() && path[index] >= '0' && path[index] <= '9')
|
||||
++index;
|
||||
|
||||
if (index == prefix.size())
|
||||
return false;
|
||||
|
||||
if (index == path.size())
|
||||
return true;
|
||||
|
||||
if (path[index++] != 's')
|
||||
return false;
|
||||
|
||||
size_t sliceStart = index;
|
||||
while (index < path.size() && path[index] >= '0' && path[index] <= '9')
|
||||
++index;
|
||||
|
||||
return index > sliceStart && index == path.size();
|
||||
}
|
||||
|
||||
static bool IsMacOSXFormatterDevicePath (const string &path)
|
||||
{
|
||||
return IsMacOSXDevicePathWithPrefix (path, "/dev/disk")
|
||||
|| IsMacOSXDevicePathWithPrefix (path, "/dev/rdisk");
|
||||
}
|
||||
|
||||
static list <string> BuildMacOSXAPFSFormatterArguments (const ExecuteMacOSXAPFSFormatterRequest &request)
|
||||
{
|
||||
if (!IsMacOSXFormatterDevicePath (request.Device))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (request.OwnerUserId > static_cast <uint64> ((uid_t) -1)
|
||||
|| request.OwnerGroupId > static_cast <uint64> ((gid_t) -1))
|
||||
{
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
stringstream uid;
|
||||
stringstream gid;
|
||||
list <string> arguments;
|
||||
|
||||
uid << request.OwnerUserId;
|
||||
gid << request.OwnerGroupId;
|
||||
|
||||
arguments.push_back ("-U");
|
||||
arguments.push_back (uid.str());
|
||||
arguments.push_back ("-G");
|
||||
arguments.push_back (gid.str());
|
||||
arguments.push_back (string (request.Device));
|
||||
|
||||
return arguments;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> CoreService::GetResponse ()
|
||||
{
|
||||
@@ -201,6 +262,17 @@ namespace VeraCrypt
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
// ExecuteMacOSXAPFSFormatterRequest
|
||||
ExecuteMacOSXAPFSFormatterRequest *executeAPFSFormatterRequest = dynamic_cast <ExecuteMacOSXAPFSFormatterRequest*> (request.get());
|
||||
if (executeAPFSFormatterRequest)
|
||||
{
|
||||
Process::Execute (CoreService::GetMacOSXAPFSFormatterPath(), BuildMacOSXAPFSFormatterArguments (*executeAPFSFormatterRequest));
|
||||
ExecuteMacOSXAPFSFormatterResponse().Serialize (outputStream);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// MountVolumeRequest
|
||||
MountVolumeRequest *mountRequest = dynamic_cast <MountVolumeRequest*> (request.get());
|
||||
if (mountRequest)
|
||||
@@ -290,6 +362,19 @@ namespace VeraCrypt
|
||||
return SendRequest <GetHostDevicesResponse> (request)->HostDevices;
|
||||
}
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
const char *CoreService::GetMacOSXAPFSFormatterPath ()
|
||||
{
|
||||
return "/sbin/newfs_apfs";
|
||||
}
|
||||
|
||||
void CoreService::RequestExecuteMacOSXAPFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId)
|
||||
{
|
||||
ExecuteMacOSXAPFSFormatterRequest request (devicePath, userId, groupId);
|
||||
SendRequest <ExecuteMacOSXAPFSFormatterResponse> (request);
|
||||
}
|
||||
#endif
|
||||
|
||||
shared_ptr <VolumeInfo> CoreService::RequestMountVolume (MountOptions &options)
|
||||
{
|
||||
MountVolumeRequest request (&options);
|
||||
|
||||
Reference in New Issue
Block a user