From 801d09f166283989a4f43ad8478bec6d3080bd7c Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 22 Feb 2013 15:26:43 +0100 Subject: [PATCH] nova: revoke set portal id right Revoke the right to set the portal id (aka label) when it is not needed anymore. Otherwise everybody in the system having a mapping of the portal can reset the label to something we don't expect. Issue #667 --- base-nova/include/cap_session/client.h | 13 ++++++++- base-nova/include/nova/syscall-generic.h | 2 ++ base-nova/src/base/pager/pager.cc | 35 +++++++++++++++--------- base-nova/src/core/echo.cc | 1 + base-nova/src/core/platform.cc | 2 ++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/base-nova/include/cap_session/client.h b/base-nova/include/cap_session/client.h index 3303e5da1..42badbdfa 100644 --- a/base-nova/include/cap_session/client.h +++ b/base-nova/include/cap_session/client.h @@ -1,6 +1,7 @@ /* * \brief Client-side CAP session interface * \author Norman Feske + * \author Alexander Boettcher * \date 2006-07-10 */ @@ -28,7 +29,17 @@ namespace Genode { Native_capability alloc(Native_capability ep, addr_t entry = 0, addr_t flags = 0) { - return call(ep, entry, flags); + Native_capability cap = call(ep, entry, flags); + + using namespace Nova; + + /* set our local name */ + if (NOVA_OK != pt_ctrl(cap.local_name(), cap.local_name())) + nova_die(); + /* disable the feature for security reasons now */ + revoke(Obj_crd(cap.local_name(), 0, Obj_crd::RIGHT_PT_CTRL)); + + return cap; } void free(Native_capability cap) { call(cap); } diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h index 40a96f7cd..07dc41333 100644 --- a/base-nova/include/nova/syscall-generic.h +++ b/base-nova/include/nova/syscall-generic.h @@ -331,6 +331,8 @@ namespace Nova { enum { RIGHT_EC_RECALL = 0x1U, + RIGHT_PT_CTRL = 0x1U, + RIGHT_PT_CALL = 0x2U }; Obj_crd() : Crd(0, 0) diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 1ad1df308..8fe760d40 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -240,6 +240,16 @@ void Pager_object::cleanup_call() utcb, this->utcb(), res); } +static uint8_t create_portal(addr_t pt, addr_t pd, addr_t ec, Mtd mtd, + addr_t eip) +{ + uint8_t res = create_pt(pt, pd, ec, mtd, eip); + + if (res == NOVA_OK) + revoke(Obj_crd(pt, 0, Obj_crd::RIGHT_PT_CTRL)); + + return res; +} Pager_object::Pager_object(unsigned long badge) : Thread_base("pager:", PF_HANDLER_STACK_SIZE), _badge(badge) @@ -264,8 +274,8 @@ Pager_object::Pager_object(unsigned long badge) /* create portal for exception handlers 0x0 - 0xd */ for (unsigned i = 0; i < PT_SEL_PAGE_FAULT; i++) { - res = create_pt(exc_pt_sel() + i, pd_sel, _tid.ec_sel, - Mtd(0), (addr_t)_exception_handler); + res = create_portal(exc_pt_sel() + i, pd_sel, _tid.ec_sel, Mtd(0), + (addr_t)_exception_handler); if (res) { PERR("could not create exception portal, error = %u\n", res); throw Create_exception_pt_failed(); @@ -277,9 +287,8 @@ Pager_object::Pager_object(unsigned long badge) revoke(Obj_crd(exc_pt_sel() + PT_SEL_PAGE_FAULT, 0)); /* create portal for page-fault handler */ - res = create_pt(exc_pt_sel() + PT_SEL_PAGE_FAULT, pd_sel, - _tid.ec_sel, Mtd(Mtd::QUAL | Mtd::EIP), - (mword_t)_page_fault_handler); + res = create_portal(exc_pt_sel() + PT_SEL_PAGE_FAULT, pd_sel, _tid.ec_sel, + Mtd(Mtd::QUAL | Mtd::EIP), (mword_t)_page_fault_handler); if (res) { PERR("could not create page-fault portal, error = %u\n", res); class Create_page_fault_pt_failed { }; @@ -288,8 +297,8 @@ Pager_object::Pager_object(unsigned long badge) /* create portal for exception handlers 0xf - 0x19 */ for (unsigned i = PT_SEL_PAGE_FAULT + 1; i < PT_SEL_PARENT; i++) { - res = create_pt(exc_pt_sel() + i, pd_sel, _tid.ec_sel, - Mtd(0), (addr_t)_exception_handler); + res = create_portal(exc_pt_sel() + i, pd_sel, _tid.ec_sel, Mtd(0), + (addr_t)_exception_handler); if (res) { PERR("could not create exception portal, error = %u\n", res); throw Create_exception_pt_failed(); @@ -297,8 +306,8 @@ Pager_object::Pager_object(unsigned long badge) } /* create portal for startup handler */ - res = create_pt(exc_pt_sel() + PT_SEL_STARTUP, pd_sel, _tid.ec_sel, - Mtd(Mtd::ESP | Mtd::EIP), (mword_t)_startup_handler); + res = create_portal(exc_pt_sel() + PT_SEL_STARTUP, pd_sel, _tid.ec_sel, + Mtd(Mtd::ESP | Mtd::EIP), (mword_t)_startup_handler); if (res) { PERR("could not create startup portal, error = %u\n", res); @@ -308,8 +317,8 @@ Pager_object::Pager_object(unsigned long badge) /* create portal for recall handler */ Mtd mtd(Mtd::ESP | Mtd::EIP | Mtd::ACDB | Mtd::EFL | Mtd::EBSD | Mtd::FSGS); - res = create_pt(exc_pt_sel() + PT_SEL_RECALL, pd_sel, _tid.ec_sel, - mtd, (addr_t)_recall_handler); + res = create_portal(exc_pt_sel() + PT_SEL_RECALL, pd_sel, _tid.ec_sel, + mtd, (addr_t)_recall_handler); if (res) { PERR("could not create recall portal, error = %u\n", res); class Create_recall_pt_failed { }; @@ -317,8 +326,8 @@ Pager_object::Pager_object(unsigned long badge) } /* create portal for final cleanup call used during destruction */ - res = create_pt(_pt_cleanup, pd_sel, _tid.ec_sel, Mtd(0), - reinterpret_cast(_invoke_handler)); + res = create_portal(_pt_cleanup, pd_sel, _tid.ec_sel, Mtd(0), + reinterpret_cast(_invoke_handler)); if (res) { PERR("could not create pager cleanup portal, error = %u\n", res); class Create_cleanup_pt_failed { }; diff --git a/base-nova/src/core/echo.cc b/base-nova/src/core/echo.cc index 0256b6621..7df8596b1 100644 --- a/base-nova/src/core/echo.cc +++ b/base-nova/src/core/echo.cc @@ -81,6 +81,7 @@ Echo::Echo(Genode::addr_t utcb_addr) /* set up echo portal to ourself */ res = create_pt(_pt_sel, pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply); if (res) { ((void (*)())(res*0x10001UL))(); } + revoke(Obj_crd(_pt_sel, 0, Obj_crd::RIGHT_PT_CTRL)); /* echo thread doesn't receive anything, it transfers items during reply */ utcb()->crd_rcv = utcb()->crd_xlt = 0; diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc index 2713f29ba..1a2fc9b32 100644 --- a/base-nova/src/core/platform.cc +++ b/base-nova/src/core/platform.cc @@ -187,11 +187,13 @@ static void init_core_page_fault_handler() create_pt(PT_SEL_PAGE_FAULT, __core_pd_sel, ec_sel, Mtd(Mtd::QUAL | Mtd::ESP | Mtd::EIP), (addr_t)page_fault_handler); + revoke(Obj_crd(PT_SEL_PAGE_FAULT, 0, Obj_crd::RIGHT_PT_CTRL)); /* startup portal for global core threads */ create_pt(PT_SEL_STARTUP, __core_pd_sel, ec_sel, Mtd(Mtd::EIP | Mtd::ESP), (addr_t)startup_handler); + revoke(Obj_crd(PT_SEL_STARTUP, 0, Obj_crd::RIGHT_PT_CTRL)); }