Fiasco.OC: sanity-check cap insertion. (fix #166)
When constructing a thread object its capability is inserted into the capability map. Normally this is done by the ipc-unmarshalling code, but in this case the thread-capability isn't transfered via normal IPC, but in a special form via the thread_state object. In contrast to the unmarshalling code, the thread-startup code doesn't check, whether the capability-map already contains a deprecated entry with the same capability id before inserting the thread's capability. This commit add the necessary check. Moreover, a check is added to the insertion methods of the capability-map to verify that capability-allocation didn't failed.
This commit is contained in:
parent
89db981280
commit
9a9f49b65c
20
base-foc/src/base/env/cap_map.cc
vendored
20
base-foc/src/base/env/cap_map.cc
vendored
|
@ -39,6 +39,10 @@ Genode::addr_t Genode::Cap_index::kcap() {
|
||||||
return cap_idx_alloc()->idx_to_kcap(this); }
|
return cap_idx_alloc()->idx_to_kcap(this); }
|
||||||
|
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
** Capability_map class **
|
||||||
|
****************************/
|
||||||
|
|
||||||
Genode::Cap_index* Genode::Capability_map::find(int id)
|
Genode::Cap_index* Genode::Capability_map::find(int id)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
@ -52,10 +56,6 @@ Genode::Cap_index* Genode::Capability_map::find(int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
** Capability_map class **
|
|
||||||
****************************/
|
|
||||||
|
|
||||||
Genode::Cap_index* Genode::Capability_map::insert(int id)
|
Genode::Cap_index* Genode::Capability_map::insert(int id)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
@ -63,8 +63,10 @@ Genode::Cap_index* Genode::Capability_map::insert(int id)
|
||||||
Lock_guard<Spin_lock> guard(_lock);
|
Lock_guard<Spin_lock> guard(_lock);
|
||||||
|
|
||||||
Cap_index *i = cap_idx_alloc()->alloc(1);
|
Cap_index *i = cap_idx_alloc()->alloc(1);
|
||||||
i->id(id);
|
if (i) {
|
||||||
_tree.insert(i);
|
i->id(id);
|
||||||
|
_tree.insert(i);
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +78,10 @@ Genode::Cap_index* Genode::Capability_map::insert(int id, addr_t kcap)
|
||||||
Lock_guard<Spin_lock> guard(_lock);
|
Lock_guard<Spin_lock> guard(_lock);
|
||||||
|
|
||||||
Cap_index *i = cap_idx_alloc()->alloc(kcap, 1);
|
Cap_index *i = cap_idx_alloc()->alloc(kcap, 1);
|
||||||
i->id(id);
|
if (i) {
|
||||||
_tree.insert(i);
|
i->id(id);
|
||||||
|
_tree.insert(i);
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,24 @@ void Thread_base::start()
|
||||||
_tid = state.kcap;
|
_tid = state.kcap;
|
||||||
_context->utcb = state.utcb;
|
_context->utcb = state.utcb;
|
||||||
|
|
||||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
|
/**
|
||||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
* If we've a dead capability in our database, which is already
|
||||||
cap_map()->insert(state.id, state.kcap);
|
* revoked, its id might be reused.
|
||||||
|
*/
|
||||||
|
Cap_index *i = cap_map()->find(state.id);
|
||||||
|
if (i) {
|
||||||
|
l4_msgtag_t tag = l4_task_cap_valid(L4_BASE_TASK_CAP, i->kcap());
|
||||||
|
if (!tag.label())
|
||||||
|
cap_map()->remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
|
||||||
|
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||||
|
cap_map()->insert(state.id, state.kcap);
|
||||||
|
} catch(Cap_index_allocator::Region_conflict) {
|
||||||
|
PERR("could not insert id %lx", state.id);
|
||||||
|
}
|
||||||
|
|
||||||
/* register initial IP and SP at core */
|
/* register initial IP and SP at core */
|
||||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user