From 31f9e699c8cd7fbe0b1d6607e9a6f3fa0ae40e71 Mon Sep 17 00:00:00 2001 From: Damian Rickard Date: Sat, 20 Jun 2026 14:35:07 -0400 Subject: [PATCH] macOS: search system directories before /usr/local/bin for binaries On macOS, Process::FindSystemBinary() searched /usr/local/bin first, so a user-writable /usr/local/bin (the default on Homebrew installs) could shadow system tools. This resolver is also used to locate privileged binaries during privilege elevation: CoreService.cpp resolves "sudo" (and "true") through it both when probing for an active sudo session and when launching the elevated helper, and the admin password is written to that sudo process's stdin. On a typical Homebrew install /usr/local is owned by the (non-root) user, so a planted /usr/local/bin/sudo would be selected ahead of /usr/bin/sudo and could capture the admin password, leading to privilege escalation. Reorder the macOS list to {/usr/bin, /bin, /usr/sbin, /sbin, /usr/local/bin} so system locations always win. The binaries actually resolved through this function on macOS (sudo, true, fsck, the terminal helper used for filesystem checks and its dependencies, and non-APFS formatters) live in system directories, so /usr/local/bin is kept only as a last-resort fallback and can no longer shadow them. (diskutil, hdiutil and newfs_apfs are invoked via absolute paths and were never affected.) --- src/Platform/Unix/Process.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Platform/Unix/Process.cpp b/src/Platform/Unix/Process.cpp index 92a4f30b81..b50add5c5d 100644 --- a/src/Platform/Unix/Process.cpp +++ b/src/Platform/Unix/Process.cpp @@ -44,9 +44,15 @@ namespace VeraCrypt return ""; } - // Default system directories to search for executables + // Default system directories to search for executables. + // On macOS, system locations are searched before /usr/local/bin so that + // a user-writable /usr/local/bin (the default on Homebrew installs) + // cannot shadow system tools. This matters because this resolver is + // also used for privileged binaries such as sudo during elevation + // (see CoreService.cpp); a planted /usr/local/bin/sudo would otherwise + // receive the admin password. #ifdef TC_MACOSX - const char* defaultDirs[] = {"/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"}; + const char* defaultDirs[] = {"/usr/bin", "/bin", "/usr/sbin", "/sbin", "/usr/local/bin"}; #elif TC_FREEBSD const char* defaultDirs[] = {"/sbin", "/bin", "/usr/sbin", "/usr/bin", "/usr/local/sbin", "/usr/local/bin"}; #elif TC_OPENBSD