summaryrefslogtreecommitdiff
path: root/libnm-glib/nm-client.c
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2013-10-11 11:14:05 +0200
committerJiří Klimeš <jklimes@redhat.com>2013-10-14 08:48:06 +0200
commit570b9b362db0372e90d1598519132ce805a01d4f (patch)
treeca94a96b27eaaa5d74e98b5136685a2f038e7c98 /libnm-glib/nm-client.c
parent8a046bedbbf8218737d7471f949a541b35579539 (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.c35
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);