mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	net: ipv6: fix dst refleaks in rpl, seg6 and ioam6 lwtunnels
dst_cache_get() gives us a reference, we need to release it. Discovered by the ioam6.sh test, kmemleak was recently fixed to catch per-cpu memory leaks. Fixes:985ec6f5e6("net: ipv6: rpl_iptunnel: mitigate 2-realloc issue") Fixes:40475b6376("net: ipv6: seg6_iptunnel: mitigate 2-realloc issue") Fixes:dce525185b("net: ipv6: ioam6_iptunnel: mitigate 2-realloc issue") Reviewed-by: Justin Iurman <justin.iurman@uliege.be> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250130031519.2716843-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									46ded70923
								
							
						
					
					
						commit
						c71a192976
					
				
					 3 changed files with 11 additions and 6 deletions
				
			
		|  | @ -336,7 +336,7 @@ static int ioam6_do_encap(struct net *net, struct sk_buff *skb, | |||
| 
 | ||||
| static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
| { | ||||
| 	struct dst_entry *dst = skb_dst(skb), *cache_dst; | ||||
| 	struct dst_entry *dst = skb_dst(skb), *cache_dst = NULL; | ||||
| 	struct in6_addr orig_daddr; | ||||
| 	struct ioam6_lwt *ilwt; | ||||
| 	int err = -EINVAL; | ||||
|  | @ -407,7 +407,6 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 		cache_dst = ip6_route_output(net, NULL, &fl6); | ||||
| 		if (cache_dst->error) { | ||||
| 			err = cache_dst->error; | ||||
| 			dst_release(cache_dst); | ||||
| 			goto drop; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -426,8 +425,10 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 		return dst_output(net, sk, skb); | ||||
| 	} | ||||
| out: | ||||
| 	dst_release(cache_dst); | ||||
| 	return dst->lwtstate->orig_output(net, sk, skb); | ||||
| drop: | ||||
| 	dst_release(cache_dst); | ||||
| 	kfree_skb(skb); | ||||
| 	return err; | ||||
| } | ||||
|  |  | |||
|  | @ -232,7 +232,6 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 		dst = ip6_route_output(net, NULL, &fl6); | ||||
| 		if (dst->error) { | ||||
| 			err = dst->error; | ||||
| 			dst_release(dst); | ||||
| 			goto drop; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -251,6 +250,7 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 	return dst_output(net, sk, skb); | ||||
| 
 | ||||
| drop: | ||||
| 	dst_release(dst); | ||||
| 	kfree_skb(skb); | ||||
| 	return err; | ||||
| } | ||||
|  | @ -269,8 +269,10 @@ static int rpl_input(struct sk_buff *skb) | |||
| 	local_bh_enable(); | ||||
| 
 | ||||
| 	err = rpl_do_srh(skb, rlwt, dst); | ||||
| 	if (unlikely(err)) | ||||
| 	if (unlikely(err)) { | ||||
| 		dst_release(dst); | ||||
| 		goto drop; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!dst) { | ||||
| 		ip6_route_input(skb); | ||||
|  |  | |||
|  | @ -482,8 +482,10 @@ static int seg6_input_core(struct net *net, struct sock *sk, | |||
| 	local_bh_enable(); | ||||
| 
 | ||||
| 	err = seg6_do_srh(skb, dst); | ||||
| 	if (unlikely(err)) | ||||
| 	if (unlikely(err)) { | ||||
| 		dst_release(dst); | ||||
| 		goto drop; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!dst) { | ||||
| 		ip6_route_input(skb); | ||||
|  | @ -571,7 +573,6 @@ static int seg6_output_core(struct net *net, struct sock *sk, | |||
| 		dst = ip6_route_output(net, NULL, &fl6); | ||||
| 		if (dst->error) { | ||||
| 			err = dst->error; | ||||
| 			dst_release(dst); | ||||
| 			goto drop; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -593,6 +594,7 @@ static int seg6_output_core(struct net *net, struct sock *sk, | |||
| 
 | ||||
| 	return dst_output(net, sk, skb); | ||||
| drop: | ||||
| 	dst_release(dst); | ||||
| 	kfree_skb(skb); | ||||
| 	return err; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jakub Kicinski
						Jakub Kicinski