diff options
author | Brendan Coles <bcoles@gmail.com> | 2021-05-30 06:00:25 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-30 10:41:25 +0100 |
commit | 340cecaf809c224d564b59559e0ef37f58b48e5a (patch) | |
tree | 313cf8a8945613611793aff1638228ed43776220 /Userland | |
parent | f387da4a901e637b4bb0e8a2c4245f6dc0f31974 (diff) | |
download | serenity-340cecaf809c224d564b59559e0ef37f58b48e5a.zip |
pls: Unveil search paths with browse permissions
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Utilities/pls.cpp | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/Userland/Utilities/pls.cpp b/Userland/Utilities/pls.cpp index 7cfb1ecedb..182e95782c 100644 --- a/Userland/Utilities/pls.cpp +++ b/Userland/Utilities/pls.cpp @@ -28,30 +28,31 @@ bool unveil_paths(const char*); // Unveil paths, given the current user's path and the command they want to execute bool unveil_paths(const char* command) { - bool did_unveil_ok = false; + // Unveil all trusted paths with browse permissions + auto trusted_directories = Array { "/bin", "/usr/bin", "/usr/local/bin" }; + for (auto directory : trusted_directories) { + if (unveil(directory, "b") < 0) { + perror("unveil"); + return false; + } + } // Attempt to unveil command via `realpath` - auto* command_path = realpath(command, nullptr); + auto command_path = Core::File::real_path_for(command); // Command found via `realpath` (meaning it was probably a locally executed program) - if (command_path) { - if (unveil(command_path, "x") == 0) - did_unveil_ok = true; - - free(command_path); - return did_unveil_ok; + if (!command_path.is_empty()) { + if (unveil(command_path.characters(), "x") == 0) + return true; + return false; } - // Okay, so we couldn't find the actual file specified by the user, let's - // instead search PATH for it... auto command_path_system = Core::find_executable_in_path(command); if (command_path_system.is_empty()) return false; - - if (unveil(command_path_system.characters(), "x") == 0) - did_unveil_ok = true; - - return did_unveil_ok; + if (unveil(command_path_system.characters(), "x") < 0) + return false; + return true; } int main(int argc, char** argv) @@ -59,9 +60,13 @@ int main(int argc, char** argv) Vector<const char*> command; Core::ArgsParser args_parser; args_parser.add_positional_argument(command, "Command to run at elevated privilege level", "command"); - args_parser.parse(argc, argv); + // Unveil command path. + // Fail silently to prevent disclosing whether the specified path is valid + auto command_path = LexicalPath(Core::File::real_path_for(command.at(0))).dirname(); + unveil(command_path.characters(), "b"); + if (pledge("stdio tty rpath exec id", nullptr) < 0) { perror("pledge"); return 1; @@ -87,12 +92,9 @@ int main(int argc, char** argv) return 1; } - // Unveil all paths in the user's PATH, as well as the command they've specified. - auto unveil_count = unveil_paths(command.at(0)); - if (unveil_count == 0) { - warnln("Error: Failed to unveil paths!"); - return 1; - } + // Find and unveil the user's command executable. + // Fail silently to prevent disclosing whether the specified path is valid + unveil_paths(command.at(0)); // Lock veil unveil(nullptr, nullptr); |