base: be more restrictive with 'managing_system'

* Only give managing_system permission when all parent nodes of the
  corresponding component agree in doing so.
* Move the physical memory constrains heuristic from sandbox library to core

Fix #4335
This commit is contained in:
Stefan Kalkowski 2021-11-24 17:37:41 +01:00 committed by Christian Helmuth
parent 916683b6d6
commit 14de84fae6
2 changed files with 31 additions and 24 deletions

View File

@ -36,14 +36,22 @@ class Genode::Pd_root : public Genode::Root_component<Genode::Pd_session_compone
Region_map &_local_rm;
Range_allocator &_core_mem;
/**
* The RAM allocations of system management components are getting
* constrained to support older devices with 32-bit physical memory
* address capabilities only, and to by compliant to certain 32-bit
* kernel limitations mapping device memory 1:1 into the lower 3 GB
*/
static Ram_dataspace_factory::Phys_range _phys_range_from_args(char const *args)
{
addr_t const start = Arg_string::find_arg(args, "phys_start").ulong_value(0);
addr_t const size = Arg_string::find_arg(args, "phys_size").ulong_value(0);
addr_t const end = start + size - 1;
if (_managing_system(args) == Pd_session_component::Managing_system::DENIED)
return Ram_dataspace_factory::any_phys_range();
return (start <= end) ? Ram_dataspace_factory::Phys_range { start, end }
: Ram_dataspace_factory::any_phys_range();
addr_t const start = 0;
addr_t const end = (sizeof(long) == 4) /* 32bit arch ? */
? 0xbfffffffUL : 0xffffffffUL;
return Ram_dataspace_factory::Phys_range { start, end };
}
static Ram_dataspace_factory::Virt_range _virt_range_from_args(char const *args)

View File

@ -647,33 +647,32 @@ void Sandbox::Child::filter_session_args(Service::Name const &service,
}
/*
* Remove phys_start and phys_size RAM-session arguments unless
* explicitly permitted by the child configuration.
* Unset the 'managing_system' argument unless explicitly permitted by the
* child configuration.
*/
if (service == Pd_session::service_name()) {
/*
* If the child is allowed to constrain physical memory allocations,
* pass the child-provided constraints as session arguments to core.
* If no constraints are specified, we apply the constraints for
* allocating DMA memory (as the only use case for the constrain-phys
* mechanism).
* For an environment PD session created by us for a direct child, the
* client's 'managing_system' argument is inferred from the child's
* <start> node. Otherwise, for PD sessions initiated by a subsystem,
* the argument is provided by the originator of the session request.
*/
if (_managing_system) {
addr_t start = 0;
addr_t size = (sizeof(long) == 4) ? 0xc0000000UL : 0x100000000UL;
bool const direct_child = (session_label_from_args(args) == name());
Arg_string::find_arg(args, "phys_start").ulong_value(start);
Arg_string::find_arg(args, "phys_size") .ulong_value(size);
Arg_string::set_arg(args, args_len, "phys_start", String<32>(Hex(start)).string());
Arg_string::set_arg(args, args_len, "phys_size", String<32>(Hex(size)) .string());
if (direct_child && _managing_system)
Arg_string::set_arg(args, args_len, "managing_system", "yes");
} else {
Arg_string::remove_arg(args, "phys_start");
Arg_string::remove_arg(args, "phys_size");
bool const client_arg = Arg_string::find_arg(args, "managing_system").bool_value(false);
/*
* Preserve the client's wish for a 'managing_system' permission only
* if the <start> node of the subsystem allows.
*/
bool const permitted = (_managing_system && client_arg);
if (!permitted)
Arg_string::remove_arg(args, "managing_system");
}
}
}