mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 16:35:28 +00:00
Fiasco.OC: check invoked capability (fix #341)
Let the Fiasco.OC base platform succeed the cap_integrity run-script meaning that it is not feasible anymore to fake a capability by using a valid one together with a guessed local_name.
This commit is contained in:
parent
c98a80251c
commit
b71c1649d6
@ -58,6 +58,8 @@ namespace Genode {
|
||||
*/
|
||||
addr_t _rcv_cap_sel_cnt;
|
||||
|
||||
unsigned long _label;
|
||||
|
||||
char _msg_start[]; /* symbol marks start of message */
|
||||
|
||||
public:
|
||||
@ -65,7 +67,8 @@ namespace Genode {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Msgbuf_base() : _rcv_idx_base(cap_idx_alloc()->alloc(MAX_CAP_ARGS))
|
||||
Msgbuf_base()
|
||||
: _rcv_idx_base(cap_idx_alloc()->alloc(MAX_CAP_ARGS)), _label(0)
|
||||
{
|
||||
rcv_reset();
|
||||
snd_reset();
|
||||
@ -137,6 +140,9 @@ namespace Genode {
|
||||
*/
|
||||
addr_t rcv_cap_sel() {
|
||||
return rcv_cap_sel_base() + _rcv_cap_sel_cnt++ * Fiasco::L4_CAP_SIZE; }
|
||||
|
||||
void label(unsigned long label) { _label = label; }
|
||||
unsigned long label() { return _label & (~0UL << 2); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -178,6 +178,9 @@ void Ipc_istream::_wait()
|
||||
tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
|
||||
} while (ipc_error(tag, DEBUG_MSG));
|
||||
|
||||
/* copy received label into message buffer */
|
||||
_rcv_msg->label(label);
|
||||
|
||||
/* copy message from the UTCBs message registers to the receive buffer */
|
||||
copy_utcb_to_msgbuf(tag, _rcv_msg);
|
||||
|
||||
@ -295,6 +298,9 @@ void Ipc_server::_reply_wait()
|
||||
_wait();
|
||||
} else {
|
||||
|
||||
/* copy received label into message buffer */
|
||||
_rcv_msg->label(label);
|
||||
|
||||
/* copy request message from the UTCBs message registers */
|
||||
copy_utcb_to_msgbuf(tag, _rcv_msg);
|
||||
}
|
||||
|
@ -37,3 +37,54 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
||||
/* return capability that uses the object id as badge */
|
||||
return new_obj_cap;
|
||||
}
|
||||
|
||||
|
||||
void Rpc_entrypoint::entry()
|
||||
{
|
||||
Ipc_server srv(&_snd_buf, &_rcv_buf);
|
||||
_ipc_server = &srv;
|
||||
_cap = srv;
|
||||
_cap_valid.unlock();
|
||||
|
||||
/*
|
||||
* Now, the capability of the server activation is initialized
|
||||
* an can be passed around. However, the processing of capability
|
||||
* invocations should not happen until activation-using server
|
||||
* is completely initialized. Thus, we wait until the activation
|
||||
* gets explicitly unblocked by calling 'Rpc_entrypoint::activate()'.
|
||||
*/
|
||||
_delay_start.lock();
|
||||
|
||||
while (1) {
|
||||
int opcode = 0;
|
||||
|
||||
srv >> IPC_REPLY_WAIT >> opcode;
|
||||
|
||||
/* set default return value */
|
||||
srv.ret(ERR_INVALID_OBJECT);
|
||||
|
||||
/* check whether capability's label fits global id */
|
||||
if (((unsigned long)srv.badge()) != _rcv_buf.label()) {
|
||||
PWRN("somebody tries to fake us!");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
_curr_obj = obj_by_id(srv.badge());
|
||||
if (!_curr_obj)
|
||||
continue;
|
||||
|
||||
_curr_obj->lock();
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
_curr_obj->unlock();
|
||||
_curr_obj = 0;
|
||||
}
|
||||
}
|
||||
|
@ -39,51 +39,6 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
}
|
||||
|
||||
|
||||
void Rpc_entrypoint::entry()
|
||||
{
|
||||
Ipc_server srv(&_snd_buf, &_rcv_buf);
|
||||
_ipc_server = &srv;
|
||||
_cap = srv;
|
||||
_cap_valid.unlock();
|
||||
|
||||
/*
|
||||
* Now, the capability of the server activation is initialized
|
||||
* an can be passed around. However, the processing of capability
|
||||
* invocations should not happen until activation-using server
|
||||
* is completely initialized. Thus, we wait until the activation
|
||||
* gets explicitly unblocked by calling 'Rpc_entrypoint::activate()'.
|
||||
*/
|
||||
_delay_start.lock();
|
||||
|
||||
while (1) {
|
||||
int opcode = 0;
|
||||
|
||||
srv >> IPC_REPLY_WAIT >> opcode;
|
||||
|
||||
/* set default return value */
|
||||
srv.ret(ERR_INVALID_OBJECT);
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
_curr_obj = obj_by_id(srv.badge());
|
||||
if (!_curr_obj)
|
||||
continue;
|
||||
|
||||
_curr_obj->lock();
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
_curr_obj->unlock();
|
||||
_curr_obj = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rpc_entrypoint::_leave_server_object(Rpc_object_base *obj)
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
@ -37,3 +37,48 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
||||
/* return capability that uses the object id as badge */
|
||||
return new_obj_cap;
|
||||
}
|
||||
|
||||
|
||||
void Rpc_entrypoint::entry()
|
||||
{
|
||||
Ipc_server srv(&_snd_buf, &_rcv_buf);
|
||||
_ipc_server = &srv;
|
||||
_cap = srv;
|
||||
_cap_valid.unlock();
|
||||
|
||||
/*
|
||||
* Now, the capability of the server activation is initialized
|
||||
* an can be passed around. However, the processing of capability
|
||||
* invocations should not happen until activation-using server
|
||||
* is completely initialized. Thus, we wait until the activation
|
||||
* gets explicitly unblocked by calling 'Rpc_entrypoint::activate()'.
|
||||
*/
|
||||
_delay_start.lock();
|
||||
|
||||
while (1) {
|
||||
int opcode = 0;
|
||||
|
||||
srv >> IPC_REPLY_WAIT >> opcode;
|
||||
|
||||
/* set default return value */
|
||||
srv.ret(ERR_INVALID_OBJECT);
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
_curr_obj = obj_by_id(srv.badge());
|
||||
if (!_curr_obj)
|
||||
continue;
|
||||
|
||||
_curr_obj->lock();
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
_curr_obj->unlock();
|
||||
_curr_obj = 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user