diff --git a/base-foc/include/base/ipc_msgbuf.h b/base-foc/include/base/ipc_msgbuf.h index d9d4e3a2b..d7d6377ce 100644 --- a/base-foc/include/base/ipc_msgbuf.h +++ b/base-foc/include/base/ipc_msgbuf.h @@ -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); } }; diff --git a/base-foc/src/base/ipc/ipc.cc b/base-foc/src/base/ipc/ipc.cc index aac576eb8..18d4f3321 100644 --- a/base-foc/src/base/ipc/ipc.cc +++ b/base-foc/src/base/ipc/ipc.cc @@ -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); } diff --git a/base-foc/src/base/server/server.cc b/base-foc/src/base/server/server.cc index a82b678ee..c4c5ad956 100644 --- a/base-foc/src/base/server/server.cc +++ b/base-foc/src/base/server/server.cc @@ -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; + } +} diff --git a/base/src/base/server/common.cc b/base/src/base/server/common.cc index 56ec7a27c..03b5c4f95 100644 --- a/base/src/base/server/common.cc +++ b/base/src/base/server/common.cc @@ -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); diff --git a/base/src/base/server/server.cc b/base/src/base/server/server.cc index 6eae3affa..afc4723d4 100644 --- a/base/src/base/server/server.cc +++ b/base/src/base/server/server.cc @@ -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; + } +}