summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2022-04-12 12:34:57 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-20 10:34:13 +0300
commit8f79ce226ad2e9b2ec598de2b9560863b7549d1b (patch)
treea9eeae20c14f02554c28c3cb5620ec830f0e24b7 /drivers/net
parent8e86fba134792f69315e37b0c122ba6a60ac0c0b (diff)
downloadlinux-8f79ce226ad2e9b2ec598de2b9560863b7549d1b.tar.xz
macvlan: Fix leaking skb in source mode with nodst option
[ Upstream commit e16b859872b87650bb55b12cca5a5fcdc49c1442 ] The MACVLAN receive handler clones skbs to all matching source MACVLAN interfaces, before it passes the packet along to match on destination based MACVLANs. When using the MACVLAN nodst mode, passing the packet to destination based MACVLANs is omitted and the handler returns with RX_HANDLER_CONSUMED. However, the passed skb is not freed, leaking for any packet processed with the nodst option. Properly free the skb when consuming packets to fix that leak. Fixes: 427f0c8c194b ("macvlan: Add nodst option to macvlan type source") Signed-off-by: Martin Willi <martin@strongswan.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/macvlan.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 35f46ad040b0..a9a515cf5a46 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -460,8 +460,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_CONSUMED;
*pskb = skb;
eth = eth_hdr(skb);
- if (macvlan_forward_source(skb, port, eth->h_source))
+ if (macvlan_forward_source(skb, port, eth->h_source)) {
+ kfree_skb(skb);
return RX_HANDLER_CONSUMED;
+ }
src = macvlan_hash_lookup(port, eth->h_source);
if (src && src->mode != MACVLAN_MODE_VEPA &&
src->mode != MACVLAN_MODE_BRIDGE) {
@@ -480,8 +482,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_PASS;
}
- if (macvlan_forward_source(skb, port, eth->h_source))
+ if (macvlan_forward_source(skb, port, eth->h_source)) {
+ kfree_skb(skb);
return RX_HANDLER_CONSUMED;
+ }
if (macvlan_passthru(port))
vlan = list_first_or_null_rcu(&port->vlans,
struct macvlan_dev, list);