chiark / gitweb /
sd-rtnl: fix self-reference leaks
authorDavid Herrmann <dh.herrmann@gmail.com>
Sat, 22 Mar 2014 16:43:30 +0000 (17:43 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Sat, 22 Mar 2014 17:00:03 +0000 (18:00 +0100)
commit22fdeadcc06e95fe41ac4de872ec245c0887547f
treefe8387b2605767f4b20d36158ad7d6d64aa472d6
parent2afa65c3122542b21d1881fada917c89b8913bd4
sd-rtnl: fix self-reference leaks

Like sd-bus, sd-rtnl can have self-references through queued messages. In
particular, each queued message has the following self-ref loop:
  rtnl->wqueue[i]->rtnl == rtnl
Same is true for "rqueue".

When sd_rtnl_unref() gets called, we must therefore make sure we correctly
consider each self-reference when deciding to destroy the object. For each
queued message, there _might_ be one ref. However, rtnl-messages can be
created _without_ a bus-reference, therefore we need to verify the
actually required ref-count.

Once we know exactly how many self-refs exist, and we verified none of the
queued messages has external references, we can destruct the object.
We must immediately drop our own reference, then flush all queues and
destroy the bus object. Otherwise, each sd_rtnl_message_unref() call would
recurse into the same destruction logic as they enter with the same
rtnl-refcnt.

Note: We really should verify _all_ queued messages have m->rtnl set to
      the bus they're queued on. If that's given, we can change:
        if (REFCNT_GET(rtnl->n_ref) <= refs)
      to
        if (REFCNT_GET(rtnl->n_ref) == refs)
      and thus avoid recalculating the required refs for each message we
      remove from the queue during destruction.
src/libsystemd/sd-rtnl/sd-rtnl.c