mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-09 21:22:41 +00:00
Linux/macOS: surface post-sudo elevation errors
Separate sudo authentication success from elevated request execution state by acknowledging when the elevated core service starts successfully. Once that channel is available, propagate later failures instead of showing repeated administrator password dialogs. Initialize the sudo dummy-password flag consistently on macOS, avoiding an uninitialized read of UseDummySudoPassword. Register admin-password cleanup before elevation attempts so plaintext sudo credentials are erased on early-return and post-sudo failure paths. References #1788.
This commit is contained in:
@@ -110,8 +110,7 @@ namespace VeraCrypt
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> CoreService::GetResponse ()
|
||||
unique_ptr <Serializable> CoreService::GetResponseObject ()
|
||||
{
|
||||
unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
|
||||
|
||||
@@ -119,6 +118,14 @@ namespace VeraCrypt
|
||||
if (deserializedException)
|
||||
deserializedException->Throw();
|
||||
|
||||
return deserializedObject;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> CoreService::GetResponse ()
|
||||
{
|
||||
unique_ptr <Serializable> deserializedObject (GetResponseObject());
|
||||
|
||||
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
@@ -199,14 +206,21 @@ namespace VeraCrypt
|
||||
|
||||
if (!ElevatedPrivileges && request->ElevateUserPrivileges)
|
||||
{
|
||||
bool elevatedServiceStarted = false;
|
||||
|
||||
if (!ElevatedServiceAvailable)
|
||||
{
|
||||
finally_do_arg (string *, &request->AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
CoreService::StartElevated (*request);
|
||||
ElevatedServiceAvailable = true;
|
||||
elevatedServiceStarted = true;
|
||||
}
|
||||
|
||||
// Report sudo/elevated-service success before executing the request.
|
||||
if (elevatedServiceStarted)
|
||||
ElevatedServiceStartedResponse().Serialize (outputStream);
|
||||
|
||||
request->Serialize (ServiceInputStream);
|
||||
GetResponse <Serializable>()->Serialize (outputStream);
|
||||
continue;
|
||||
@@ -424,6 +438,7 @@ namespace VeraCrypt
|
||||
request.UserEnvPATH = Core->GetUserEnvPATH();
|
||||
request.UseDummySudoPassword = Core->GetUseDummySudoPassword();
|
||||
request.AllowInsecureMount = Core->GetAllowInsecureMount();
|
||||
finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
if (request.RequiresElevation())
|
||||
{
|
||||
@@ -482,12 +497,28 @@ namespace VeraCrypt
|
||||
try
|
||||
{
|
||||
request.Serialize (ServiceInputStream);
|
||||
unique_ptr <T> response (GetResponse <T>());
|
||||
|
||||
unique_ptr <Serializable> response (GetResponseObject());
|
||||
if (dynamic_cast <ElevatedServiceStartedResponse *> (response.get()) != nullptr)
|
||||
{
|
||||
// The elevated channel is usable even if the forwarded request fails.
|
||||
// Any later failure must be propagated as the real error rather than
|
||||
// triggering another administrator-password prompt.
|
||||
ElevatedServiceAvailable = true;
|
||||
return GetResponse <T> ();
|
||||
}
|
||||
|
||||
if (dynamic_cast <T *> (response.get()) == nullptr)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
ElevatedServiceAvailable = true;
|
||||
return response;
|
||||
return unique_ptr <T> (dynamic_cast <T *> (response.release()));
|
||||
}
|
||||
catch (ElevationFailed &e)
|
||||
{
|
||||
if (ElevatedServiceAvailable)
|
||||
throw;
|
||||
|
||||
if (!request.FastElevation)
|
||||
{
|
||||
ExceptionEventArgs args (e);
|
||||
@@ -502,8 +533,6 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
request.Serialize (ServiceInputStream);
|
||||
return GetResponse <T>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user