Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp348668ybi; Fri, 7 Jun 2019 09:02:36 -0700 (PDT) X-Google-Smtp-Source: APXvYqz31srE6Iw1yX1rZg2KyZJ1yXmWJvQ65Fo49S/Fk0q1XIoWosJ1IzqthRR8zkIqzoEsAIch X-Received: by 2002:a17:90a:24e4:: with SMTP id i91mr6609650pje.9.1559923356337; Fri, 07 Jun 2019 09:02:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559923356; cv=none; d=google.com; s=arc-20160816; b=iUqvT738IFj/Cj3mYgRn8QONbnncAc8H9UDiQS4qcfxGMBoiM1/fvteY3V9bjvsDki 8axMMOLoT6jh428VTU0/zaQTR3fZRsXbpH4/j5GzHVg3UbRCtv6bhh8rZJN9Jpc7lSaq h/tmCiAjJ5YtWukq3BwXiSS/3439TILXK1kG6CKT+5Z1zf8477z93U/Ut6wXdf5LmZU9 y40+RNyYL+8nfXrrm22KI9tVACtl1RgR+TUwxcPnVCutlt1Qe4ZgJEgvyBRFJRRSLmGJ 3a8ebfN8difX0Y6yx3TLh01n37tSQh1+vDoClAL0aQocDL5FaXYj4yDVuKmMwEBS7xMR eEWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=3/E1F4hb1WEgjJhzWXJE1M8Kw7iuAGvtc3i3EKTStIc=; b=WX8SA7E96NkCOSRaf8meoHltlyfmuW4a/OX4+9XyHmugXZvUId0HL8n1uSZtd9Ih/6 sC9u+tWcScHvqU4ym62eyLU2L5zMr0P5uZZ3kvhTA/MQhQ2s7VObsAgF5SoICZVZstPy 6wRv4KI4NpXmdlNrduD+FYLJ5AHhDRhbiScOBlaDUpGC8wFZVKlndQQuvyCngC8Hpqiy CvuWu8FalccVyUGmhcglQY2cHWYy/5Bq9WIRA0tMNev8E8bBCcjWA2nIwemFJlAsw5op 86R4BlFzLsmXaUGEueFR9OFhraBAhugzZTMVXyP/IZ1bbNtBKgfd+Ch0iksh8fNMltja 76eA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=0qG+W+AR; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k12si2169249pgj.593.2019.06.07.09.02.16; Fri, 07 Jun 2019 09:02:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=0qG+W+AR; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731188AbfFGP7T (ORCPT + 99 others); Fri, 7 Jun 2019 11:59:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:52538 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730435AbfFGPmI (ORCPT ); Fri, 7 Jun 2019 11:42:08 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8F5E1212F5; Fri, 7 Jun 2019 15:42:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559922128; bh=mpakMRqCJ6zt7o931qndqudXzv6c7d/YcTmSu5u+QLM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0qG+W+ARISqE7pNiOZbadR7w3CtHmhTAPxzrScBgVYDXY1QSI4XT1yZcsqtuZIsuj N2ydOvb+4aj3rA5cdLjtGp45BEuQ+PweeZIJzDS7K6BefH+1TgCVz10LVMHeZxCzDl 6UqM4hPVIbvGQcoFBlM8CrPslGiQDi0/JfGm6rNo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , Hangbin Liu , syzbot , "David S. Miller" Subject: [PATCH 4.14 11/69] ipv4/igmp: fix another memory leak in igmpv3_del_delrec() Date: Fri, 7 Jun 2019 17:38:52 +0200 Message-Id: <20190607153849.670806553@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190607153848.271562617@linuxfoundation.org> References: <20190607153848.271562617@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet [ Upstream commit 3580d04aa674383c42de7b635d28e52a1e5bc72c ] syzbot reported memory leaks [1] that I have back tracked to a missing cleanup from igmpv3_del_delrec() when (im->sfmode != MCAST_INCLUDE) Add ip_sf_list_clear_all() and kfree_pmc() helpers to explicitely handle the cleanups before freeing. [1] BUG: memory leak unreferenced object 0xffff888123e32b00 (size 64): comm "softirq", pid 0, jiffies 4294942968 (age 8.010s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 e0 00 00 01 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<000000006105011b>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<000000006105011b>] slab_post_alloc_hook mm/slab.h:439 [inline] [<000000006105011b>] slab_alloc mm/slab.c:3326 [inline] [<000000006105011b>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<000000004bba8073>] kmalloc include/linux/slab.h:547 [inline] [<000000004bba8073>] kzalloc include/linux/slab.h:742 [inline] [<000000004bba8073>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline] [<000000004bba8073>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085 [<00000000a46a65a0>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475 [<000000005956ca89>] do_ip_setsockopt.isra.0+0x1795/0x1930 net/ipv4/ip_sockglue.c:957 [<00000000848e2d2f>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246 [<00000000b9db185c>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616 [<000000003028e438>] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3130 [<0000000015b65589>] __sys_setsockopt+0x98/0x120 net/socket.c:2078 [<00000000ac198ef0>] __do_sys_setsockopt net/socket.c:2089 [inline] [<00000000ac198ef0>] __se_sys_setsockopt net/socket.c:2086 [inline] [<00000000ac198ef0>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086 [<000000000a770437>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:301 [<00000000d3adb93b>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 9c8bb163ae78 ("igmp, mld: Fix memory leak in igmpv3/mld_del_delrec()") Signed-off-by: Eric Dumazet Cc: Hangbin Liu Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/igmp.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -635,6 +635,24 @@ static void igmpv3_clear_zeros(struct ip } } +static void ip_sf_list_clear_all(struct ip_sf_list *psf) +{ + struct ip_sf_list *next; + + while (psf) { + next = psf->sf_next; + kfree(psf); + psf = next; + } +} + +static void kfree_pmc(struct ip_mc_list *pmc) +{ + ip_sf_list_clear_all(pmc->sources); + ip_sf_list_clear_all(pmc->tomb); + kfree(pmc); +} + static void igmpv3_send_cr(struct in_device *in_dev) { struct ip_mc_list *pmc, *pmc_prev, *pmc_next; @@ -671,7 +689,7 @@ static void igmpv3_send_cr(struct in_dev else in_dev->mc_tomb = pmc_next; in_dev_put(pmc->interface); - kfree(pmc); + kfree_pmc(pmc); } else pmc_prev = pmc; } @@ -1203,12 +1221,16 @@ static void igmpv3_del_delrec(struct in_ im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv; if (im->sfmode == MCAST_INCLUDE) { im->tomb = pmc->tomb; + pmc->tomb = NULL; + im->sources = pmc->sources; + pmc->sources = NULL; + for (psf = im->sources; psf; psf = psf->sf_next) psf->sf_crcount = im->crcount; } in_dev_put(pmc->interface); - kfree(pmc); + kfree_pmc(pmc); } spin_unlock_bh(&im->lock); } @@ -1229,21 +1251,18 @@ static void igmpv3_clear_delrec(struct i nextpmc = pmc->next; ip_mc_clear_src(pmc); in_dev_put(pmc->interface); - kfree(pmc); + kfree_pmc(pmc); } /* clear dead sources, too */ rcu_read_lock(); for_each_pmc_rcu(in_dev, pmc) { - struct ip_sf_list *psf, *psf_next; + struct ip_sf_list *psf; spin_lock_bh(&pmc->lock); psf = pmc->tomb; pmc->tomb = NULL; spin_unlock_bh(&pmc->lock); - for (; psf; psf = psf_next) { - psf_next = psf->sf_next; - kfree(psf); - } + ip_sf_list_clear_all(psf); } rcu_read_unlock(); } @@ -2107,7 +2126,7 @@ static int ip_mc_add_src(struct in_devic static void ip_mc_clear_src(struct ip_mc_list *pmc) { - struct ip_sf_list *psf, *nextpsf, *tomb, *sources; + struct ip_sf_list *tomb, *sources; spin_lock_bh(&pmc->lock); tomb = pmc->tomb; @@ -2119,14 +2138,8 @@ static void ip_mc_clear_src(struct ip_mc pmc->sfcount[MCAST_EXCLUDE] = 1; spin_unlock_bh(&pmc->lock); - for (psf = tomb; psf; psf = nextpsf) { - nextpsf = psf->sf_next; - kfree(psf); - } - for (psf = sources; psf; psf = nextpsf) { - nextpsf = psf->sf_next; - kfree(psf); - } + ip_sf_list_clear_all(tomb); + ip_sf_list_clear_all(sources); } /* Join a multicast group