From eb236a1a10f9ca72df5cf47eb56fc1127acc1a75 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 12 Nov 2015 15:21:23 +0100 Subject: [PATCH] nova: re-add server object IPC cleanup call Accidentally removed by #1658. We need to make the cleanup call for server objects - otherwise we may get in capability identifier re-use trouble. Issue #1778 --- repos/base-nova/src/base/server/server.cc | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index 6d2ea646c..cee231417 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -90,8 +90,38 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj) /* make sure nobody is able to find this object */ remove(obj); + + + /* + * The activation may execute a blocking operation in a dispatch function. + * Before resolving the corresponding object, we need to ensure that it is + * no longer used by an activation. Therefore, we to need cancel an + * eventually blocking operation and let the activation leave the context + * of the object. + */ + using namespace Nova; + + Utcb *utcb = reinterpret_cast(Thread_base::myself()->utcb()); + /* don't call ourself */ + if (utcb == reinterpret_cast(this->utcb())) + return; + + /* + * Required outside of core. E.g. launchpad needs it to forcefully kill + * a client which blocks on a session opening request where the service + * is not up yet. + */ + cancel_blocking(); + + /* make a IPC to ensure that cap() identifier is not used anymore */ + utcb->msg[0] = 0xdead; + utcb->set_msg_word(1); + if (uint8_t res = call(_cap.local_name())) + PERR("%8p - could not clean up entry point of thread 0x%p - res %u", + utcb, this->utcb(), res); } + void Rpc_entrypoint::_activation_entry() { /* retrieve portal id from eax/rdi */