From 3c5d27506f216e38108d81ff07b0a12c25f773aa Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sat, 10 Jun 2023 01:12:30 +0200 Subject: [PATCH] base: stricter distinction between rx and rwx This patch restricts 'Region_map::attach_executable' to create read-only mappings, while offering the option to map the full rights using a new 'attach_rwx' method. The 'attach_rwx' method is now used by the dynamic linker to explicitly attach the linker area with full rwx rights. With the old page-fault handling code, the execute flag was evaluated only for leaf dataspaces, not for managed dataspaces while traversing region-map hierarchies. With the new page-fault handling code, the execute bit is downgraded to no-execute when passing a managed dataspace that is not attached as executable. Issue #4920 --- repos/base/include/region_map/region_map.h | 11 +++++++++-- repos/base/src/lib/ldso/include/region_map.h | 2 +- repos/ports/src/virtualbox5/generic/sup_vmm.cc | 5 ++--- repos/ports/src/virtualbox5/mm.h | 2 +- repos/ports/src/virtualbox5/spec/nova/sup.cc | 5 ++--- repos/ports/src/virtualbox6/sup_gmm.cc | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/repos/base/include/region_map/region_map.h b/repos/base/include/region_map/region_map.h index 201c902dcf..d3b1b568ad 100644 --- a/repos/base/include/region_map/region_map.h +++ b/repos/base/include/region_map/region_map.h @@ -127,11 +127,18 @@ struct Genode::Region_map : Interface return attach(ds, size, offset, true, local_addr); } /** - * Shortcut for attaching a dataspace executable at a predefined local address + * Shortcut for attaching a dataspace executable at local address */ Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr, size_t size = 0, off_t offset = 0) { - return attach(ds, size, offset, true, local_addr, true); } + return attach(ds, size, offset, true, local_addr, true, false ); } + + /** + * Shortcut for attaching a dataspace will full rights at local address + */ + Local_addr attach_rwx(Dataspace_capability ds, addr_t local_addr, + size_t size = 0, off_t offset = 0) { + return attach(ds, size, offset, true, local_addr, true, true ); } /** * Remove region from local address space diff --git a/repos/base/src/lib/ldso/include/region_map.h b/repos/base/src/lib/ldso/include/region_map.h index 3078e5b41d..0e2b32a2be 100644 --- a/repos/base/src/lib/ldso/include/region_map.h +++ b/repos/base/src/lib/ldso/include/region_map.h @@ -57,7 +57,7 @@ class Linker::Region_map Region_map(Env &env, Allocator &md_alloc, addr_t base) : _env(env), _range(&md_alloc), - _base((addr_t)_env.rm().attach_at(_rm.dataspace(), base)) + _base((addr_t)_env.rm().attach_rwx(_rm.dataspace(), base)) { _range.add_range(base, Pd_session::LINKER_AREA_SIZE); diff --git a/repos/ports/src/virtualbox5/generic/sup_vmm.cc b/repos/ports/src/virtualbox5/generic/sup_vmm.cc index d7033318a9..d73d2c3d93 100644 --- a/repos/ports/src/virtualbox5/generic/sup_vmm.cc +++ b/repos/ports/src/virtualbox5/generic/sup_vmm.cc @@ -135,9 +135,8 @@ static Sub_rm_connection &vm_memory(Genode::uint64_t vm_size = 0) while (allocated < memory_size) { Ram_dataspace_capability ds = genode_env().ram().alloc(alloc_size); - addr_t to = vm_memory.attach_executable(ds, memory.addr + - allocated - vmm_local, - alloc_size); + addr_t to = vm_memory.attach_rwx(ds, memory.addr + allocated - vmm_local, + alloc_size); Assert(to == vm_memory.local_addr(memory.addr + allocated - vmm_local)); allocated += alloc_size; diff --git a/repos/ports/src/virtualbox5/mm.h b/repos/ports/src/virtualbox5/mm.h index 24b28ee240..cbe51f9bc1 100644 --- a/repos/ports/src/virtualbox5/mm.h +++ b/repos/ports/src/virtualbox5/mm.h @@ -39,7 +39,7 @@ class Sub_rm_connection : private Genode::Rm_connection, : Rm_connection(env), Genode::Region_map_client(Rm_connection::create(size)), - _offset(env.rm().attach(dataspace())), + _offset(env.rm().attach(dataspace(), 0, 0, false, nullptr, true, true)), _size(size) { } diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 0d68c3af52..c2fed7af12 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -110,9 +110,8 @@ static Sub_rm_connection &vm_memory(Genode::uint64_t vm_size = 0) while (allocated < memory_size) { Ram_dataspace_capability ds = genode_env().ram().alloc(alloc_size); - addr_t to = vm_memory.attach_executable(ds, memory.addr + - allocated - vmm_local, - alloc_size); + addr_t to = vm_memory.attach_rwx(ds, memory.addr + allocated - vmm_local, + alloc_size); Assert(to == vm_memory.local_addr(memory.addr + allocated - vmm_local)); allocated += alloc_size; diff --git a/repos/ports/src/virtualbox6/sup_gmm.cc b/repos/ports/src/virtualbox6/sup_gmm.cc index b8ab54a944..33a13f429c 100644 --- a/repos/ports/src/virtualbox6/sup_gmm.cc +++ b/repos/ports/src/virtualbox6/sup_gmm.cc @@ -35,7 +35,7 @@ void Sup::Gmm::_add_one_slice() Ram_dataspace_capability ds = _env.ram().alloc(slice_size); _map.connection.retry_with_upgrade(Ram_quota{8192}, Cap_quota{2}, [&] () { - _map.rm.attach_executable(ds, attach_base, slice_size); }); + _map.rm.attach_rwx(ds, attach_base, slice_size); }); _slices[_slice_index(Offset{attach_base})] = ds;