mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-22 12:31:31 +00: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:
@@ -843,7 +843,9 @@ namespace VeraCrypt
|
||||
{
|
||||
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
|
||||
});
|
||||
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||
bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter);
|
||||
if (!useElevatedAPFSFormatter)
|
||||
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||
#else
|
||||
UserId origDeviceOwner ((uid_t) -1);
|
||||
|
||||
@@ -888,10 +890,19 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
if (IsMacOSXAPFSFormatter (fsFormatter) && !useElevatedAPFSFormatter)
|
||||
AddMacOSXAPFSFormatterUserArgs (args);
|
||||
#endif
|
||||
|
||||
args.push_back (string (virtualDevice));
|
||||
|
||||
SetCreationProgressText (StringFormatter (LangString["FORMAT_STAGE_CREATING_FILESYSTEM"], fsFormatter));
|
||||
#ifdef TC_MACOSX
|
||||
ExecuteMacOSXFilesystemFormatter (fsFormatter, args);
|
||||
#else
|
||||
Process::Execute (fsFormatter, args);
|
||||
#endif
|
||||
SetCreationProgressText (LangString["FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME"]);
|
||||
}
|
||||
#endif // TC_UNIX
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
#include <unistd.h>
|
||||
#include "Core/Unix/CoreService.h"
|
||||
#include "Platform/Unix/Process.h"
|
||||
|
||||
namespace VeraCrypt
|
||||
{
|
||||
@@ -59,6 +61,33 @@ namespace VeraCrypt
|
||||
return deviceIdentifier;
|
||||
}
|
||||
|
||||
inline bool IsMacOSXAPFSFormatter (const string &fsFormatter)
|
||||
{
|
||||
size_t namePos = fsFormatter.find_last_of ('/');
|
||||
string fsFormatterName = namePos == string::npos ? fsFormatter : fsFormatter.substr (namePos + 1);
|
||||
return fsFormatterName == "newfs_apfs";
|
||||
}
|
||||
|
||||
inline bool UseElevatedMacOSXAPFSFormatter (const string &fsFormatter)
|
||||
{
|
||||
return IsMacOSXAPFSFormatter (fsFormatter) && !Core->HasAdminPrivileges();
|
||||
}
|
||||
|
||||
inline void AddMacOSXAPFSFormatterUserArgs (list <string> &args)
|
||||
{
|
||||
stringstream uid;
|
||||
stringstream gid;
|
||||
|
||||
// The APFS formatter may run elevated, so preserve the invoking user's ownership.
|
||||
uid << getuid();
|
||||
gid << getgid();
|
||||
|
||||
args.push_back ("-U");
|
||||
args.push_back (uid.str());
|
||||
args.push_back ("-G");
|
||||
args.push_back (gid.str());
|
||||
}
|
||||
|
||||
struct MacOSXFormatterDeviceOwnerRestore
|
||||
{
|
||||
MacOSXFormatterDeviceOwnerRestore (const FilesystemPath &path, const UserId &owner)
|
||||
@@ -125,6 +154,20 @@ namespace VeraCrypt
|
||||
catch (...) { }
|
||||
}
|
||||
}
|
||||
|
||||
inline void ExecuteMacOSXFilesystemFormatter (const string &fsFormatter, const list <string> &args)
|
||||
{
|
||||
if (UseElevatedMacOSXAPFSFormatter (fsFormatter))
|
||||
{
|
||||
if (args.empty())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
CoreService::RequestExecuteMacOSXAPFSFormatter (DevicePath (args.back()), getuid(), getgid());
|
||||
return;
|
||||
}
|
||||
|
||||
Process::Execute (IsMacOSXAPFSFormatter (fsFormatter) ? CoreService::GetMacOSXAPFSFormatterPath() : fsFormatter, args);
|
||||
}
|
||||
}
|
||||
#endif // TC_MACOSX
|
||||
|
||||
|
||||
@@ -1078,7 +1078,9 @@ namespace VeraCrypt
|
||||
{
|
||||
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
|
||||
});
|
||||
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||
bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter);
|
||||
if (!useElevatedAPFSFormatter)
|
||||
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
|
||||
#else
|
||||
UserId origDeviceOwner ((uid_t) -1);
|
||||
|
||||
@@ -1123,9 +1125,18 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
if (IsMacOSXAPFSFormatter (fsFormatter) && !useElevatedAPFSFormatter)
|
||||
AddMacOSXAPFSFormatterUserArgs (args);
|
||||
#endif
|
||||
|
||||
args.push_back (string (virtualDevice));
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
ExecuteMacOSXFilesystemFormatter (fsFormatter, args);
|
||||
#else
|
||||
Process::Execute (fsFormatter, args);
|
||||
#endif
|
||||
}
|
||||
#endif // TC_UNIX
|
||||
|
||||
|
||||
Reference in New Issue
Block a user