From 8e165887578b1924c924c5a76efcfcf7dca08498 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 4 Nov 2022 21:20:10 +0200 Subject: [PATCH] Utilities+Base: Add unveil utility This utility essentially creates a filesystem sandbox for a specified command, so it can be tested with only the unveiled paths the user specifies beforehand. --- Base/usr/share/man/man1/unveil.md | 29 +++++++++++++++++++++++ Userland/Utilities/CMakeLists.txt | 1 + Userland/Utilities/unveil.cpp | 38 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 Base/usr/share/man/man1/unveil.md create mode 100644 Userland/Utilities/unveil.cpp diff --git a/Base/usr/share/man/man1/unveil.md b/Base/usr/share/man/man1/unveil.md new file mode 100644 index 0000000000..d89f93645d --- /dev/null +++ b/Base/usr/share/man/man1/unveil.md @@ -0,0 +1,29 @@ +## Name + +unveil - unveil certain paths when running a command + +## Synopsis + +```**sh +$ unveil [--path] [command...] +``` + +## Description + +Run a command under certain path restrictions by using [`unveil`(2)](help://man/2/unveil). + +## Options + +* `-u`, `--path`: Unveil a path, with the format of `permissions,path` + +## Examples + +Run `ls -la /sys/kernel` with restricted access to certain paths: +```sh +$ unveil --path=r,/etc/timezone --path=r,/usr/lib --path=r,/sys/ --path=r,/etc/passwd --path=r,/etc/group ls -la /sys/kernel +``` + +Run `ps -ef` with restricted access to certain paths: +```sh +$ unveil --path=r,/etc/timezone --path=r,/usr/lib --path=r,/sys/ --path=r,/etc/passwd --path=r,/etc/group ps -ef +``` diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 489079d20c..c9f1226d9a 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -120,6 +120,7 @@ target_link_libraries(telws PRIVATE LibProtocol LibLine) target_link_libraries(test-fuzz PRIVATE LibGemini LibGfx LibHTTP LibIPC LibJS LibMarkdown LibRegex LibShell) target_link_libraries(test-imap PRIVATE LibIMAP) target_link_libraries(test-pthread PRIVATE LibThreading) +target_link_libraries(unveil PRIVATE LibMain) target_link_libraries(unzip PRIVATE LibArchive LibCompress) target_link_libraries(update-cpp-test-results PRIVATE LibCpp) target_link_libraries(useradd PRIVATE LibCrypt) diff --git a/Userland/Utilities/unveil.cpp b/Userland/Utilities/unveil.cpp new file mode 100644 index 0000000000..848029dd20 --- /dev/null +++ b/Userland/Utilities/unveil.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +ErrorOr serenity_main(Main::Arguments arguments) +{ + Vector unveil_paths; + Vector command; + + Core::ArgsParser args_parser; + args_parser.set_stop_on_first_non_option(true); + args_parser.add_option(unveil_paths, "Path to unveil [permissions,path]", "path", 'u', ""); + args_parser.add_positional_argument(command, "Command to execute", "command"); + args_parser.parse(arguments); + + if (unveil_paths.is_empty()) { + return Error::from_string_view("No unveil paths were specified."sv); + } + + for (auto& path : unveil_paths) { + auto parts = path.split_view(','); + if (parts.size() != 2) + return Error::from_string_literal("Unveil path being specified is invalid."); + TRY(Core::System::unveil_after_exec(parts[1], parts[0])); + } + + TRY(Core::System::exec(command[0], command, Core::System::SearchInPath::Yes)); + return 0; +}