Skip to content

Commit c71a192

Browse files
committed
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: 985ec6f ("net: ipv6: rpl_iptunnel: mitigate 2-realloc issue") Fixes: 40475b6 ("net: ipv6: seg6_iptunnel: mitigate 2-realloc issue") Fixes: dce5251 ("net: ipv6: ioam6_iptunnel: mitigate 2-realloc issue") Reviewed-by: Justin Iurman <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 46ded70 commit c71a192

File tree

3 files changed

+11
-6
lines changed

3 files changed

+11
-6
lines changed

net/ipv6/ioam6_iptunnel.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ static int ioam6_do_encap(struct net *net, struct sk_buff *skb,
336336

337337
static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
338338
{
339-
struct dst_entry *dst = skb_dst(skb), *cache_dst;
339+
struct dst_entry *dst = skb_dst(skb), *cache_dst = NULL;
340340
struct in6_addr orig_daddr;
341341
struct ioam6_lwt *ilwt;
342342
int err = -EINVAL;
@@ -407,7 +407,6 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
407407
cache_dst = ip6_route_output(net, NULL, &fl6);
408408
if (cache_dst->error) {
409409
err = cache_dst->error;
410-
dst_release(cache_dst);
411410
goto drop;
412411
}
413412

@@ -426,8 +425,10 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
426425
return dst_output(net, sk, skb);
427426
}
428427
out:
428+
dst_release(cache_dst);
429429
return dst->lwtstate->orig_output(net, sk, skb);
430430
drop:
431+
dst_release(cache_dst);
431432
kfree_skb(skb);
432433
return err;
433434
}

net/ipv6/rpl_iptunnel.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb)
232232
dst = ip6_route_output(net, NULL, &fl6);
233233
if (dst->error) {
234234
err = dst->error;
235-
dst_release(dst);
236235
goto drop;
237236
}
238237

@@ -251,6 +250,7 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb)
251250
return dst_output(net, sk, skb);
252251

253252
drop:
253+
dst_release(dst);
254254
kfree_skb(skb);
255255
return err;
256256
}
@@ -269,8 +269,10 @@ static int rpl_input(struct sk_buff *skb)
269269
local_bh_enable();
270270

271271
err = rpl_do_srh(skb, rlwt, dst);
272-
if (unlikely(err))
272+
if (unlikely(err)) {
273+
dst_release(dst);
273274
goto drop;
275+
}
274276

275277
if (!dst) {
276278
ip6_route_input(skb);

net/ipv6/seg6_iptunnel.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,10 @@ static int seg6_input_core(struct net *net, struct sock *sk,
482482
local_bh_enable();
483483

484484
err = seg6_do_srh(skb, dst);
485-
if (unlikely(err))
485+
if (unlikely(err)) {
486+
dst_release(dst);
486487
goto drop;
488+
}
487489

488490
if (!dst) {
489491
ip6_route_input(skb);
@@ -571,7 +573,6 @@ static int seg6_output_core(struct net *net, struct sock *sk,
571573
dst = ip6_route_output(net, NULL, &fl6);
572574
if (dst->error) {
573575
err = dst->error;
574-
dst_release(dst);
575576
goto drop;
576577
}
577578

@@ -593,6 +594,7 @@ static int seg6_output_core(struct net *net, struct sock *sk,
593594

594595
return dst_output(net, sk, skb);
595596
drop:
597+
dst_release(dst);
596598
kfree_skb(skb);
597599
return err;
598600
}

0 commit comments

Comments
 (0)