diff --git a/repos/libports/run/execve.run b/repos/libports/run/execve.run index 424c32dab..c20fcd75c 100644 --- a/repos/libports/run/execve.run +++ b/repos/libports/run/execve.run @@ -16,9 +16,13 @@ install_config { - + - + + + + + } diff --git a/repos/libports/src/lib/libc/execve.cc b/repos/libports/src/lib/libc/execve.cc index ee9000e4a..5a89d6141 100644 --- a/repos/libports/src/lib/libc/execve.cc +++ b/repos/libports/src/lib/libc/execve.cc @@ -25,6 +25,7 @@ #include #include #include +#include using namespace Genode; @@ -161,6 +162,13 @@ extern "C" int execve(char const *filename, return Libc::Errno(EACCES); } + Libc::Absolute_path resolved_path; + try { + Libc::resolve_symlinks(filename, resolved_path); } + catch (Libc::Symlink_resolve_error) { + warning("execve: ", filename, " does not exist"); + return Libc::Errno(ENOENT); } + /* capture environment variables and args to libc-internal heap */ Libc::String_array *saved_env_vars = new (*_alloc_ptr) Libc::String_array(*_alloc_ptr, envp); @@ -169,7 +177,7 @@ extern "C" int execve(char const *filename, new (*_alloc_ptr) Libc::String_array(*_alloc_ptr, argv); try { - _main_ptr = Dynamic_linker::respawn(*_env_ptr, filename, "main"); + _main_ptr = Dynamic_linker::respawn(*_env_ptr, resolved_path.string(), "main"); } catch (Dynamic_linker::Invalid_symbol) { error("Dynamic_linker::respawn could not obtain binary entry point"); diff --git a/repos/libports/src/lib/libc/fork.cc b/repos/libports/src/lib/libc/fork.cc index 8f81f8a17..1b9807b56 100644 --- a/repos/libports/src/lib/libc/fork.cc +++ b/repos/libports/src/lib/libc/fork.cc @@ -478,12 +478,21 @@ struct Libc::Forked_child : Child_policy, Child_ready Route resolve_session_request(Service::Name const &name, Session_label const &label) override { + Session_label rewritten_label = label; + Service *service_ptr = nullptr; if (_state == State::STARTING_UP && name == Clone_session::service_name()) service_ptr = &_local_clone_service.service; if (name == Rom_session::service_name()) { + /* + * Strip off the originating child name to allow the application of + * routing rules based on the leading path elements, regardless + * of which child in the process hierarchy requests a ROM. + */ + rewritten_label = label.last_element(); + try { service_ptr = &_local_rom_services.matching_service(name, label); } catch (...) { } @@ -496,7 +505,7 @@ struct Libc::Forked_child : Child_policy, Child_ready if (service_ptr) return Route { .service = *service_ptr, - .label = label, + .label = rewritten_label, .diag = Session::Diag() }; throw Service_denied(); diff --git a/repos/libports/src/lib/libc/internal/file_operations.h b/repos/libports/src/lib/libc/internal/file_operations.h new file mode 100644 index 000000000..1d9366e79 --- /dev/null +++ b/repos/libports/src/lib/libc/internal/file_operations.h @@ -0,0 +1,35 @@ +/* + * \brief Libc-internal file operations + * \author Norman Feske + * \date 2019-09-23 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _LIBC__INTERNAL__FILE_OPERATIONS_H_ +#define _LIBC__INTERNAL__FILE_OPERATIONS_H_ + +/* Genode includes */ +#include + +/* libc includes */ +#include /* for 'PATH_MAX' */ + +/* libc-internal includes */ +#include + +namespace Libc { + + typedef Genode::Path Absolute_path; + + class Symlink_resolve_error : Exception { }; + + void resolve_symlinks(char const *path, Absolute_path &resolved_path); +} + +#endif /* _LIBC__INTERNAL__FILE_OPERATIONS_H_ */ diff --git a/repos/ports/run/bash.run b/repos/ports/run/bash.run index 6fcf0f55a..f88a61a99 100644 --- a/repos/ports/run/bash.run +++ b/repos/ports/run/bash.run @@ -87,7 +87,7 @@ install_config { - + @@ -103,7 +103,7 @@ install_config { - + - - + +