From f583bac0da8140c748e90fd5ccd562e4d37f5a06 Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Thu, 6 Aug 2026 00:20:07 +0200 Subject: [PATCH] net: openvswitch: fix skb leak on flow key update failure during recirculation [ Upstream commit e1cf066244dad576221b7123a0e5005967f25a20 ] do_execute_actions() returns right away when execute_recirc() fails on the last action as it assumes this function always takes ownership of the skb when 'last' is true. But when the flow key update fails, the function doesn't free the skb and it ends up leaked. This is a very unlikely scenario as it requires the packet to become unparseable by applying a set of actions on a previously parseable skb, but should be fixed nevertheless. Reported by Sashiko. Fixes: 971427f353f3 ("openvswitch: Add recirc and hash action.") Cc: stable@vger.kernel.org Signed-off-by: Ilya Maximets Reviewed-by: Aaron Conole Link: https://patch.msgid.link/20260727181851.306076-2-i.maximets@ovn.org Signed-off-by: Jakub Kicinski [OVS drop reasons are not available in 5.15, hence plain kfree_skb()] Signed-off-by: Ilya Maximets Signed-off-by: Sasha Levin --- net/openvswitch/actions.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 3a69ed9d2192..6fd22d3632ba 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -1107,6 +1107,10 @@ static int execute_masked_set_action(struct sk_buff *skb, return err; } +/* When 'last' is true, recirc() should always consume the 'skb'. + * Otherwise, recirc() should keep 'skb' intact regardless what + * actions are executed on recirculation. + */ static int execute_recirc(struct datapath *dp, struct sk_buff *skb, struct sw_flow_key *key, const struct nlattr *a, bool last) @@ -1117,8 +1121,11 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb, int err; err = ovs_flow_key_update(skb, key); - if (err) + if (err) { + if (last) + kfree_skb(skb); return err; + } } BUG_ON(!is_flow_key_valid(key));