提交 7a2cef31 编写于 作者: S Simon Fels

Run container as unprivileged for enhanced security

On the Android side this requires no change with the current setup.
上级 128cc242
......@@ -35,7 +35,8 @@ namespace fs = boost::filesystem;
namespace anbox {
namespace container {
LxcContainer::LxcContainer() : state_(State::inactive), container_(nullptr) {
LxcContainer::LxcContainer(const network::Credentials &creds)
: state_(State::inactive), container_(nullptr), creds_(creds) {
utils::ensure_paths({
config::container_config_path(), config::log_path(),
});
......@@ -49,6 +50,32 @@ LxcContainer::~LxcContainer() {
if (container_) lxc_container_put(container_);
}
void LxcContainer::setup_id_maps() {
const auto base_id = 100000;
const auto max_id = 65536;
set_config_item("lxc.id_map",
utils::string_format("u 0 %d %d", base_id, creds_.uid() - 1));
set_config_item("lxc.id_map",
utils::string_format("g 0 %d %d", base_id, creds_.gid() - 1));
// We need to bind the user id for the one running the client side
// process as he is the owner of various socket files we bind mount
// into the container.
set_config_item("lxc.id_map",
utils::string_format("u %d %d 1", creds_.uid(), creds_.uid()));
set_config_item("lxc.id_map",
utils::string_format("g %d %d 1", creds_.gid(), creds_.gid()));
set_config_item("lxc.id_map",
utils::string_format("u %d %d %d", creds_.uid() + 1,
base_id + creds_.uid() + 1,
max_id - creds_.uid() - 1));
set_config_item("lxc.id_map",
utils::string_format("g %d %d %d", creds_.uid() + 1,
base_id + creds_.gid() + 1,
max_id - creds_.gid() - 1));
}
void LxcContainer::start(const Configuration &configuration) {
if (getuid() != 0)
BOOST_THROW_EXCEPTION(
......@@ -128,7 +155,20 @@ void LxcContainer::start(const Configuration &configuration) {
set_config_item("lxc.aa_profile", "unconfined");
#endif
for (const auto &bind_mount : configuration.bind_mounts) {
setup_id_maps();
auto bind_mounts = configuration.bind_mounts;
// Extra bind-mounts for user-namespace setup
bind_mounts.insert({"/dev/console", "dev/console"});
bind_mounts.insert({"/dev/full", "dev/full"});
bind_mounts.insert({"/dev/null", "dev/null"});
bind_mounts.insert({"/dev/random", "dev/random"});
bind_mounts.insert({"/dev/tty", "dev/tty"});
bind_mounts.insert({"/dev/urandom", "dev/urandom"});
bind_mounts.insert({"/dev/zero", "dev/zero"});
for (const auto &bind_mount : bind_mounts) {
std::string create_type = "file";
if (fs::is_directory(bind_mount.first)) create_type = "dir";
......
......@@ -19,6 +19,7 @@
#define ANBOX_CONTAINER_LXC_CONTAINER_H_
#include "anbox/container/container.h"
#include "anbox/network/credentials.h"
#include <string>
......@@ -28,7 +29,7 @@ namespace anbox {
namespace container {
class LxcContainer : public Container {
public:
LxcContainer();
LxcContainer(const network::Credentials &creds);
~LxcContainer();
void start(const Configuration &configuration) override;
......@@ -37,9 +38,11 @@ class LxcContainer : public Container {
private:
void set_config_item(const std::string &key, const std::string &value);
void setup_id_maps();
State state_;
lxc_container *container_;
network::Credentials creds_;
};
} // namespace container
} // namespace anbox
......
......@@ -59,8 +59,6 @@ void ManagementApiSkeleton::start_container(
utils::string_format("Failed to start container: %s", err.what()));
}
DEBUG("");
done->Run();
}
} // namespace container
......
......@@ -77,7 +77,7 @@ void Service::new_client(
auto pending_calls = std::make_shared<rpc::PendingCallCache>();
auto rpc_channel = std::make_shared<rpc::Channel>(pending_calls, messenger);
auto server = std::make_shared<container::ManagementApiSkeleton>(
pending_calls, std::make_shared<LxcContainer>());
pending_calls, std::make_shared<LxcContainer>(messenger->creds()));
auto processor = std::make_shared<container::ManagementApiMessageProcessor>(
messenger, pending_calls, server);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册