From: Olaf Weber Date: Wed, 20 Jul 2016 12:57:36 +0000 (+0200) Subject: LU-7734 lnet: double free in lnet_add_net_common() X-Git-Tag: 2.9.53~47^2~9 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b9880b8325827963bb6ab34a1282c2006d118da0 LU-7734 lnet: double free in lnet_add_net_common() 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 Change-Id: I1cfc3494eada4660b792f6a1ebd96b5dc80d9945 Reviewed-on: http://review.whamcloud.com/21446 Reviewed-by: Amir Shehata Tested-by: Amir Shehata --- diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index 18261c1..8aa37e7 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -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; }