All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bridge, v3] br_netfilter: Drop dst references before setting.
@ 2022-08-31  5:36 Harsh Modi
  2022-08-31  6:44 ` Florian Westphal
  0 siblings, 1 reply; 3+ messages in thread
From: Harsh Modi @ 2022-08-31  5:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: harshmodi, sdf, pablo, kadlec, fw

The IPv6 path already drops dst in the daddr changed case, but the IPv4
path does not. This change makes the two code paths consistent.

Further, it is possible that there is already a metadata_dst allocated from
ingress that might already be attached to skbuff->dst while following
the bridge path. If it is not released before setting a new
metadata_dst, it will be leaked. This is similar to what is done in
bpf_set_tunnel_key() or ip6_route_input().

It is important to note that the memory being leaked is not the dst
being set in the bridge code, but rather memory allocated from some
other code path that is not being freed correctly before the skb dst is
overwritten.

An example of the leakage fixed by this commit found using kmemleak:

unreferenced object 0xffff888010112b00 (size 256):
  comm "softirq", pid 0, jiffies 4294762496 (age 32.012s)
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 80 16 f1 83 ff ff ff ff  ................
    e1 4e f6 82 ff ff ff ff 00 00 00 00 00 00 00 00  .N..............
  backtrace:
    [<00000000d79567ea>] metadata_dst_alloc+0x1b/0xe0
    [<00000000be113e13>] udp_tun_rx_dst+0x174/0x1f0
    [<00000000a36848f4>] geneve_udp_encap_recv+0x350/0x7b0
    [<00000000d4afb476>] udp_queue_rcv_one_skb+0x380/0x560
    [<00000000ac064aea>] udp_unicast_rcv_skb+0x75/0x90
    [<000000009a8ee8c5>] ip_protocol_deliver_rcu+0xd8/0x230
    [<00000000ef4980bb>] ip_local_deliver_finish+0x7a/0xa0
    [<00000000d7533c8c>] __netif_receive_skb_one_core+0x89/0xa0
    [<00000000a879497d>] process_backlog+0x93/0x190
    [<00000000e41ade9f>] __napi_poll+0x28/0x170
    [<00000000b4c0906b>] net_rx_action+0x14f/0x2a0
    [<00000000b20dd5d4>] __do_softirq+0xf4/0x305
    [<000000003a7d7e15>] __irq_exit_rcu+0xc3/0x140
    [<00000000968d39a2>] sysvec_apic_timer_interrupt+0x9e/0xc0
    [<000000009e920794>] asm_sysvec_apic_timer_interrupt+0x16/0x20
    [<000000008942add0>] native_safe_halt+0x13/0x20

Signed-off-by: Harsh Modi <harshmodi@google.com>
---
 net/bridge/br_netfilter_hooks.c | 2 ++
 net/bridge/br_netfilter_ipv6.c  | 1 +
 2 files changed, 3 insertions(+)

diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index ff4779036649..f20f4373ff40 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -384,6 +384,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
 				/* - Bridged-and-DNAT'ed traffic doesn't
 				 *   require ip_forwarding. */
 				if (rt->dst.dev == dev) {
+					skb_dst_drop(skb);
 					skb_dst_set(skb, &rt->dst);
 					goto bridged_dnat;
 				}
@@ -413,6 +414,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
 			kfree_skb(skb);
 			return 0;
 		}
+		skb_dst_drop(skb);
 		skb_dst_set_noref(skb, &rt->dst);
 	}
 
diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
index e4e0c836c3f5..6b07f30675bb 100644
--- a/net/bridge/br_netfilter_ipv6.c
+++ b/net/bridge/br_netfilter_ipv6.c
@@ -197,6 +197,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
 			kfree_skb(skb);
 			return 0;
 		}
+		skb_dst_drop(skb);
 		skb_dst_set_noref(skb, &rt->dst);
 	}
 
-- 
2.37.2.672.g94769d06f0-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bridge, v3] br_netfilter: Drop dst references before setting.
  2022-08-31  5:36 [PATCH bridge, v3] br_netfilter: Drop dst references before setting Harsh Modi
@ 2022-08-31  6:44 ` Florian Westphal
  2022-08-31  9:46   ` Pablo Neira Ayuso
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Westphal @ 2022-08-31  6:44 UTC (permalink / raw)
  To: Harsh Modi; +Cc: netfilter-devel, sdf, pablo, kadlec, fw

Harsh Modi <harshmodi@google.com> wrote:
> The IPv6 path already drops dst in the daddr changed case, but the IPv4
> path does not. This change makes the two code paths consistent.

Acked-by: Florian Westphal <fw@strlen.de>

Probably best to add a

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")

... just to make sure this gets propagated to stable.

Original code was likely fine because nothing ever did set a skb->dst
entry earlier than bridge in those days.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH bridge, v3] br_netfilter: Drop dst references before setting.
  2022-08-31  6:44 ` Florian Westphal
@ 2022-08-31  9:46   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2022-08-31  9:46 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Harsh Modi, netfilter-devel, sdf, kadlec

On Wed, Aug 31, 2022 at 08:44:47AM +0200, Florian Westphal wrote:
> Harsh Modi <harshmodi@google.com> wrote:
> > The IPv6 path already drops dst in the daddr changed case, but the IPv4
> > path does not. This change makes the two code paths consistent.
> 
> Acked-by: Florian Westphal <fw@strlen.de>

Applied, thanks

> Probably best to add a
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> 
> ... just to make sure this gets propagated to stable.
> 
> Original code was likely fine because nothing ever did set a skb->dst
> entry earlier than bridge in those days.

I have appended this comment for the record.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-08-31  9:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-31  5:36 [PATCH bridge, v3] br_netfilter: Drop dst references before setting Harsh Modi
2022-08-31  6:44 ` Florian Westphal
2022-08-31  9:46   ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.