From 8d8b0d0a34f68ed850a96e1437084a2e07876f9b Mon Sep 17 00:00:00 2001 From: Liav A Date: Wed, 2 Nov 2022 22:28:58 +0200 Subject: [PATCH] Userland: Add support for jails This happens in two ways: 1. LibCore now has two new methods for creating Jails and attaching processes to a Jail. 2. We introduce 3 new utilities - lsjails, jail-create and jails-attach, which list jails, create jails and attach processes to a Jail, respectively. --- Base/usr/share/man/man1/jail-attach.md | 21 ++++++++++++++++ Base/usr/share/man/man1/jail-create.md | 20 +++++++++++++++ Base/usr/share/man/man1/lsjails.md | 22 ++++++++++++++++ Userland/Libraries/LibCore/System.cpp | 14 +++++++++++ Userland/Libraries/LibCore/System.h | 5 ++++ Userland/Utilities/CMakeLists.txt | 2 ++ Userland/Utilities/jail-attach.cpp | 28 +++++++++++++++++++++ Userland/Utilities/jail-create.cpp | 27 ++++++++++++++++++++ Userland/Utilities/lsjails.cpp | 35 ++++++++++++++++++++++++++ 9 files changed, 174 insertions(+) create mode 100644 Base/usr/share/man/man1/jail-attach.md create mode 100644 Base/usr/share/man/man1/jail-create.md create mode 100644 Base/usr/share/man/man1/lsjails.md create mode 100644 Userland/Utilities/jail-attach.cpp create mode 100644 Userland/Utilities/jail-create.cpp create mode 100644 Userland/Utilities/lsjails.cpp diff --git a/Base/usr/share/man/man1/jail-attach.md b/Base/usr/share/man/man1/jail-attach.md new file mode 100644 index 00000000000..7c8cf5b8262 --- /dev/null +++ b/Base/usr/share/man/man1/jail-attach.md @@ -0,0 +1,21 @@ +## Name + +jail-attach - attach a new process to existing jail + +## Synopsis + +```**sh +$ jail-attach +``` + +## Description + +`jail-attach` attaches a new process by specifying a command, to an existing jail, with a +specified jail index. + +## Examples + +```sh +# Attach the command "ps -ef" to a jail with the index 0 +$ jail-attach 0 ps -ef +``` diff --git a/Base/usr/share/man/man1/jail-create.md b/Base/usr/share/man/man1/jail-create.md new file mode 100644 index 00000000000..c6660ad9bd3 --- /dev/null +++ b/Base/usr/share/man/man1/jail-create.md @@ -0,0 +1,20 @@ +## Name + +jail-create - create a new jail + +## Synopsis + +```**sh +$ jail-create +``` + +## Description + +`jail-create` creates a new jail, with a specified name + +## Examples + +```sh +# Create jail with the name "test-jail" +$ jail-create test-jail +``` diff --git a/Base/usr/share/man/man1/lsjails.md b/Base/usr/share/man/man1/lsjails.md new file mode 100644 index 00000000000..e99ee50a566 --- /dev/null +++ b/Base/usr/share/man/man1/lsjails.md @@ -0,0 +1,22 @@ +## Name + +lsjails - list existing jails + +## Synopsis + +```**sh +# lsjails +``` + +## Description + +This utility will list all existing jails at the moment of invoking this program. +Please note that if the current process is in jail, it will not see any jail. + +## Examples + +```sh +# lsjails +Index Name +2 test-jail +``` diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 3490f33818b..2a0e345e6c8 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -1000,6 +1000,20 @@ ErrorOr exec_command(Vector& command, bool preserve_env) TRY(Core::System::exec(command.at(0), command, Core::System::SearchInPath::Yes, exec_environment)); return {}; } + +ErrorOr join_jail(u64 jail_index) +{ + Syscall::SC_jail_attach_params params { jail_index }; + int rc = syscall(SC_jail_attach, ¶ms); + HANDLE_SYSCALL_RETURN_VALUE("jail_attach", rc, {}); +} + +ErrorOr create_jail(StringView jail_name) +{ + Syscall::SC_jail_create_params params { 0, { jail_name.characters_without_null_termination(), jail_name.length() } }; + int rc = syscall(SC_jail_create, ¶ms); + HANDLE_SYSCALL_RETURN_VALUE("jail_create", rc, static_cast(params.index)); +} #endif ErrorOr exec(StringView filename, Span arguments, SearchInPath search_in_path, Optional> environment) diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index d506dd8df0b..0a47c4ead71 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -172,6 +172,11 @@ ErrorOr exec_command(Vector& command, bool preserve_env); ErrorOr exec(StringView filename, Span arguments, SearchInPath, Optional> environment = {}); +#ifdef AK_OS_SERENITY +ErrorOr join_jail(u64 jail_index); +ErrorOr create_jail(StringView jail_name); +#endif + ErrorOr socket(int domain, int type, int protocol); ErrorOr bind(int sockfd, struct sockaddr const*, socklen_t); ErrorOr listen(int sockfd, int backlog); diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 9d8870772e1..cadc73746bb 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -90,6 +90,8 @@ target_link_libraries(grep PRIVATE LibRegex) target_link_libraries(gunzip PRIVATE LibCompress) target_link_libraries(gzip PRIVATE LibCompress) target_link_libraries(headless-browser PRIVATE LibCrypto LibGemini LibGfx LibHTTP LibTLS LibWeb LibWebSocket) +target_link_libraries(jail-attach PRIVATE LibCore LibMain) +target_link_libraries(jail-create PRIVATE LibCore LibMain) target_link_libraries(js PRIVATE LibCrypto LibJS LibLine LibLocale LibTextCodec) link_with_locale_data(js) target_link_libraries(keymap PRIVATE LibKeyboard) diff --git a/Userland/Utilities/jail-attach.cpp b/Userland/Utilities/jail-attach.cpp new file mode 100644 index 00000000000..ba09dafc498 --- /dev/null +++ b/Userland/Utilities/jail-attach.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +ErrorOr serenity_main(Main::Arguments arguments) +{ + unsigned jail_index = 0; + Vector command; + Core::ArgsParser args_parser; + bool preserve_env = false; + args_parser.set_stop_on_first_non_option(true); + args_parser.add_option(preserve_env, "Preserve user environment when running command", "preserve-env", 'E'); + args_parser.add_positional_argument(jail_index, "Jail Index", "jail index"); + args_parser.add_positional_argument(command, "Command to execute", "command"); + args_parser.parse(arguments); + + TRY(Core::System::pledge("stdio rpath exec id jail tty")); + TRY(Core::System::join_jail(jail_index)); + TRY(Core::System::exec_command(command, preserve_env)); + return 0; +} diff --git a/Userland/Utilities/jail-create.cpp b/Userland/Utilities/jail-create.cpp new file mode 100644 index 00000000000..43d235c86e0 --- /dev/null +++ b/Userland/Utilities/jail-create.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +ErrorOr serenity_main(Main::Arguments arguments) +{ + StringView new_jail_name; + Core::ArgsParser args_parser; + args_parser.add_positional_argument(new_jail_name, "New jail name", "jail name"); + args_parser.parse(arguments); + + TRY(Core::System::pledge("stdio jail")); + + if (!new_jail_name.is_null() && !new_jail_name.is_empty()) { + TRY(Core::System::create_jail(new_jail_name)); + return 0; + } + + return Error::from_string_view("Can't create a jail with empty name."sv); +} diff --git a/Userland/Utilities/lsjails.cpp b/Userland/Utilities/lsjails.cpp new file mode 100644 index 00000000000..e817164b6c8 --- /dev/null +++ b/Userland/Utilities/lsjails.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +ErrorOr serenity_main(Main::Arguments) +{ + TRY(Core::System::pledge("stdio rpath")); + TRY(Core::System::unveil("/sys/kernel/jails", "r")); + TRY(Core::System::unveil(nullptr, nullptr)); + + auto jails_data = TRY(Core::Stream::File::open("/sys/kernel/jails"sv, Core::Stream::OpenMode::Read)); + + TRY(Core::System::pledge("stdio")); + + outln("Index Name"); + auto file_contents = TRY(jails_data->read_all()); + auto json = TRY(JsonValue::from_string(file_contents)); + json.as_array().for_each([](auto& value) { + auto& jail = value.as_object(); + auto index = jail.get("index"sv).to_string(); + auto name = jail.get("name"sv).to_string(); + + outln("{:4} {:10}", index, name); + }); + + return 0; +}