mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
base: safeguard entrypoint against double manage
This patch adds sanity checks to the RPC entrypoint that detect attempts to manage or dissolve the same RPC object twice. This is not always a bug. I.e., if RPC objects are implemented in the modern way where the object manages/dissolves itself. As the generic framework code (in particular root/component.h) cannot rely on this pattern, it has to call manage/dissolve for session objects anyway. For modern session objects, this double attempt would result in a serious error (double insertion into the object pool's AVL tree). Issue #2398
This commit is contained in:
committed by
Christian Helmuth
parent
843dd179d7
commit
eea493a8ca
@ -36,6 +36,12 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
|||||||
{
|
{
|
||||||
using namespace Nova;
|
using namespace Nova;
|
||||||
|
|
||||||
|
/* don't manage RPC object twice */
|
||||||
|
if (obj->cap().valid()) {
|
||||||
|
warning("attempt to manage RPC object twice");
|
||||||
|
return obj->cap();
|
||||||
|
}
|
||||||
|
|
||||||
Untyped_capability ec_cap;
|
Untyped_capability ec_cap;
|
||||||
|
|
||||||
/* _ec_sel is invalid until thread gets started */
|
/* _ec_sel is invalid until thread gets started */
|
||||||
@ -60,6 +66,10 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
|||||||
|
|
||||||
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||||
{
|
{
|
||||||
|
/* don't dissolve RPC object twice */
|
||||||
|
if (!obj->cap().valid())
|
||||||
|
return;
|
||||||
|
|
||||||
/* de-announce object from cap_session */
|
/* de-announce object from cap_session */
|
||||||
_free_rpc_cap(_pd_session, obj->cap());
|
_free_rpc_cap(_pd_session, obj->cap());
|
||||||
|
|
||||||
|
@ -169,7 +169,12 @@ class Genode::Root_component : public Rpc_object<Typed_root<SESSION_TYPE> >,
|
|||||||
throw Root::Unavailable();
|
throw Root::Unavailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
_ep->manage(s);
|
/*
|
||||||
|
* Consider that the session-object constructor may already have
|
||||||
|
* called 'manage'.
|
||||||
|
*/
|
||||||
|
if (!s->cap().valid())
|
||||||
|
_ep->manage(s);
|
||||||
|
|
||||||
aquire_guard.ack = true;
|
aquire_guard.ack = true;
|
||||||
return *s;
|
return *s;
|
||||||
|
@ -27,6 +27,12 @@ using namespace Genode;
|
|||||||
|
|
||||||
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
||||||
{
|
{
|
||||||
|
/* don't manage RPC object twice */
|
||||||
|
if (obj->cap().valid()) {
|
||||||
|
warning("attempt to manage RPC object twice");
|
||||||
|
return obj->cap();
|
||||||
|
}
|
||||||
|
|
||||||
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap);
|
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap);
|
||||||
|
|
||||||
/* add server object to object pool */
|
/* add server object to object pool */
|
||||||
|
@ -26,6 +26,10 @@ using namespace Genode;
|
|||||||
|
|
||||||
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||||
{
|
{
|
||||||
|
/* don't dissolve RPC object twice */
|
||||||
|
if (!obj->cap().valid())
|
||||||
|
return;
|
||||||
|
|
||||||
/* make sure nobody is able to find this object */
|
/* make sure nobody is able to find this object */
|
||||||
remove(obj);
|
remove(obj);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user