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
This commit is contained in:
Alexander Boettcher 2013-02-22 15:26:43 +01:00 committed by Norman Feske
parent 46447d531e
commit 801d09f166
5 changed files with 39 additions and 14 deletions

View File

@ -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<Rpc_alloc>(ep, entry, flags);
Native_capability cap = call<Rpc_alloc>(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<Rpc_free>(cap); }

View File

@ -331,6 +331,8 @@ namespace Nova {
enum {
RIGHT_EC_RECALL = 0x1U,
RIGHT_PT_CTRL = 0x1U,
RIGHT_PT_CALL = 0x2U
};
Obj_crd() : Crd(0, 0)

View File

@ -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<addr_t>(_invoke_handler));
res = create_portal(_pt_cleanup, pd_sel, _tid.ec_sel, Mtd(0),
reinterpret_cast<addr_t>(_invoke_handler));
if (res) {
PERR("could not create pager cleanup portal, error = %u\n", res);
class Create_cleanup_pt_failed { };

View File

@ -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;

View File

@ -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));
}