From owner-freebsd-net@freebsd.org Sat Jul 22 09:11:39 2017 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C65E0D3D216 for ; Sat, 22 Jul 2017 09:11:39 +0000 (UTC) (envelope-from bu7cher@yandex.ru) Received: from forward4m.cmail.yandex.net (forward4m.cmail.yandex.net [IPv6:2a02:6b8:b030::1b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "forwards.mail.yandex.net", Issuer "Yandex CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 7D56F72AFE for ; Sat, 22 Jul 2017 09:11:39 +0000 (UTC) (envelope-from bu7cher@yandex.ru) Received: from smtp2m.mail.yandex.net (smtp2m.mail.yandex.net [77.88.61.129]) by forward4m.cmail.yandex.net (Yandex) with ESMTP id 09E3021058; Sat, 22 Jul 2017 12:11:35 +0300 (MSK) Received: from smtp2m.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp2m.mail.yandex.net (Yandex) with ESMTP id 599E22300A74; Sat, 22 Jul 2017 12:11:33 +0300 (MSK) Received: by smtp2m.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id CSdfLEZTPW-BXEO91w4; Sat, 22 Jul 2017 12:11:33 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1500714693; bh=JAlH095gn+UiQw/loNVVNK3SMlSnp7NEU1xEs8Vlm4Y=; h=Subject:To:References:From:Message-ID:Date:In-Reply-To; b=etyom8h7BujnN8Ib8FeKx983hkP1l59HoRq+ZWwEww9jxRWDVF7TJgiLRGls6YtZ5 8YQvCHwLTBqPIt66EEHQQsO2ttPeqCD4UCfNcDXoWU06BdnN3gxum4qvnpPkz3dk8R ig3o9gYfhJOWClMarxbhIUBHuu9GgbLvZOxnsTeI= Authentication-Results: smtp2m.mail.yandex.net; dkim=pass header.i=@yandex.ru X-Yandex-Suid-Status: 1 0,1 0 Subject: Re: mbuf clusters leak in netinet6 To: Daniel Bilik , freebsd-net@freebsd.org References: <20170721232112.82f6e78b76057312183be937@neosystem.cz> From: "Andrey V. Elsukov" Message-ID: <5dadd0d0-d5ce-3a2c-7ad6-1c0a39a4a0e7@yandex.ru> Date: Sat, 22 Jul 2017 12:11:31 +0300 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 MIME-Version: 1.0 In-Reply-To: <20170721232112.82f6e78b76057312183be937@neosystem.cz> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 Jul 2017 09:11:39 -0000 22.07.17 0:21, Daniel Bilik пишет: > Hi. > > (Please keep me in cc, I'm not subscribed to the list.) > > After deploying ndproxy[1] on a few 10-stable hosts, some of them have > experienced mbuf clusters exhaustion. Initial analysis showed that after > loading ndproxy.ko, "current" values of "mbuf clusters" and "mbuf+clusters > out of packet secondary zone" (from netstat -m output) keep continuously > increasing and never decrease. More thorough inspection of ndproxy source > code pointed me at function packet() in ndpacket.c[2], to the very last > "return 1". With this line changed to "return 0", mbuf clusters do not > increase anymore, ie. it fixes the issue. As the leak does not come from > "return" itself, I suspect "the proper solution" is to modify code in > the upper layer to not leak anything on any returned value. If I read it > right, the upper layer in this case is function ip6_input() in > sys/netinet6/ip6_input.c[3], specifically pfil_run_hooks() call at line > 765. I guess it should be changed like this to avoid the leak: > > --- ip6_input.c.orig 2017-07-21 22:42:17.780594000 +0200 > +++ ip6_input.c 2017-07-21 22:45:28.981497000 +0200 > @@ -620,8 +620,11 @@ > goto passin; > > if (pfil_run_hooks(&V_inet6_pfil_hook, &m, > - m->m_pkthdr.rcvif, PFIL_IN, NULL)) > + m->m_pkthdr.rcvif, PFIL_IN, NULL)) { > + if (m) > + m_free(m); > return; > + } > if (m == NULL) /* consumed by filter */ > return; > ip6 = mtod(m, struct ip6_hdr *); > > I haven't actually tested this modification. I prefer to know your > opinions first before trying to panic production hosts running hundreds of > miles from me. ;-) Thanks. Freeing mbuf is under pfil hook responsibility, if it returns nonzero value it must call m_freem(). So, it is bug in the ndpacket.c. https://github.com/AlexandreFenyo/ndproxy/blob/master/ndpacket.c Also, ip6_output() always consumes mbuf, it is wrong to call m_freem() after calling ip6_output(), even when it returns error. -- WBR, Andrey V. Elsukov