From 6a62f752740f24eb219bf216c03da6bb9dba043a Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 26 Jan 2017 07:35:19 +0100 Subject: [PATCH 1/4] Allow privileged containers for systems without user namespace support --- src/anbox/cmds/container_manager.cpp | 5 ++++- src/anbox/cmds/container_manager.h | 1 + src/anbox/container/lxc_container.cpp | 12 ++++++------ src/anbox/container/lxc_container.h | 3 ++- src/anbox/container/service.cpp | 18 ++++++++---------- src/anbox/container/service.h | 6 ++++-- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index a688f1f..f2d5fb0 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -45,6 +45,9 @@ anbox::cmds::ContainerManager::ContainerManager() flag(cli::make_flag(cli::Name{"data-path"}, cli::Description{"Path where the container and its data is stored"}, data_path_)); + flag(cli::make_flag(cli::Name{"privileged"}, + cli::Description{"Run Android container in privileged mode"}, + privileged_)); action([&](const cli::Command::Context&) { try { @@ -62,7 +65,7 @@ anbox::cmds::ContainerManager::ContainerManager() return EXIT_FAILURE; auto rt = Runtime::create(); - auto service = container::Service::create(rt); + auto service = container::Service::create(rt, privileged_); rt->start(); trap->run(); diff --git a/src/anbox/cmds/container_manager.h b/src/anbox/cmds/container_manager.h index 36bd2a7..4525756 100644 --- a/src/anbox/cmds/container_manager.h +++ b/src/anbox/cmds/container_manager.h @@ -41,6 +41,7 @@ class ContainerManager : public cli::CommandWithFlagsAndAction { std::string data_path_; std::shared_ptr android_img_loop_dev_; std::vector> mounts_; + bool privileged_ = false; }; } // namespace cmds } // namespace anbox diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index e8e532e..3faf842 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -35,8 +35,8 @@ namespace fs = boost::filesystem; namespace anbox { namespace container { -LxcContainer::LxcContainer(const network::Credentials &creds) - : state_(State::inactive), container_(nullptr), creds_(creds) { +LxcContainer::LxcContainer(bool privileged, const network::Credentials &creds) + : state_(State::inactive), container_(nullptr), privileged_(privileged), creds_(creds) { utils::ensure_paths({ SystemConfiguration::instance().container_config_dir(), SystemConfiguration::instance().log_dir(), @@ -44,16 +44,15 @@ LxcContainer::LxcContainer(const network::Credentials &creds) } LxcContainer::~LxcContainer() { - DEBUG(""); - stop(); - if (container_) lxc_container_put(container_); } void LxcContainer::setup_id_maps() { + // FIXME make these id sets configurable 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", @@ -150,7 +149,8 @@ void LxcContainer::start(const Configuration &configuration) { set_config_item("lxc.aa_profile", "unconfined"); #endif - setup_id_maps(); + if (!privileged_) + setup_id_maps(); auto bind_mounts = configuration.bind_mounts; diff --git a/src/anbox/container/lxc_container.h b/src/anbox/container/lxc_container.h index 9302fad..886a9d4 100644 --- a/src/anbox/container/lxc_container.h +++ b/src/anbox/container/lxc_container.h @@ -29,7 +29,7 @@ namespace anbox { namespace container { class LxcContainer : public Container { public: - LxcContainer(const network::Credentials &creds); + LxcContainer(bool privileged, const network::Credentials &creds); ~LxcContainer(); void start(const Configuration &configuration) override; @@ -42,6 +42,7 @@ class LxcContainer : public Container { State state_; lxc_container *container_; + bool privileged_; network::Credentials creds_; }; } // namespace container diff --git a/src/anbox/container/service.cpp b/src/anbox/container/service.cpp index 3b0f6fe..667d1bb 100644 --- a/src/anbox/container/service.cpp +++ b/src/anbox/container/service.cpp @@ -30,8 +30,8 @@ namespace anbox { namespace container { -std::shared_ptr Service::create(const std::shared_ptr &rt) { - auto sp = std::make_shared(rt); +std::shared_ptr Service::create(const std::shared_ptr &rt, bool privileged) { + auto sp = std::shared_ptr(new Service(rt, privileged)); auto delegate_connector = std::make_shared< network::DelegateConnectionCreator>( @@ -49,34 +49,32 @@ std::shared_ptr Service::create(const std::shared_ptr &rt) { return sp; } -Service::Service(const std::shared_ptr &rt) +Service::Service(const std::shared_ptr &rt, bool privileged) : dispatcher_(anbox::common::create_dispatcher_for_runtime(rt)), next_connection_id_(0), - connections_( - std::make_shared>()) { + connections_(std::make_shared>()), + privileged_(privileged) { } Service::~Service() {} int Service::next_id() { return next_connection_id_++; } -void Service::new_client( - std::shared_ptr const +void Service::new_client(std::shared_ptr const &socket) { if (connections_->size() >= 1) { socket->close(); return; } - auto const messenger = - std::make_shared(socket); + auto const messenger = std::make_shared(socket); DEBUG("Got connection from pid %d", messenger->creds().pid()); auto pending_calls = std::make_shared(); auto rpc_channel = std::make_shared(pending_calls, messenger); auto server = std::make_shared( - pending_calls, std::make_shared(messenger->creds())); + pending_calls, std::make_shared(privileged_, messenger->creds())); auto processor = std::make_shared( messenger, pending_calls, server); diff --git a/src/anbox/container/service.h b/src/anbox/container/service.h index 7aaf006..30a6fa1 100644 --- a/src/anbox/container/service.h +++ b/src/anbox/container/service.h @@ -30,12 +30,13 @@ namespace anbox { namespace container { class Service : public std::enable_shared_from_this { public: - static std::shared_ptr create(const std::shared_ptr &rt); + static std::shared_ptr create(const std::shared_ptr &rt, bool privileged); - Service(const std::shared_ptr &rt); ~Service(); private: + Service(const std::shared_ptr &rt, bool privileged); + int next_id(); void new_client(std::shared_ptr< boost::asio::local::stream_protocol::socket> const &socket); @@ -45,6 +46,7 @@ class Service : public std::enable_shared_from_this { std::atomic next_connection_id_; std::shared_ptr> connections_; std::shared_ptr backend_; + bool privileged_; }; } // namespace container } // namespace anbox From 17bdff54c2b867ff05feb2233cd864c5bc65b486 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 26 Jan 2017 07:36:26 +0100 Subject: [PATCH 2/4] Mark SDL2 as required build dependency --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f8de6d..b209469 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,8 +63,7 @@ find_package(EGL REQUIRED) find_package(GLESv2 REQUIRED) find_package(Protobuf REQUIRED) -pkg_check_modules(SDL2 sdl2) - +pkg_check_modules(SDL2 sdl2 REQUIRED) pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) pkg_check_modules(DBUS dbus-1 REQUIRED) pkg_check_modules(LXC lxc REQUIRED) From 53b8071e6ae617ce56472ebbdb0036532994a57c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 26 Jan 2017 07:36:53 +0100 Subject: [PATCH 3/4] On systems we run against Mir we also need to build against it --- CMakeLists.txt | 4 ++++ src/CMakeLists.txt | 4 ++++ src/anbox/ubuntu/window.cpp | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b209469..328aec3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,10 @@ pkg_check_modules(SDL2 sdl2 REQUIRED) pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) pkg_check_modules(DBUS dbus-1 REQUIRED) pkg_check_modules(LXC lxc REQUIRED) +pkg_check_modules(MIRCLIENT mirclient) +if (MIRCLIENT_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMIR_SUPPORT") +endif() ##################################################################### # Enable code coverage calculation with gcov/gcovr/lcov diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 02a38a9..22113c4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,9 +8,11 @@ include_directories( ${DBUS_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} ${LXC_INCLUDE_DIRS} + ${MIRCLIENT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/external ${CMAKE_SOURCE_DIR}/external/process-cpp-minimal/include ${CMAKE_SOURCE_DIR}/external/android-emugl/shared ${CMAKE_SOURCE_DIR}/external/android-emugl/host/include @@ -205,6 +207,8 @@ target_link_libraries(anbox-core ${SDL2_LIBRARIES} ${LXC_LDFLAGS} ${LXC_LIBRARIES} + ${MIRCLIENT_LDFLAGS} + ${MIRCLIENT_LIBRARIES} pthread process-cpp emugl_common diff --git a/src/anbox/ubuntu/window.cpp b/src/anbox/ubuntu/window.cpp index 8140c99..d87d1e6 100644 --- a/src/anbox/ubuntu/window.cpp +++ b/src/anbox/ubuntu/window.cpp @@ -23,6 +23,10 @@ #include +#if defined(MIR_SUPPORT) +#include +#endif + #include #pragma GCC diagnostic pop @@ -58,10 +62,17 @@ Window::Window(const std::shared_ptr &renderer, SDL_GetWindowWMInfo(window_, &info); switch (info.subsystem) { case SDL_SYSWM_X11: - native_display_ = - static_cast(info.info.x11.display); + native_display_ = static_cast(info.info.x11.display); native_window_ = static_cast(info.info.x11.window); break; +#if defined(MIR_SUPPORT) + case SDL_SYSWM_MIR: { + native_display_ = static_cast(mir_connection_get_egl_native_display(info.info.mir.connection)); + auto buffer_stream = mir_surface_get_buffer_stream(info.info.mir.surface); + native_window_ = reinterpret_cast(mir_buffer_stream_get_egl_native_window(buffer_stream)); + break; + } +#endif default: ERROR("Unknown subsystem (%d)", info.subsystem); BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not suported")); From bdcfbd47dd3a2e4b206e567091d530c43e0d4187 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 26 Jan 2017 07:37:17 +0100 Subject: [PATCH 4/4] Print detailed error message when SDL initialization fails --- src/anbox/ubuntu/platform_policy.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/anbox/ubuntu/platform_policy.cpp b/src/anbox/ubuntu/platform_policy.cpp index f60db21..17992a6 100644 --- a/src/anbox/ubuntu/platform_policy.cpp +++ b/src/anbox/ubuntu/platform_policy.cpp @@ -40,8 +40,10 @@ PlatformPolicy::PlatformPolicy( : input_manager_(input_manager), android_api_(android_api), event_thread_running_(false) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL")); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0) { + const auto message = utils::string_format("Failed to initialize SDL: %s", SDL_GetError()); + BOOST_THROW_EXCEPTION(std::runtime_error(message)); + } auto display_frame = graphics::Rect::Invalid; for (auto n = 0; n < SDL_GetNumVideoDisplays(); n++) {