VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Unix/CoreUnix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/Unix/CoreUnix.cpp')
-rw-r--r--src/Core/Unix/CoreUnix.cpp237
1 files changed, 190 insertions, 47 deletions
diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp
index 1868eb6d..1f2d3125 100644
--- a/src/Core/Unix/CoreUnix.cpp
+++ b/src/Core/Unix/CoreUnix.cpp
@@ -4,7 +4,7 @@
by the TrueCrypt License 3.0.
Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2017 IDRIX
+ and all other portions of this file are Copyright (c) 2013-2025 IDRIX
and are 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.
@@ -29,6 +29,41 @@ namespace VeraCrypt
static bool SamePath (const string& path1, const string& path2);
#endif
+ // Struct to hold terminal emulator information
+ struct TerminalInfo {
+ const char* name;
+ const char** args;
+ const char** dependency_path;
+ };
+
+ // Popular terminal emulators data and arguments
+ static const char* xterm_args[] = {"-T", "fsck", "-e", NULL};
+
+ static const char* gnome_args[] = {"--title", "fsck", "--", "sh", "-c", NULL};
+ static const char* gnome_deps[] = {"dbus-launch", NULL};
+
+ static const char* konsole_args[] = {"--hold", "-p", "tabtitle=fsck", "-e", "sh", "-c", NULL};
+ static const char* xfce4_args[] = {"--title=fsck", "-x", "sh", "-c", NULL};
+ static const char* mate_args[] = {"--title", "fsck", "--", "sh", "-c", NULL};
+ static const char* lxterminal_args[] = {"--title=fsck", "-e", "sh", "-c", NULL};
+ static const char* terminator_args[] = {"-T", "fsck", "-x", "sh", "-c", NULL};
+ static const char* urxvt_args[] = {"-title", "fsck", "-e", "sh", "-c", NULL};
+ static const char* st_args[] = {"-t", "fsck", "-e", "sh", "-c", NULL};
+
+ // List of popular terminal emulators
+ static const TerminalInfo TERMINALS[] = {
+ {"xterm", xterm_args, NULL},
+ {"gnome-terminal", gnome_args, gnome_deps},
+ {"konsole", konsole_args, NULL},
+ {"xfce4-terminal", xfce4_args, NULL},
+ {"mate-terminal", mate_args, NULL},
+ {"lxterminal", lxterminal_args, NULL},
+ {"terminator", terminator_args, NULL},
+ {"urxvt", urxvt_args, NULL},
+ {"st", st_args, NULL},
+ {NULL, NULL, NULL}
+ };
+
CoreUnix::CoreUnix ()
{
signal (SIGPIPE, SIG_IGN);
@@ -47,14 +82,16 @@ namespace VeraCrypt
if (!mountedVolume->MountPoint.IsEmpty())
DismountFilesystem (mountedVolume->MountPoint, false);
- list <string> args;
-
- args.push_back ("-T");
- args.push_back ("fsck");
+ // Find system fsck first
+ std::string errorMsg;
+ std::string fsckPath = Process::FindSystemBinary("fsck", errorMsg);
+ if (fsckPath.empty()) {
+ throw SystemException(SRC_POS, errorMsg);
+ }
- args.push_back ("-e");
+ list <string> args;
- string xargs = "fsck ";
+ string xargs = fsckPath + " "; // Use absolute fsck path
#ifdef TC_LINUX
if (!repair)
@@ -64,49 +101,48 @@ namespace VeraCrypt
#endif
xargs += string (mountedVolume->VirtualDevice) + "; echo '[Done]'; read W";
- args.push_back (xargs);
+ // Try each terminal
+ for (const TerminalInfo* term = TERMINALS; term->name != NULL; ++term) {
+ errno = 0;
+ std::string termPath = Process::FindSystemBinary(term->name, errorMsg);
+ if (termPath.length() > 0) {
+ // check dependencies
+ if (term->dependency_path) {
+ bool depFound = true;
+ for (const char** dep = term->dependency_path; *dep != NULL; ++dep) {
+ string depPath = Process::FindSystemBinary(*dep, errorMsg);
+ if (depPath.empty()) {
+ depFound = false;
+ break;
+ }
+ }
- try
- {
- Process::Execute ("xterm", args, 1000);
- } catch (TimeOut&) { }
-#ifdef TC_LINUX
- catch (SystemException&)
- {
- // xterm not available. Try with KDE konsole if it exists
- struct stat sb;
- if (stat("/usr/bin/konsole", &sb) == 0)
- {
- args.clear ();
- args.push_back ("-p");
- args.push_back ("tabtitle=fsck");
- args.push_back ("-e");
- args.push_back ("sh");
- args.push_back ("-c");
- args.push_back (xargs);
- try
- {
- Process::Execute ("konsole", args, 1000);
- } catch (TimeOut&) { }
- }
- else if (stat("/usr/bin/gnome-terminal", &sb) == 0 && stat("/usr/bin/dbus-launch", &sb) == 0)
- {
- args.clear ();
- args.push_back ("--title");
- args.push_back ("fsck");
- args.push_back ("--");
- args.push_back ("sh");
- args.push_back ("-c");
- args.push_back (xargs);
- try
- {
- Process::Execute ("gnome-terminal", args, 1000);
- } catch (TimeOut&) { }
+ if (!depFound) {
+ continue; // dependency not found, skip
+ }
+ }
+
+ // Build args
+ std::list<std::string> args;
+ for (const char** arg = term->args; *arg != NULL; ++arg) {
+ args.push_back(*arg);
+ }
+ args.push_back(xargs);
+
+ try {
+ Process::Execute (termPath, args, 1000);
+ return;
+ }
+ catch (TimeOut&) {
+ return;
+ }
+ catch (SystemException&) {
+ // Continue to next terminal
+ }
}
- else
- throw TerminalNotFound();
}
-#endif
+
+ throw TerminalNotFound();
}
void CoreUnix::DismountFilesystem (const DirectoryPath &mountPoint, bool force) const
@@ -560,6 +596,17 @@ namespace VeraCrypt
if (IsVolumeMounted (*options.Path))
throw VolumeAlreadyMounted (SRC_POS);
+ if (options.MountPoint && !options.MountPoint->IsEmpty())
+ {
+ // Reject if the mount point is a system directory
+ if (IsProtectedSystemDirectory(*options.MountPoint))
+ throw MountPointBlocked (SRC_POS);
+
+ // Reject if the mount point is in the user's PATH and the user has not explicitly allowed insecure mount points
+ if (!GetAllowInsecureMount() && IsDirectoryOnUserPath(*options.MountPoint))
+ throw MountPointNotAllowed (SRC_POS);
+ }
+
Cipher::EnableHwSupport (!options.NoHardwareCrypto);
shared_ptr <Volume> volume;
@@ -792,4 +839,100 @@ namespace VeraCrypt
s << GetDefaultMountPointPrefix() << slotNumber;
return s.str();
}
+
+ bool CoreUnix::IsProtectedSystemDirectory (const DirectoryPath &directory) const
+ {
+ static const char* systemDirs[] = {
+ "/usr",
+ "/bin",
+ "/sbin",
+ "/lib",
+#ifdef TC_LINUX
+ "/lib32",
+ "/lib64",
+ "/libx32",
+#endif
+ "/etc",
+ "/boot",
+ "/root",
+ "/proc",
+ "/sys",
+ "/dev",
+ NULL
+ };
+
+ // Resolve any symlinks in the path
+ string path(directory);
+ char* resolvedPathCStr = realpath(path.c_str(), NULL);
+ if (resolvedPathCStr)
+ {
+ path = resolvedPathCStr;
+ free(resolvedPathCStr); // Free the allocated memory
+ }
+
+ // reject of the path is the root directory "/"
+ if (path == "/")
+ return true;
+
+ // Check if resolved path matches any system directory
+ for (int i = 0; systemDirs[i] != NULL; ++i)
+ {
+ if (path == systemDirs[i] || path.find(string(systemDirs[i]) + "/") == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CoreUnix::IsDirectoryOnUserPath(const DirectoryPath &directory) const
+ {
+ // Obtain the PATH environment variable
+ const char* pathEnv = UserEnvPATH.c_str();
+ if (!pathEnv[0])
+ return false;
+
+ // Resolve the given directory
+ string dirPath(directory);
+ char* resolvedDir = realpath(dirPath.c_str(), NULL);
+ if (resolvedDir)
+ {
+ dirPath = resolvedDir;
+ free(resolvedDir);
+ }
+
+ // Split PATH and compare each entry
+ stringstream ss(pathEnv);
+ string token;
+ while (getline(ss, token, ':'))
+ {
+ // remove any trailing slashes from the token
+ while (!token.empty() && token.back() == '/')
+ token.pop_back();
+
+ if (token.empty())
+ continue;
+
+ // check if the directory is the same as the entry or a subdirectory
+ if (dirPath == token || dirPath.find(token + "/") == 0)
+ return true;
+
+ // handle the case where the PATH entry is a symlink
+ char* resolvedEntry = realpath(token.c_str(), NULL);
+ if (!resolvedEntry)
+ continue; // skip to the next entry since the path does not exist
+
+ string entryPath(resolvedEntry);
+ free(resolvedEntry);
+
+ // remove any trailing slashes from the token
+ while (!entryPath.empty() && entryPath.back() == '/')
+ entryPath.pop_back();
+
+ // perform check again if the resolved path is different from the original (symlink)
+ if (dirPath == entryPath || dirPath.find(entryPath + "/") == 0)
+ return true;
+ }
+
+ return false;
+ }
}