lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 31 May 2022 13:35:30 +0200
From:   Steffen Klassert <steffen.klassert@...unet.com>
To:     Hangyu Hua <hbh25y@...il.com>
CC:     <herbert@...dor.apana.org.au>, <davem@...emloft.net>,
        <edumazet@...gle.com>, <kuba@...nel.org>, <pabeni@...hat.com>,
        <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] xfrm: xfrm_input: fix a possible memory leak in
 xfrm_input()

On Tue, May 31, 2022 at 10:12:05AM +0800, Hangyu Hua wrote:
> On 2022/5/30 18:37, Steffen Klassert wrote:
> > On Mon, May 30, 2022 at 06:20:46PM +0800, Hangyu Hua wrote:
> > > xfrm_input needs to handle skb internally. But skb is not freed When
> > > xo->flags & XFRM_GRO == 0 and decaps == 0.
> > > 
> > > Fixes: 7785bba299a8 ("esp: Add a software GRO codepath")
> > > Signed-off-by: Hangyu Hua <hbh25y@...il.com>
> > > ---
> > >   net/xfrm/xfrm_input.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
> > > index 144238a50f3d..6f9576352f30 100644
> > > --- a/net/xfrm/xfrm_input.c
> > > +++ b/net/xfrm/xfrm_input.c
> > > @@ -742,7 +742,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
> > >   			gro_cells_receive(&gro_cells, skb);
> > >   			return err;
> > >   		}
> > > -
> > > +		kfree_skb(skb);
> > >   		return err;
> > >   	}
> > 
> > Did you test this? The function behind the 'afinfo->the transport_finish()'
> > pointer handles this skb and frees it in that case.
> 
> int xfrm4_transport_finish(struct sk_buff *skb, int async)
> {
> 	struct xfrm_offload *xo = xfrm_offload(skb);
> 	struct iphdr *iph = ip_hdr(skb);
> 
> 	iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
> 
> #ifndef CONFIG_NETFILTER
> 	if (!async)
> 		return -iph->protocol;		<--- [1]
> #endif
> ...
> 	NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
> 		dev_net(skb->dev), NULL, skb, skb->dev, NULL,
> 		xfrm4_rcv_encap_finish);	<--- [2]
> 	return 0;
> }
> 
> int xfrm6_transport_finish(struct sk_buff *skb, int async)
> {
> 	struct xfrm_offload *xo = xfrm_offload(skb);
> 	int nhlen = skb->data - skb_network_header(skb);
> 
> 	skb_network_header(skb)[IP6CB(skb)->nhoff] =
> 		XFRM_MODE_SKB_CB(skb)->protocol;
> 
> #ifndef CONFIG_NETFILTER
> 	if (!async)
> 		return 1;			<--- [3]
> #endif
> ...
> 	NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
> 		dev_net(skb->dev), NULL, skb, skb->dev, NULL,
> 		xfrm6_transport_finish2);
> 	return 0;				<--- [4]
> }
> 
> If transport_finish() return in [1] or [3], there will be a memory leak.

No, even in that case there is no memleak. Look for instance at the
IPv4 case, we return -iph->protocol here.
Then look at ip_protocol_deliver_rcu(). If the ipprot->handler (xfrm)
returns a negative value, this is interpreted as the protocol number
and the packet is resubmitted to the next protocol handler.

Please test your patches before you submit them in the future.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ