microbit: BUGFIX DoS attacks on the MessageBus

- Enures an event listener is not deleted whilst a fiber is activiely processing a queue
 - Added support for resurrection of event listeners in cases where identical listeners are removed/added repetitively.
This commit is contained in:
Joe Finney 2015-11-01 12:59:52 +00:00
parent 84da6a4a09
commit b2e9369771

View file

@ -190,7 +190,7 @@ int MicroBitMessageBus::deleteMarkedListeners()
// Walk this list of event handlers. Delete any that match the given listener.
while (l != NULL)
{
if (l->flags & MESSAGE_BUS_LISTENER_DELETING)
if (l->flags & MESSAGE_BUS_LISTENER_DELETING && !l->flags & MESSAGE_BUS_LISTENER_BUSY)
{
if (p == NULL)
listeners = l->next;
@ -455,8 +455,16 @@ int MicroBitMessageBus::add(MicroBitListener *newListener)
{
methodCallback = (newListener->flags & MESSAGE_BUS_LISTENER_METHOD) && (l->flags & MESSAGE_BUS_LISTENER_METHOD);
if (l->id == newListener->id && l->value == newListener->value && (methodCallback ? *l->cb_method == *newListener->cb_method : l->cb == newListener->cb) && !(l->flags & MESSAGE_BUS_LISTENER_DELETING))
if (l->id == newListener->id && l->value == newListener->value && (methodCallback ? *l->cb_method == *newListener->cb_method : l->cb == newListener->cb))
{
// We have a perfect match for this event listener already registered.
// If it's marked for deletion, we simply resurrect the listener, and we're done.
// Either way, we return an error code, as the *new* listener should be released...
if(l->flags & MESSAGE_BUS_LISTENER_DELETING)
l->flags &= ~MESSAGE_BUS_LISTENER_DELETING;
return 0;
}
l = l->next;
}