mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 21:57:55 +00:00
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); }
|
||||
|
||||
|
||||
/****************************
|
||||
** Capability_map class **
|
||||
****************************/
|
||||
|
||||
Genode::Cap_index* Genode::Capability_map::find(int id)
|
||||
{
|
||||
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)
|
||||
{
|
||||
using namespace Genode;
|
||||
@ -63,8 +63,10 @@ Genode::Cap_index* Genode::Capability_map::insert(int id)
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
Cap_index *i = cap_idx_alloc()->alloc(1);
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
if (i) {
|
||||
i->id(id);
|
||||
_tree.insert(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);
|
||||
|
||||
Cap_index *i = cap_idx_alloc()->alloc(kcap, 1);
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
if (i) {
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,24 @@ void Thread_base::start()
|
||||
_tid = state.kcap;
|
||||
_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;
|
||||
cap_map()->insert(state.id, state.kcap);
|
||||
/**
|
||||
* If we've a dead capability in our database, which is already
|
||||
* 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 */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
|
Loading…
Reference in New Issue
Block a user