mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
libc: resolve symlinks in execve
This patch complements the commit "libc: execve" with the ability to execute files stored at arbitrary sub directories of the file system. Issue #3481 Issue #3500
This commit is contained in:
parent
697d496093
commit
ab5187d673
@ -16,9 +16,13 @@ install_config {
|
||||
<arg value="name_of_executeable"/>
|
||||
<arg value="100"/>
|
||||
<libc stdin="/null" stdout="/log" stderr="/log"/>
|
||||
<vfs> <null/> <log/> </vfs>
|
||||
<vfs> <rom name="test-execve"/> <null/> <log/> </vfs>
|
||||
</config>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
<route>
|
||||
<service name="ROM" label="/test-execve">
|
||||
<parent label="test-execve"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <internal/call_func.h>
|
||||
#include <internal/init.h>
|
||||
#include <internal/errno.h>
|
||||
#include <internal/file_operations.h>
|
||||
|
||||
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<main_fn_ptr>(*_env_ptr, filename, "main");
|
||||
_main_ptr = Dynamic_linker::respawn<main_fn_ptr>(*_env_ptr, resolved_path.string(), "main");
|
||||
}
|
||||
catch (Dynamic_linker::Invalid_symbol) {
|
||||
error("Dynamic_linker::respawn could not obtain binary entry point");
|
||||
|
@ -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();
|
||||
|
35
repos/libports/src/lib/libc/internal/file_operations.h
Normal file
35
repos/libports/src/lib/libc/internal/file_operations.h
Normal file
@ -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 <os/path.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <limits.h> /* for 'PATH_MAX' */
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <internal/types.h>
|
||||
|
||||
namespace Libc {
|
||||
|
||||
typedef Genode::Path<PATH_MAX> Absolute_path;
|
||||
|
||||
class Symlink_resolve_error : Exception { };
|
||||
|
||||
void resolve_symlinks(char const *path, Absolute_path &resolved_path);
|
||||
}
|
||||
|
||||
#endif /* _LIBC__INTERNAL__FILE_OPERATIONS_H_ */
|
@ -87,7 +87,7 @@ install_config {
|
||||
</dir>
|
||||
</vfs>
|
||||
|
||||
<policy label_prefix="vfs_rom" root="/bin"/>
|
||||
<policy label_prefix="vfs_rom" root="/"/>
|
||||
<default-policy root="/" writeable="yes"/>
|
||||
</config>
|
||||
</start>
|
||||
@ -103,7 +103,7 @@ install_config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="bash" caps="1000">
|
||||
<start name="/bin/bash" caps="1000">
|
||||
<resource name="RAM" quantum="30M" />
|
||||
<config>
|
||||
<libc stdin="/dev/terminal" stdout="/dev/terminal"
|
||||
@ -115,9 +115,9 @@ install_config {
|
||||
</config>
|
||||
<route>
|
||||
<service name="File_system"> <child name="vfs"/> </service>
|
||||
<service name="ROM" label_last="bash"> <child name="vfs_rom"/> </service>
|
||||
<service name="ROM" label_suffix=".lib.so"> <parent/> </service>
|
||||
<service name="ROM" label_prefix=""> <child name="vfs_rom"/> </service>
|
||||
<service name="ROM" label_last="/bin/bash"> <child name="vfs_rom"/> </service>
|
||||
<service name="ROM" label_prefix="/bin"> <child name="vfs_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
Loading…
x
Reference in New Issue
Block a user