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; Region_map &_local_rm;
Range_allocator &_core_mem; 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) 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); if (_managing_system(args) == Pd_session_component::Managing_system::DENIED)
addr_t const size = Arg_string::find_arg(args, "phys_size").ulong_value(0); return Ram_dataspace_factory::any_phys_range();
addr_t const end = start + size - 1;
return (start <= end) ? Ram_dataspace_factory::Phys_range { start, end } addr_t const start = 0;
: Ram_dataspace_factory::any_phys_range(); 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) 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 * Unset the 'managing_system' argument unless explicitly permitted by the
* explicitly permitted by the child configuration. * child configuration.
*/ */
if (service == Pd_session::service_name()) { if (service == Pd_session::service_name()) {
/* /*
* If the child is allowed to constrain physical memory allocations, * For an environment PD session created by us for a direct child, the
* pass the child-provided constraints as session arguments to core. * client's 'managing_system' argument is inferred from the child's
* If no constraints are specified, we apply the constraints for * <start> node. Otherwise, for PD sessions initiated by a subsystem,
* allocating DMA memory (as the only use case for the constrain-phys * the argument is provided by the originator of the session request.
* mechanism).
*/ */
if (_managing_system) { bool const direct_child = (session_label_from_args(args) == name());
addr_t start = 0;
addr_t size = (sizeof(long) == 4) ? 0xc0000000UL : 0x100000000UL;
Arg_string::find_arg(args, "phys_start").ulong_value(start); if (direct_child && _managing_system)
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());
Arg_string::set_arg(args, args_len, "managing_system", "yes"); Arg_string::set_arg(args, args_len, "managing_system", "yes");
} else {
Arg_string::remove_arg(args, "phys_start"); bool const client_arg = Arg_string::find_arg(args, "managing_system").bool_value(false);
Arg_string::remove_arg(args, "phys_size");
/*
* 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"); Arg_string::remove_arg(args, "managing_system");
}
} }
} }