From 46c6e7c7c630af7a591c403fa6009ef7a3fab0c2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 7 Dec 2007 17:35:24 +0000 Subject: [PATCH] 2007-12-07 Dan Williams * src/nm-netlink.c src/NetworkManagerSystem.c - (new_nl_handle): ensure that the same netlink pid is never chosen twice (gnome.org #491047) - Make more robust against allocation-related failures should they occur git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3156 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 8 ++++++ src/NetworkManagerSystem.c | 28 +++++++++++++------- src/nm-netlink.c | 54 +++++++++++++++++++++++++++++++------- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea42255f5b..45c079603c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-12-07 Dan Williams + + * src/nm-netlink.c + src/NetworkManagerSystem.c + - (new_nl_handle): ensure that the same netlink pid is never chosen + twice (gnome.org #491047) + - Make more robust against allocation-related failures should they occur + 2007-12-07 Dan Williams Noticed by Christian Persch diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 509aebbae1..e230978037 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -199,22 +199,22 @@ nm_system_device_set_from_ip4_config (const char *iface, g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (config != NULL, FALSE); + nlh = nm_netlink_get_default_handle (); + if (!nlh) + return FALSE; + nm_system_delete_default_route (); nm_system_device_flush_addresses_with_iface (iface); nm_system_device_flush_routes_with_iface (iface); nm_system_flush_arp_cache (); - nlh = nm_netlink_get_default_handle (); - - if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT))) - { + if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT))) { rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface)); if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror()); rtnl_addr_put (addr); - } - else + } else nm_warning ("couldn't create rtnl address!\n"); sleep (1); @@ -353,11 +353,14 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, if (!iface || !strlen (iface)) goto out; + nlh = nm_netlink_get_default_handle (); + if (!nlh) + goto out; + nm_system_device_set_up_down_with_iface (iface, TRUE); iface_idx = nm_netlink_iface_to_index (iface); - nlh = nm_netlink_get_default_handle (); if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_PTP_DEFAULT))) { int err = 0; rtnl_addr_set_ifindex (addr, iface_idx); @@ -474,8 +477,11 @@ gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up idx = nm_netlink_iface_to_index (iface); old = nm_netlink_index_to_rtnl_link (idx); if (old) { - struct nl_handle * nlh = nm_netlink_get_default_handle (); - rtnl_link_change (nlh, old, request, 0); + struct nl_handle *nlh; + + nlh = nm_netlink_get_default_handle (); + if (nlh) + rtnl_link_change (nlh, old, request, 0); } rtnl_link_put (old); @@ -518,9 +524,11 @@ void nm_system_set_mtu (NMDevice *dev) mtu); rtnl_link_set_mtu (request, mtu); nlh = nm_netlink_get_default_handle (); - rtnl_link_change (nlh, old, request, 0); + if (nlh) + rtnl_link_change (nlh, old, request, 0); rtnl_link_put (old); out_request: rtnl_link_put (request); } + diff --git a/src/nm-netlink.c b/src/nm-netlink.c index 72b4f2f393..f7712c1c54 100644 --- a/src/nm-netlink.c +++ b/src/nm-netlink.c @@ -37,11 +37,18 @@ get_link_cache (void) struct nl_handle * nlh; nlh = nm_netlink_get_default_handle (); - g_assert (nlh); + if (G_UNLIKELY (!nlh)) { + nm_warning ("couldn't allocate netlink handle."); + return NULL; + } - if (!link_cache) + if (G_UNLIKELY (!link_cache)) link_cache = rtnl_link_alloc_cache (nlh); - g_assert (link_cache); + + if (G_UNLIKELY (!link_cache)) { + nm_warning ("couldn't allocate netlink link cache."); + return NULL; + } nl_cache_update (nlh, link_cache); return link_cache; @@ -51,13 +58,31 @@ get_link_cache (void) struct nl_handle * nm_netlink_get_default_handle (void) { + pid_t nl_pid; + int i = 10; + if (def_nl_handle) return def_nl_handle; - def_nl_handle = nl_handle_alloc_nondefault (NL_CB_VERBOSE); - g_assert (def_nl_handle); + while (i-- > 0) { + nl_pid = g_random_int (); + /* Ensure we don't use the same netlink pid as nm-netlink-monitor.c */ + if (nl_pid != getpid ()) + break; + } - nl_handle_set_pid (def_nl_handle, (pthread_self () << 16 | getpid ())); + if (G_UNLIKELY (i <= 0)) { + nm_warning ("couldn't get unused netlink pid."); + return NULL; + } + + def_nl_handle = nl_handle_alloc_nondefault (NL_CB_VERBOSE); + if (!def_nl_handle) { + nm_warning ("couldn't allocate netlink handle."); + return NULL; + } + + nl_handle_set_pid (def_nl_handle, nl_pid); if (nl_connect (def_nl_handle, NETLINK_ROUTE) < 0) { nm_error ("couldn't connect to netlink: %s", nl_geterror ()); nl_handle_destroy (def_nl_handle); @@ -75,7 +100,9 @@ nm_netlink_iface_to_index (const char *iface) g_return_val_if_fail (iface != NULL, -1); cache = get_link_cache (); - g_assert (cache); + if (!cache) + return RTNL_LINK_NOT_FOUND; + return rtnl_link_name2i (cache, iface); } @@ -87,13 +114,16 @@ nm_netlink_index_to_iface (int idx) struct nl_cache * cache; char * buf = NULL; + cache = get_link_cache (); + if (!cache) + return NULL; + buf = g_malloc0 (MAX_IFACE_LEN); if (buf == NULL) { nm_warning ("Not enough memory to allocate interface name buffer."); return NULL; } - cache = get_link_cache (); if (rtnl_link_i2name (cache, idx, buf, MAX_IFACE_LEN - 1) == NULL) { g_free (buf); buf = NULL; @@ -105,6 +135,12 @@ nm_netlink_index_to_iface (int idx) struct rtnl_link * nm_netlink_index_to_rtnl_link (int idx) { - return rtnl_link_get (get_link_cache (), idx); + struct nl_cache *cache; + + cache = get_link_cache (); + if (!cache) + return NULL; + + return rtnl_link_get (cache, idx); }