mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
Add an 'executable' flag to 'Rm_session::attach()'
With this patch clients of the RM service can state if they want a mapping to be executable or not. This allows dataspaces to be mapped as non-executable on Linux by default and as executable only if needed. Partially fixes #176.
This commit is contained in:
parent
de92956220
commit
7a369bc74d
@ -25,7 +25,8 @@ using namespace Genode;
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
|
@ -34,7 +34,8 @@ namespace Genode {
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size = 0,
|
||||
off_t offset = 0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0);
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
|
@ -206,7 +206,8 @@ namespace Genode {
|
||||
**************************************/
|
||||
|
||||
Local_addr attach(Dataspace_capability ds, size_t size,
|
||||
off_t, bool, Local_addr);
|
||||
off_t, bool, Local_addr,
|
||||
bool executable);
|
||||
|
||||
void detach(Local_addr local_addr);
|
||||
|
||||
|
@ -34,9 +34,11 @@ namespace Genode {
|
||||
: _cap(session) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
|
||||
bool use_local_addr, Local_addr local_addr)
|
||||
bool use_local_addr, Local_addr local_addr,
|
||||
bool executable = false)
|
||||
{
|
||||
return _local()->attach(ds, size, offset, use_local_addr, local_addr);
|
||||
return _local()->attach(ds, size, offset, use_local_addr,
|
||||
local_addr, executable);
|
||||
}
|
||||
|
||||
void detach(Local_addr local_addr) {
|
||||
|
16
base-linux/src/base/env/rm_session_mmap.cc
vendored
16
base-linux/src/base/env/rm_session_mmap.cc
vendored
@ -43,7 +43,8 @@ static bool is_sub_rm_session(Dataspace_capability ds)
|
||||
|
||||
|
||||
static void *map_local(Dataspace_capability ds, Genode::size_t size,
|
||||
addr_t offset, bool use_local_addr, addr_t local_addr)
|
||||
addr_t offset, bool use_local_addr, addr_t local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Linux_dataspace::Filename fname = Linux_dataspace_client(ds).fname();
|
||||
fname.buf[sizeof(fname.buf) - 1] = 0;
|
||||
@ -56,7 +57,7 @@ static void *map_local(Dataspace_capability ds, Genode::size_t size,
|
||||
}
|
||||
|
||||
int flags = MAP_SHARED | (use_local_addr ? MAP_FIXED : 0);
|
||||
int prot = PROT_READ | PROT_EXEC | (writable ? PROT_WRITE : 0);
|
||||
int prot = PROT_READ | (writable ? PROT_WRITE : 0) | (executable ? PROT_EXEC : 0);
|
||||
void *addr = lx_mmap(use_local_addr ? (void*)local_addr : 0, size,
|
||||
prot, flags, fd, offset);
|
||||
|
||||
@ -84,7 +85,8 @@ Rm_session::Local_addr
|
||||
Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
||||
size_t size, off_t offset,
|
||||
bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
|
||||
@ -150,7 +152,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
||||
* and map it.
|
||||
*/
|
||||
if (_is_attached())
|
||||
map_local(ds, region_size, offset, true, _base + (addr_t)local_addr);
|
||||
map_local(ds, region_size, offset, true, _base + (addr_t)local_addr, executable);
|
||||
|
||||
return (void *)local_addr;
|
||||
|
||||
@ -197,7 +199,8 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
||||
continue;
|
||||
|
||||
map_local(region.dataspace(), region.size(), region.offset(),
|
||||
true, rm->_base + region.start() + region.offset());
|
||||
true, rm->_base + region.start() + region.offset(),
|
||||
executable);
|
||||
}
|
||||
|
||||
return rm->_base;
|
||||
@ -209,7 +212,8 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
||||
*
|
||||
* Boring, a plain dataspace is attached to a root RM session.
|
||||
*/
|
||||
void *addr = map_local(ds, region_size, offset, use_local_addr, local_addr);
|
||||
void *addr = map_local(ds, region_size, offset, use_local_addr,
|
||||
local_addr, executable);
|
||||
|
||||
_add_to_rmap(Region((addr_t)addr, offset, ds, region_size));
|
||||
|
||||
|
@ -39,7 +39,8 @@ class Context_area_rm_session : public Genode::Rm_session
|
||||
*/
|
||||
Local_addr attach(Genode::Dataspace_capability ds_cap,
|
||||
Genode::size_t size, Genode::off_t offset,
|
||||
bool use_local_addr, Local_addr local_addr)
|
||||
bool use_local_addr, Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace Genode {
|
||||
|
||||
void upgrade_ram_quota(size_t ram_quota) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr) {
|
||||
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) {
|
||||
return (addr_t)0; }
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
@ -25,7 +25,8 @@ using namespace Genode;
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
if (!ds)
|
||||
|
@ -34,7 +34,8 @@ namespace Genode {
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
||||
off_t offset=0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0);
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
|
@ -29,7 +29,8 @@ using namespace Genode;
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
if (!ds)
|
||||
|
@ -34,7 +34,8 @@ namespace Genode {
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
||||
off_t offset=0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0);
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
|
@ -22,7 +22,7 @@ using namespace Genode;
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr)
|
||||
Rm_session::Local_addr, bool executable)
|
||||
{
|
||||
using namespace Okl4;
|
||||
|
||||
|
@ -39,7 +39,8 @@ namespace Genode {
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
||||
off_t offset=0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0);
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
|
@ -46,7 +46,8 @@ namespace Genode {
|
||||
Local_addr attach(Dataspace_capability ds,
|
||||
size_t size = 0, off_t offset = 0,
|
||||
bool use_local_addr = false,
|
||||
Local_addr local_addr = (addr_t)0) {
|
||||
Local_addr local_addr = (addr_t)0,
|
||||
bool executable = false) {
|
||||
|
||||
bool try_again;
|
||||
do {
|
||||
@ -54,7 +55,8 @@ namespace Genode {
|
||||
try {
|
||||
return Rm_session_client::attach(ds, size, offset,
|
||||
use_local_addr,
|
||||
local_addr);
|
||||
local_addr,
|
||||
executable);
|
||||
|
||||
} catch (Rm_session::Out_of_metadata) {
|
||||
|
||||
|
@ -25,10 +25,12 @@ namespace Genode {
|
||||
: Rpc_client<Rm_session>(session) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
|
||||
bool use_local_addr, Local_addr local_addr)
|
||||
bool use_local_addr, Local_addr local_addr,
|
||||
bool executable = false)
|
||||
{
|
||||
return call<Rpc_attach>(ds, size, offset,
|
||||
use_local_addr, local_addr);
|
||||
use_local_addr, local_addr,
|
||||
executable);
|
||||
}
|
||||
|
||||
void detach(Local_addr local_addr) {
|
||||
|
@ -117,6 +117,7 @@ namespace Genode {
|
||||
* \param use_local_addr if set to true, attach the dataspace at
|
||||
* the specified 'local_addr'
|
||||
* \param local_addr local destination address
|
||||
* \param executable if the mapping should be executable
|
||||
*
|
||||
* \throw Attach_failed if dataspace or offset is invalid,
|
||||
* or on region conflict
|
||||
@ -128,7 +129,8 @@ namespace Genode {
|
||||
virtual Local_addr attach(Dataspace_capability ds,
|
||||
size_t size = 0, off_t offset = 0,
|
||||
bool use_local_addr = false,
|
||||
Local_addr local_addr = (addr_t)0) = 0;
|
||||
Local_addr local_addr = (addr_t)0,
|
||||
bool executable = false) = 0;
|
||||
|
||||
/**
|
||||
* Shortcut for attaching a dataspace at a predefined local address
|
||||
@ -137,6 +139,13 @@ namespace Genode {
|
||||
size_t size = 0, off_t offset = 0) {
|
||||
return attach(ds, size, offset, true, local_addr); }
|
||||
|
||||
/**
|
||||
* Shortcut for attaching a dataspace executable at a predefined 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); }
|
||||
|
||||
/**
|
||||
* Remove region from local address space
|
||||
*/
|
||||
@ -179,7 +188,7 @@ namespace Genode {
|
||||
GENODE_RPC_THROW(Rpc_attach, Local_addr, attach,
|
||||
GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict,
|
||||
Out_of_metadata, Invalid_args),
|
||||
Dataspace_capability, size_t, off_t, bool, Local_addr);
|
||||
Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
|
||||
GENODE_RPC(Rpc_detach, void, detach, Local_addr);
|
||||
GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
|
||||
GENODE_TYPE_LIST(Invalid_thread, Out_of_memory),
|
||||
|
@ -42,15 +42,15 @@ if [have_spec linux_x86_32] {
|
||||
puts "Error: detaching from sub RM session failed"
|
||||
exit -1
|
||||
}
|
||||
if {![regexp {60040000-60044000 rwxs} $maps]} {
|
||||
if {![regexp {60040000-60044000 rw.s} $maps]} {
|
||||
puts "Error: populating already attached sub RM session failed"
|
||||
exit -1
|
||||
}
|
||||
if {![regexp {60080000-60083000 rwxs 00001000} $maps]} {
|
||||
if {![regexp {60080000-60083000 rw.s 00001000} $maps]} {
|
||||
puts "Error: using offset parameter to sub RM attach did not work"
|
||||
exit -1
|
||||
}
|
||||
if {![regexp {600c0000-600c2000 rwxs 00001000} $maps]} {
|
||||
if {![regexp {600c0000-600c2000 rw.s 00001000} $maps]} {
|
||||
puts "Error: using offset and size parameters to sub RM attach did not work"
|
||||
exit -1
|
||||
}
|
||||
|
@ -84,8 +84,11 @@ static addr_t _setup_elf(Parent_capability parent_cap,
|
||||
bool parent_info = false;
|
||||
off_t offset;
|
||||
Dataspace_capability ds_cap;
|
||||
void *out_ptr = 0;
|
||||
|
||||
bool write = seg.flags().w;
|
||||
bool exec = seg.flags().x;
|
||||
|
||||
if (write) {
|
||||
|
||||
/* read-write segment */
|
||||
@ -133,6 +136,9 @@ static addr_t _setup_elf(Parent_capability parent_cap,
|
||||
/* detach dataspace */
|
||||
env()->rm_session()->detach(base);
|
||||
|
||||
try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
|
||||
catch (Rm_session::Attach_failed) { }
|
||||
|
||||
} else {
|
||||
|
||||
/* read-only segment */
|
||||
@ -142,11 +148,14 @@ static addr_t _setup_elf(Parent_capability parent_cap,
|
||||
/* XXX currently we assume r/o segment sizes never differ */
|
||||
if (seg.file_size() != seg.mem_size())
|
||||
PWRN("filesz and memsz for read-only segment differ");
|
||||
}
|
||||
|
||||
void *out_ptr = 0;
|
||||
try { out_ptr = rm.attach(ds_cap, size, offset, true, addr); }
|
||||
catch (Rm_session::Attach_failed) { }
|
||||
if (exec)
|
||||
try { out_ptr = rm.attach_executable(ds_cap, addr, size, offset); }
|
||||
catch (Rm_session::Attach_failed) { }
|
||||
else
|
||||
try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
|
||||
catch (Rm_session::Attach_failed) { }
|
||||
}
|
||||
|
||||
if ((addr_t)out_ptr != addr)
|
||||
PWRN("addresses differ after attach (addr=%p out_ptr=%p)",
|
||||
|
@ -49,7 +49,8 @@ class Context_area_rm_session : public Rm_session
|
||||
*/
|
||||
Local_addr attach(Dataspace_capability ds_cap,
|
||||
size_t size, off_t offset,
|
||||
bool use_local_addr, Local_addr local_addr)
|
||||
bool use_local_addr, Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Dataspace_component *ds =
|
||||
dynamic_cast<Dataspace_component*>(Dataspace_capability::deref(ds_cap));
|
||||
|
@ -38,7 +38,8 @@ namespace Genode {
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
||||
off_t offset=0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0)
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
if (!ds)
|
||||
|
@ -342,7 +342,7 @@ namespace Genode {
|
||||
** Region manager session interface **
|
||||
**************************************/
|
||||
|
||||
Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr);
|
||||
Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
|
||||
void detach (Local_addr);
|
||||
Pager_capability add_client (Thread_capability);
|
||||
void fault_handler (Signal_context_capability handler);
|
||||
|
@ -318,7 +318,8 @@ void Rm_faulter::continue_after_resolved_fault()
|
||||
Rm_session::Local_addr
|
||||
Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
/* serialize access */
|
||||
Lock::Guard lock_guard(_lock);
|
||||
|
@ -78,6 +78,13 @@ namespace Genode {
|
||||
size_t size = 0, off_t offset = 0) {
|
||||
return Rm_connection::attach_at(ds, local_addr - _base, size, offset); }
|
||||
|
||||
/**
|
||||
* Overwritten from 'Rm_connection'
|
||||
*/
|
||||
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
|
||||
size_t size = 0, off_t offset = 0) {
|
||||
return Rm_connection::attach_executable(ds, local_addr - _base, size, offset); }
|
||||
|
||||
void detach(Local_addr local_addr) {
|
||||
Rm_connection::detach((addr_t)local_addr - _base); }
|
||||
};
|
||||
@ -128,7 +135,7 @@ namespace Genode {
|
||||
void setup_text(addr_t vaddr, size_t size, off_t offset)
|
||||
{
|
||||
_vaddr = vaddr;
|
||||
Rm_area::r()->attach_at(_ds_rom, vaddr, size, offset);
|
||||
Rm_area::r()->attach_executable(_ds_rom, vaddr, size, offset);
|
||||
}
|
||||
|
||||
addr_t alloc_region(addr_t vaddr, addr_t vlimit)
|
||||
|
@ -57,7 +57,8 @@ Rm_session_component::Region *Rm_session_component::find_region(void *local_addr
|
||||
Rm_session::Local_addr
|
||||
Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr)
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
if (verbose)
|
||||
PDBG("size = %zd, offset = %x", size, (unsigned int)offset);
|
||||
@ -76,7 +77,9 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
throw Invalid_args();
|
||||
}
|
||||
|
||||
void *addr = _parent_rm_session.attach(ds_cap, size, offset, use_local_addr, local_addr);
|
||||
void *addr = _parent_rm_session.attach(ds_cap, size, offset,
|
||||
use_local_addr, local_addr,
|
||||
executable);
|
||||
|
||||
Lock::Guard lock_guard(_region_map_lock);
|
||||
_region_map.insert(new (env()->heap()) Region(addr, (void*)((addr_t)addr + size - 1), ds_cap, offset));
|
||||
|
@ -93,7 +93,7 @@ namespace Gdb_monitor {
|
||||
**************************************/
|
||||
|
||||
Local_addr attach (Dataspace_capability, Genode::size_t,
|
||||
Genode::off_t, bool, Local_addr);
|
||||
Genode::off_t, bool, Local_addr, bool);
|
||||
void detach (Local_addr);
|
||||
Pager_capability add_client (Thread_capability);
|
||||
void fault_handler (Signal_context_capability handler);
|
||||
|
@ -188,7 +188,8 @@ namespace Noux {
|
||||
Local_addr attach(Dataspace_capability ds,
|
||||
size_t size = 0, off_t offset = 0,
|
||||
bool use_local_addr = false,
|
||||
Local_addr local_addr = (addr_t)0)
|
||||
Local_addr local_addr = (addr_t)0,
|
||||
bool executable = false)
|
||||
{
|
||||
if (size == 0)
|
||||
size = Dataspace_client(ds).size();
|
||||
@ -199,7 +200,8 @@ namespace Noux {
|
||||
*/
|
||||
|
||||
local_addr = _rm.attach(ds, size, offset,
|
||||
use_local_addr, local_addr);
|
||||
use_local_addr, local_addr,
|
||||
executable);
|
||||
|
||||
/*
|
||||
* Record attachement for later replay (needed during
|
||||
|
Loading…
Reference in New Issue
Block a user