When tcf_ct_handle_fragments() returns an error other than -EINPROGRESS (e.g. -EINVAL from malformed fragments), tcf_ct_act() jumps to out_frag which unconditionally returns TC_ACT_CONSUMED. This tells the caller the skb was consumed, but it was not freed, leaking one skb per malformed fragment. TC_ACT_CONSUMED is only correct for -EINPROGRESS, where defragmentation is genuinely in progress and the skb has been queued. For all other errors the skb is still owned by the caller and must be freed via TC_ACT_SHOT. Fixes: 3f14b377d01d ("net/sched: act_ct: fix skb leak and crash on ooo frags") Signed-off-by: Dudu Lu --- net/sched/act_ct.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 7d5e50c921a0..870655f682bd 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -1107,8 +1107,10 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, return retval; out_frag: - if (err != -EINPROGRESS) + if (err != -EINPROGRESS) { tcf_action_inc_drop_qstats(&c->common); + return TC_ACT_SHOT; + } return TC_ACT_CONSUMED; drop: -- 2.39.3 (Apple Git-145)