diff options
author | Jiří Klimeš <jklimes@redhat.com> | 2013-10-11 11:14:05 +0200 |
---|---|---|
committer | Jiří Klimeš <jklimes@redhat.com> | 2013-10-14 08:48:06 +0200 |
commit | 570b9b362db0372e90d1598519132ce805a01d4f (patch) | |
tree | ca94a96b27eaaa5d74e98b5136685a2f038e7c98 /libnm-glib/nm-client.c | |
parent | 8a046bedbbf8218737d7471f949a541b35579539 (diff) |
libnm-glib: fix a crash in nm_client_new() (rh #1010288)
We have to check if 'client' is valid when calling _nm_object_ensure_inited().
Creation of NMClient object can fail, because its parent NMObject's
constructor() returns NULL for D-Bus errors.
https://bugzilla.redhat.com/show_bug.cgi?id=1010288
Diffstat (limited to 'libnm-glib/nm-client.c')
-rw-r--r-- | libnm-glib/nm-client.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index f34b685ced..15c708acc1 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright (C) 2007 - 2013 Red Hat, Inc. */ #include <dbus/dbus-glib.h> @@ -1616,7 +1616,7 @@ nm_client_check_connectivity_finish (NMClient *client, * control them. To access and modify network configuration data, use the * #NMRemoteSettings object. * - * Returns: a new #NMClient + * Returns: a new #NMClient or NULL on an error **/ NMClient * nm_client_new (void) @@ -1624,7 +1624,13 @@ nm_client_new (void) NMClient *client; client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL); - _nm_object_ensure_inited (NM_OBJECT (client)); + + /* NMObject's constructor() can fail on a D-Bus connection error. So we can + * get NULL here instead of a valid NMClient object. + */ + if (client) + _nm_object_ensure_inited (NM_OBJECT (client)); + return client; } @@ -1650,7 +1656,8 @@ client_inited (GObject *source, GAsyncResult *result, gpointer user_data) * * Creates a new #NMClient and begins asynchronously initializing it. * @callback will be called when it is done; use - * nm_client_new_finish() to get the result. + * nm_client_new_finish() to get the result. Note that on an error, + * the callback can be invoked with two first parameters as NULL. * * NOTE: #NMClient provides information about devices and a mechanism to * control them. To access and modify network configuration data, use the @@ -1664,8 +1671,16 @@ nm_client_new_async (GCancellable *cancellable, NMClient *client; GSimpleAsyncResult *simple; - simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async); client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL); + /* When client is NULL, do no continue with initialization and run callback + * directly with result == NULL indicating NMClient creation failure. + */ + if (!client) { + callback (NULL, NULL, user_data); + return; + } + + simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async); g_async_initable_init_async (G_ASYNC_INITABLE (client), G_PRIORITY_DEFAULT, cancellable, client_inited, simple); } @@ -1684,6 +1699,16 @@ nm_client_new_finish (GAsyncResult *result, GError **error) { GSimpleAsyncResult *simple; + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!result) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_UNKNOWN, + "NMClient initialization failed (or you passed NULL 'result' by mistake)"); + return NULL; + } + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, nm_client_new_async), NULL); simple = G_SIMPLE_ASYNC_RESULT (result); |