Skip to content

libnm: fix leaking internal GMainContext for synchronously initialized NMClient

Thomas Haller requested to merge th/nmclient-context-leak into master

NMClient makes asynchronous D-Bus calls via g_dbus_connection_call(). This references the current GMainContext to later invoke the asynchronous callback. Even when we cancel the asynchronous call, the callback will still be invoked (later) to complete the request.

In particular this means when we destroy (unref) an NMClient, there are quite possibly pending requests in the GMainContext. Although they are cancelled, they keep the GMainContext alive.

With synchronous initialization, we have an internal GMainContext. When we destroy the NMClient, we cannot just unhook the integrated source, instead, we need to keep it integrated in the callers main context, as long as there are pending requests.

Add a mechanism to track those pending requests and fix the leak for the internal GMainContext. Also expose this mechanism to the user via a new API called nm_client_get_context_busy_watcher(). This allows the user to know when it can stop iterating the main context and when all resources are reclaimed.

For example the following will lead to a crash:

for i in range(1,2000):
    nmc = NM.Client.new(None)

This creates a number of NMClient instances and destroys them again. Note that here the GMainContext is never iterated, because synchronous initialization does not do that. So, while we correctly unref and dispose the created NMClient instances, there are pending requests left in the inner GMainContext. These pile up and soon the program will crash because it runs out of file descriptors.

We can have a similar problem with asynchronous initialization, if we create new GMainContext per client, and don't iterate it after we are done with the client.

Note that this patch does not avoid the problem in general. The problem cannot be avoided, the user must iterate the main contex at some point. Otherwise resources (memory and file descriptors) are leaked.

Fixes: ce0e898f ('libnm: refactor caching of D-Bus objects in NMClient')

Merge request reports