Whamcloud - gitweb
LU-7734 lnet: double free in lnet_add_net_common()
authorOlaf Weber <olaf@sgi.com>
Wed, 20 Jul 2016 12:57:36 +0000 (14:57 +0200)
committerAmir Shehata <amir.shehata@intel.com>
Wed, 25 Jan 2017 03:10:17 +0000 (19:10 -0800)
lnet_startup_lndnet() always consumes its net parameter, so we
should not free net after the function has been called. This
fixes a double free triggered by adding a network twice.

Eliminate the netl local variable.

Signed-off-by: Olaf Weber <olaf@sgi.com>
Change-Id: I1cfc3494eada4660b792f6a1ebd96b5dc80d9945
Reviewed-on: http://review.whamcloud.com/21446
Reviewed-by: Amir Shehata <amir.shehata@intel.com>
Tested-by: Amir Shehata <amir.shehata@intel.com>
lnet/lnet/api-ni.c

index 18261c1..8aa37e7 100644 (file)
@@ -2214,7 +2214,6 @@ lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni,
 static int lnet_add_net_common(struct lnet_net *net,
                               struct lnet_ioctl_config_lnd_tunables *tun)
 {
-       struct lnet_net         *netl = NULL;
        __u32                   net_id;
        lnet_ping_info_t        *pinfo;
        lnet_handle_md_t        md_handle;
@@ -2233,8 +2232,8 @@ static int lnet_add_net_common(struct lnet_net *net,
        if (rnet) {
                CERROR("Adding net %s will invalidate routing configuration\n",
                       libcfs_net2str(net->net_id));
-               rc = -EUSERS;
-               goto failed1;
+               lnet_net_free(net);
+               return -EUSERS;
        }
 
        /*
@@ -2251,8 +2250,10 @@ static int lnet_add_net_common(struct lnet_net *net,
        rc = lnet_ping_info_setup(&pinfo, &md_handle,
                                  net_ni_count + lnet_get_ni_count(),
                                  false);
-       if (rc < 0)
-               goto failed1;
+       if (rc < 0) {
+               lnet_net_free(net);
+               return rc;
+       }
 
        if (tun)
                memcpy(&net->net_tunables,
@@ -2276,18 +2277,16 @@ static int lnet_add_net_common(struct lnet_net *net,
                goto failed;
 
        lnet_net_lock(LNET_LOCK_EX);
-       netl = lnet_get_net_locked(net_id);
+       net = lnet_get_net_locked(net_id);
        lnet_net_unlock(LNET_LOCK_EX);
 
-       LASSERT(netl);
+       LASSERT(net);
 
        /*
         * Start the acceptor thread if this is the first network
         * being added that requires the thread.
         */
-       if (netl->net_lnd->lnd_accept &&
-           num_acceptor_nets == 0)
-       {
+       if (net->net_lnd->lnd_accept && num_acceptor_nets == 0) {
                rc = lnet_acceptor_start();
                if (rc < 0) {
                        /* shutdown the net that we just started */
@@ -2298,7 +2297,7 @@ static int lnet_add_net_common(struct lnet_net *net,
        }
 
        lnet_net_lock(LNET_LOCK_EX);
-       lnet_peer_net_added(netl);
+       lnet_peer_net_added(net);
        lnet_net_unlock(LNET_LOCK_EX);
 
        lnet_ping_target_update(pinfo, md_handle);
@@ -2308,8 +2307,6 @@ static int lnet_add_net_common(struct lnet_net *net,
 failed:
        lnet_ping_md_unlink(pinfo, &md_handle);
        lnet_ping_info_free(pinfo);
-failed1:
-       lnet_net_free(net);
        return rc;
 }