1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-12 19:38:26 -06:00

Linux/FreeBSD: Prevent mounting volumes on system directories and PATH (CVE-2025-23021, reported by SivertPL @__tfr)

Added security checks to prevent mounting VeraCrypt volumes on system directories (like /usr/bin) or directories in the user's PATH, which could theoretically allow execution of malicious binaries instead of legitimate system binaries.

Key changes:
- Block mounting on protected system directories (/usr, /bin, /lib, etc.)
  This restriction cannot be overridden
- Block mounting on directories present in user's PATH environment variable
  This can be overridden with --allow-insecure-mount flag
- Add visual warnings (red border, "[INSECURE MODE]") when mounting on PATH directories is allowed
- Handle symlinks properly when checking paths
- Add new error messages for blocked mount points

To override PATH-based restrictions only (system directories remain protected):
veracrypt --allow-insecure-mount [options] volume mountpoint

Security Impact: Low to Medium
The attack requires either:
- User explicitly choosing a system directory as mount point instead of using VeraCrypt's default mount points
- Or attacker having both filesystem access to modify favorites configuration AND knowledge of the volume password
Default mount points are not affected by this vulnerability.

Security: CVE-2025-23021
This commit is contained in:
Mounir IDRASSI
2025-01-11 23:22:40 +01:00
parent 2cca2e1daf
commit 078d1410dd
59 changed files with 370 additions and 6 deletions

View File

@@ -33,6 +33,9 @@ namespace VeraCrypt
ArgDisableFileSizeCheck (false),
ArgUseLegacyPassword (false),
ArgUseDummySudoPassword (false),
#if defined(TC_UNIX)
ArgAllowInsecureMount (false),
#endif
StartBackgroundTask (false)
{
wxCmdLineParser parser;
@@ -107,6 +110,9 @@ namespace VeraCrypt
parser.AddSwitch (L"", L"legacy-password-maxlength", _("Use legacy maximum password length (64 UTF-8 bytes)"));
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
parser.AddSwitch (L"", L"use-dummy-sudo-password", _("Use dummy password in sudo to detect if it is already authenticated"));
#endif
#if defined(TC_UNIX)
parser.AddSwitch (L"", L"allow-insecure-mount", _("Allow mounting volumes on mount points that are in the user's PATH"));
#endif
wxString str;
bool param1IsVolume = false;
@@ -376,6 +382,10 @@ namespace VeraCrypt
ArgUseLegacyPassword = parser.Found (L"legacy-password-maxlength");
ArgUseDummySudoPassword = parser.Found (L"use-dummy-sudo-password");
#if defined(TC_UNIX)
ArgAllowInsecureMount = parser.Found (L"allow-insecure-mount");
#endif
#if !defined(TC_WINDOWS) && !defined(TC_MACOSX)
if (parser.Found (L"fs-options", &str))
ArgMountOptions.FilesystemOptions = str;

View File

@@ -89,6 +89,10 @@ namespace VeraCrypt
bool ArgUseLegacyPassword;
bool ArgUseDummySudoPassword;
#if defined(TC_UNIX)
bool ArgAllowInsecureMount;
#endif
bool StartBackgroundTask;
UserPreferences Preferences;

View File

@@ -34,6 +34,9 @@ namespace VeraCrypt
, wxDefaultPosition, wxSize (-1,-1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
#endif
), Options (options)
#ifdef TC_UNIX
, m_showRedBorder(false)
#endif
{
if (!title.empty())
this->SetTitle (title);
@@ -42,6 +45,16 @@ namespace VeraCrypt
else
this->SetTitle (LangString["ENTER_TC_VOL_PASSWORD"]);
#ifdef TC_UNIX
if (Gui->InsecureMountAllowed())
{
this->SetTitle (LangString["INSECURE_MODE"] + L" - " + this->GetTitle());
m_showRedBorder = true;
Bind(wxEVT_PAINT, &MountOptionsDialog::OnPaint, this);
Bind(wxEVT_SIZE, &MountOptionsDialog::OnSize, this);
}
#endif
if (disableMountOptions)
OptionsButton->Show (false);
@@ -230,4 +243,27 @@ namespace VeraCrypt
Layout();
MainSizer->Fit( this );
}
#ifdef TC_UNIX
void MountOptionsDialog::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
if (m_showRedBorder)
{
wxSize size = GetClientSize();
wxPen pen(*wxRED, 3); // 3 pixels width
dc.SetPen(pen);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(0, 0, size.GetWidth(), size.GetHeight());
}
event.Skip();
}
void MountOptionsDialog::OnSize(wxSizeEvent& event)
{
event.Skip();
if (m_showRedBorder)
Refresh();
}
#endif
}

View File

@@ -40,7 +40,16 @@ namespace VeraCrypt
void OnReadOnlyCheckBoxClick (wxCommandEvent& event) { UpdateDialog(); }
void UpdateDialog ();
#ifdef TC_UNIX
// Used for displaying a red border around the dialog window when insecure mode is enabled
void OnPaint(wxPaintEvent& event);
void OnSize(wxSizeEvent& event);
#endif
MountOptions &Options;
#ifdef TC_UNIX
bool m_showRedBorder;
#endif
wxString OptionsButtonLabel;
VolumePasswordPanel *PasswordPanel;
VolumePasswordPanel *ProtectionPasswordPanel;

View File

@@ -117,6 +117,9 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound);
VC_CONVERT_EXCEPTION (EMVPANNotFound);
VC_CONVERT_EXCEPTION (MountPointBlocked);
VC_CONVERT_EXCEPTION (MountPointNotAllowed);
throw *ex;
}
}

View File

@@ -1082,7 +1082,12 @@ namespace VeraCrypt
#endif
mMainFrame = new MainFrame (nullptr);
#if defined(TC_UNIX)
if (CmdLine->ArgAllowInsecureMount)
{
mMainFrame->SetTitle (mMainFrame->GetTitle() + wxT(" ") + LangString["INSECURE_MODE"]);
}
#endif
if (CmdLine->StartBackgroundTask)
{
UserPreferences prefs = GetPreferences ();

View File

@@ -541,6 +541,9 @@ namespace VeraCrypt
EX2MSG (HigherFuseVersionRequired, LangString["LINUX_EX2MSG_HIGHERFUSEVERSIONREQUIRED"]);
#endif
EX2MSG (MountPointBlocked, LangString["MOUNTPOINT_BLOCKED"]);
EX2MSG (MountPointNotAllowed, LangString["MOUNTPOINT_NOTALLOWED"]);
#undef EX2MSG
return L"";
}
@@ -560,6 +563,7 @@ namespace VeraCrypt
SetPreferences (CmdLine->Preferences);
Core->SetApplicationExecutablePath (Application::GetExecutablePath());
Core->SetUserEnvPATH (getenv ("PATH"));
if (!Preferences.NonInteractive)
{
@@ -572,6 +576,10 @@ namespace VeraCrypt
Core->ForceUseDummySudoPassword (CmdLine->ArgUseDummySudoPassword);
#if defined(TC_UNIX)
Core->SetAllowInsecureMount (CmdLine->ArgAllowInsecureMount);
#endif
Core->WarningEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnWarning));
Core->VolumeMountedEvent.Connect (EventConnector <UserInterface> (this, &UserInterface::OnVolumeMounted));
@@ -1646,6 +1654,13 @@ const FileManager fileManagers[] = {
return sResult;
}
#ifdef TC_UNIX
bool UserInterface::InsecureMountAllowed () const
{
return CmdLine->ArgAllowInsecureMount;
}
#endif
#define VC_CONVERT_EXCEPTION(NAME) if (dynamic_cast<NAME*> (ex)) throw (NAME&) *ex;
void UserInterface::ThrowException (Exception* ex)
@@ -1734,6 +1749,9 @@ const FileManager fileManagers[] = {
VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound);
VC_CONVERT_EXCEPTION (EMVPANNotFound);
VC_CONVERT_EXCEPTION (MountPointBlocked);
VC_CONVERT_EXCEPTION (MountPointNotAllowed);
throw *ex;
}
}

View File

@@ -86,7 +86,9 @@ namespace VeraCrypt
virtual wxDateTime VolumeTimeToDateTime (VolumeTime volumeTime) const { return wxDateTime ((time_t) (volumeTime / 1000ULL / 1000 / 10 - 134774ULL * 24 * 3600)); }
virtual wxString VolumeTimeToString (VolumeTime volumeTime) const;
virtual wxString VolumeTypeToString (VolumeType::Enum type, VolumeProtection::Enum protection) const;
#ifdef TC_UNIX
virtual bool InsecureMountAllowed () const;
#endif
Event PreferencesUpdatedEvent;
struct BusyScope