From de5c0603f11cbb38ace62c9367c57428e04f88ae Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sun, 12 Nov 2017 19:40:13 -0600 Subject: [PATCH] platform_drv: account session capabilities with a Cap_quota_guard The platform driver is a critical component and must not allow sessions to deplete its own resource quotas. Fix #2576 --- .../src/drivers/platform/spec/x86/device_pd.h | 36 +++++++-------- .../platform/spec/x86/pci_session_component.h | 46 +++++++++++-------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd.h b/repos/os/src/drivers/platform/spec/x86/device_pd.h index bb424774c..9c53d7bc7 100644 --- a/repos/os/src/drivers/platform/spec/x86/device_pd.h +++ b/repos/os/src/drivers/platform/spec/x86/device_pd.h @@ -15,7 +15,7 @@ /* base */ #include -#include +#include #include #include @@ -41,16 +41,18 @@ class Platform::Device_pd */ struct Expanding_region_map_client : Genode::Region_map_client { - Genode::Env &_env; - Genode::Pd_connection &_pd; - Genode::Ram_session_guard &ram_guard; + Genode::Env &_env; + Genode::Pd_connection &_pd; + Genode::Ram_quota_guard &_ram_guard; + Genode::Cap_quota_guard &_cap_guard; Expanding_region_map_client(Genode::Env &env, Genode::Pd_connection &pd, - Genode::Ram_session_guard &ram_guard) + Genode::Ram_quota_guard &ram_guard, + Genode::Cap_quota_guard &cap_guard) : Region_map_client(pd.address_space()), _env(env), _pd(pd), - ram_guard(ram_guard) + _ram_guard(ram_guard), _cap_guard(cap_guard) { } Local_addr attach(Genode::Dataspace_capability ds, @@ -69,22 +71,17 @@ class Platform::Device_pd executable); }, [&] () { enum { UPGRADE_CAP_QUOTA = 2 }; - /* XXX actually we would need here a ram_cap - * guard per session, not the process global - * cap env to check for enough caps */ - if (_env.pd().avail_caps().value < UPGRADE_CAP_QUOTA) - throw; - - _env.pd().transfer_quota(_pd, Genode::Cap_quota{UPGRADE_CAP_QUOTA}); + Genode::Cap_quota const caps { UPGRADE_CAP_QUOTA }; + _cap_guard.withdraw(caps); + _env.pd().transfer_quota(_pd, caps); } ); }, [&] () { enum { UPGRADE_RAM_QUOTA = 4096 }; - if (!ram_guard.withdraw(UPGRADE_RAM_QUOTA)) - throw; - - _env.pd().transfer_quota(_pd, Genode::Ram_quota{UPGRADE_RAM_QUOTA}); + Genode::Ram_quota const ram { UPGRADE_RAM_QUOTA }; + _ram_guard.withdraw(ram); + _env.pd().transfer_quota(_pd, ram); } ); } @@ -101,11 +98,12 @@ class Platform::Device_pd Device_pd(Genode::Env &env, Genode::Session_label const &label, - Genode::Ram_session_guard &ram_guard) + Genode::Ram_quota_guard &ram_guard, + Genode::Cap_quota_guard &cap_guard) : _pd(env, label.string(), Genode::Pd_connection::Virt_space::UNCONSTRAIN), _label(label), - _address_space(env, _pd, ram_guard) + _address_space(env, _pd, ram_guard, cap_guard) { _pd.ref_account(env.pd_session_cap()); } diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 4ce7b228b..f9fc06c3f 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -28,10 +28,10 @@ /* os */ #include -#include #include #include #include +#include /* local */ #include "pci_device_component.h" @@ -202,16 +202,19 @@ class Platform::Session_component : public Genode::Rpc_object { private: - Genode::Env &_env; - Genode::Attached_rom_dataspace &_config; - Genode::Ram_session_guard _env_ram; - Genode::Heap _md_alloc; - Genode::Session_label const _label; - Genode::Session_policy const _policy { _label, _config.xml() }; - Genode::List _device_list; - Platform::Pci_buses &_pci_bus; - Genode::Heap &_global_heap; - bool _no_device_pd = false; + Genode::Env &_env; + Genode::Attached_rom_dataspace &_config; + Genode::Ram_quota_guard _ram_guard; + Genode::Cap_quota_guard _cap_guard; + Genode::Constrained_ram_allocator _env_ram { + _env.pd(), _ram_guard, _cap_guard }; + Genode::Heap _md_alloc; + Genode::Session_label const _label; + Genode::Session_policy const _policy { _label, _config.xml() }; + Genode::List _device_list; + Platform::Pci_buses &_pci_bus; + Genode::Heap &_global_heap; + bool _no_device_pd = false; /** * Registry of RAM dataspaces allocated by the session @@ -236,7 +239,7 @@ class Platform::Session_component : public Genode::Rpc_object return false; } - Platform::Device_pd _device_pd { _env, _label, _env_ram }; + Platform::Device_pd _device_pd { _env, _label, _ram_guard, _cap_guard }; enum { MAX_PCI_DEVICES = Device_config::MAX_BUSES * Device_config::MAX_DEVICES * @@ -457,11 +460,15 @@ class Platform::Session_component : public Genode::Rpc_object : _env(env), _config(config), - _env_ram(env.ram(), Genode::ram_quota_from_args(args).value), + _ram_guard(Genode::ram_quota_from_args(args)), + _cap_guard(Genode::cap_quota_from_args(args)), _md_alloc(_env_ram, env.rm()), _label(Genode::label_from_args(args)), _pci_bus(buses), _global_heap(global_heap) { + /* subtract the RPC session and session dataspace capabilities */ + _cap_guard.withdraw(Genode::Cap_quota{2}); + /* non-pci devices */ _policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) { try { @@ -578,7 +585,11 @@ class Platform::Session_component : public Genode::Rpc_object } - void upgrade_ram_quota(long quota) { _env_ram.upgrade(quota); } + void upgrade_resources(Genode::Session::Resources resources) + { + _ram_guard.upgrade(resources.ram_quota); + _cap_guard.upgrade(resources.cap_quota); + } static void add_config_space(Genode::uint32_t bdf_start, @@ -981,11 +992,8 @@ class Platform::Root : public Genode::Root_component } - void _upgrade_session(Session_component *s, const char *args) override - { - long ram_quota = Genode::Arg_string::find_arg(args, "ram_quota").long_value(0); - s->upgrade_ram_quota(ram_quota); - } + void _upgrade_session(Session_component *s, const char *args) override { + s->upgrade_resources(Genode::session_resources_from_args(args)); } public: