Whenever a mirred redirect to self on egress happens, mirred allocates a new skb (skb_to_send). The loop to self check was done after that allocation, but was not freeing the newly allocated skb, causing a leak. Fix this by moving the if-statement to before the allocation of the new skb. The issue was found by running the accompanying tdc test in 2/2 with config kmemleak enabled. After a few minutes the kmemleak thread ran and reported the leak coming from mirred. Fixes: 1d856251a009 ("net/sched: act_mirred: fix loop detection") Signed-off-by: Jamal Hadi Salim --- net/sched/act_mirred.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 91c96cc625bd..c9653b76a4cf 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -266,6 +266,17 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m, goto err_cant_do; } + want_ingress = tcf_mirred_act_wants_ingress(m_eaction); + + if (dev == skb->dev && want_ingress == at_ingress) { + pr_notice_once("tc mirred: Loop (%s:%s --> %s:%s)\n", + netdev_name(skb->dev), + at_ingress ? "ingress" : "egress", + netdev_name(dev), + want_ingress ? "ingress" : "egress"); + goto err_cant_do; + } + /* we could easily avoid the clone only if called by ingress and clsact; * since we can't easily detect the clsact caller, skip clone only for * ingress - that covers the TC S/W datapath. @@ -279,17 +290,6 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m, goto err_cant_do; } - want_ingress = tcf_mirred_act_wants_ingress(m_eaction); - - if (dev == skb->dev && want_ingress == at_ingress) { - pr_notice_once("tc mirred: Loop (%s:%s --> %s:%s)\n", - netdev_name(skb->dev), - at_ingress ? "ingress" : "egress", - netdev_name(dev), - want_ingress ? "ingress" : "egress"); - goto err_cant_do; - } - /* All mirred/redirected skbs should clear previous ct info */ nf_reset_ct(skb_to_send); if (want_ingress && !at_ingress) /* drop dst for egress -> ingress */ -- 2.52.0