linux-stable/net/bridge
Harsh Modi 92c4fe831a netfilter: br_netfilter: Drop dst references before setting.
[ Upstream commit d047283a70 ]

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

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

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Harsh Modi <harshmodi@google.com>
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-09-15 12:39:46 +02:00
..
netfilter netfilter: nft_reject_bridge: enable reject with bridge vlan 2020-06-03 08:16:45 +02:00
Kconfig
Makefile bridge: switchdev: Add forward mark support for stacked devices 2016-08-26 13:13:36 -07:00
br.c netfilter: bridge: clarify bridge/netfilter message 2016-10-02 22:44:03 -04:00
br_device.c net: bridge: add missing counters to ndo_get_stats64 callback 2020-11-24 13:02:55 +01:00
br_fdb.c rtnetlink: fdb dump: optimize by saving last interface markers 2016-09-01 16:56:15 -07:00
br_forward.c net: bridge: Fix ethernet header pointer before check skb forwardable 2019-01-31 08:12:32 +01:00
br_if.c net: bridge: fix memleak in br_add_if() 2021-08-26 08:37:22 -04:00
br_input.c net: bridge: fix per-port af_packet sockets 2019-04-27 09:34:40 +02:00
br_ioctl.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-05-09 15:59:24 -04:00
br_mdb.c bridge/mdb: remove wrong use of NLM_F_MULTI 2019-09-21 07:14:01 +02:00
br_multicast.c net: bridge: mcast: don't delete permanent entries when fast leave is enabled 2019-08-11 12:22:16 +02:00
br_netfilter_hooks.c netfilter: br_netfilter: Drop dst references before setting. 2022-09-15 12:39:46 +02:00
br_netfilter_ipv6.c netfilter: br_netfilter: Drop dst references before setting. 2022-09-15 12:39:46 +02:00
br_netlink.c net: bridge: use nla_total_size_64bit() in br_get_linkxstats_size() 2021-10-17 10:05:39 +02:00
br_nf_core.c
br_private.h net: bridge: change unicast boolean to exact pkt_type 2016-09-01 22:48:33 -07:00
br_private_stp.h
br_stp.c net: bridge: br_set_ageing_time takes a clock_t 2016-07-25 10:30:03 -07:00
br_stp_bpdu.c net: bridge: stp: don't cache eth dest pointer before skb pull 2019-08-04 09:33:35 +02:00
br_stp_if.c net: bridge: start hello timer only if device is up 2017-06-14 15:05:52 +02:00
br_stp_timer.c bridge: start hello_timer when enabling KERNEL_STP in br_stp_start 2017-06-07 12:07:44 +02:00
br_switchdev.c bridge: switchdev: Add forward mark support for stacked devices 2016-08-26 13:13:36 -07:00
br_sysfs_br.c net: bridge: set error code on failure 2016-12-05 13:26:22 -05:00
br_sysfs_if.c bridge: check brport attr show in brport_show 2018-03-11 16:21:31 +01:00
br_vlan.c net: bridge: vlan: fix error return code in __vlan_add() 2020-12-29 13:44:48 +01:00