cfa15c bus-message: introduce two kinds of references to bus messages

2 files Authored by Lennart Poettering 4 years ago, Committed by Packit Service 4 years ago,
    bus-message: introduce two kinds of references to bus messages
    
    Before this commit bus messages had a single reference count: when it
    reached zero the message would be freed. This simple approach meant a
    cyclic dependency was typically seen: a message that was enqueued in a
    bus connection object would reference the bus connection object but also
    itself be referenced by the bus connection object. So far out strategy
    to avoid cases like this was: make sure to process the bus connection
    regularly so that messages don#t stay queued, and at exit flush/close
    the connection so that the message queued would be emptied, and thus the
    cyclic dependencies resolved. Im many cases this isn't done properly
    however.
    
    With this change, let's address the issue more systematically: let's
    break the reference cycle. Specifically, there are now two types of
    references to a bus message:
    
    1. A regular one, which keeps both the message and the bus object it is
       associated with pinned.
    
    2. A "queue" reference, which is weaker: it pins the message, but not
       the bus object it is associated with.
    
    The idea is then that regular user handling uses regular references, but
    when a message is enqueued on its connection, then this takes a "queue"
    reference instead. This then means that a queued message doesn't imply
    the connection itself remains pinned, only regular references to the
    connection or a message associated with it do. Thus, if we end up in the
    situation where a user allocates a bus and a message and enqueues the
    latter in the former and drops all refs to both, then this will detect
    this case and free both.
    
    Note that this scheme isn't perfect, it only covers references between
    messages and the busses they are associated with. If OTOH a bus message
    is enqueued on a different bus than it is associated with cyclic deps
    cannot be recognized with this simple algorithm, and thus if you enqueue
    a message associated with a bus A on a bus B, and another message
    associated with bus B on a bus A, a cyclic ref will be in effect and not
    be discovered. However, given that this is an exotic case (though one
    that happens, consider systemd-bus-stdio-bridge), it should be OK not to
    cover with this, and people have to explicit flush all queues on exit in
    that case.
    
    Note that this commit only establishes the separate reference counters
    per message. A follow-up commit will start making use of this from the
    bus connection object.
    
    (cherry picked from commit 1b3f9dd759ca0ea215e7b89f8ce66d1b724497b9)
    Related: CVE-2020-1712
    
    patch_name: 0313-bus-message-introduce-two-kinds-of-references-to-bus.patch
    present_in_specfile: true
    location_in_specfile: 313
    squash_commits: true