linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Ziyang Xuan <william.xuanziyang@huawei.com>,
	Oliver Hartkopp <socketcan@hartkopp.net>,
	Marc Kleine-Budde <mkl@pengutronix.de>
Subject: [PATCH 4.14 19/38] can: raw: raw_setsockopt(): fix raw_rcv panic for sock UAF
Date: Mon,  2 Aug 2021 15:44:41 +0200	[thread overview]
Message-ID: <20210802134335.438356324@linuxfoundation.org> (raw)
In-Reply-To: <20210802134334.835358048@linuxfoundation.org>

From: Ziyang Xuan <william.xuanziyang@huawei.com>

commit 54f93336d000229f72c26d8a3f69dd256b744528 upstream.

We get a bug during ltp can_filter test as following.

===========================================
[60919.264984] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
[60919.265223] PGD 8000003dda726067 P4D 8000003dda726067 PUD 3dda727067 PMD 0
[60919.265443] Oops: 0000 [#1] SMP PTI
[60919.265550] CPU: 30 PID: 3638365 Comm: can_filter Kdump: loaded Tainted: G        W         4.19.90+ #1
[60919.266068] RIP: 0010:selinux_socket_sock_rcv_skb+0x3e/0x200
[60919.293289] RSP: 0018:ffff8d53bfc03cf8 EFLAGS: 00010246
[60919.307140] RAX: 0000000000000000 RBX: 000000000000001d RCX: 0000000000000007
[60919.320756] RDX: 0000000000000001 RSI: ffff8d5104a8ed00 RDI: ffff8d53bfc03d30
[60919.334319] RBP: ffff8d9338056800 R08: ffff8d53bfc29d80 R09: 0000000000000001
[60919.347969] R10: ffff8d53bfc03ec0 R11: ffffb8526ef47c98 R12: ffff8d53bfc03d30
[60919.350320] perf: interrupt took too long (3063 > 2500), lowering kernel.perf_event_max_sample_rate to 65000
[60919.361148] R13: 0000000000000001 R14: ffff8d53bcf90000 R15: 0000000000000000
[60919.361151] FS:  00007fb78b6b3600(0000) GS:ffff8d53bfc00000(0000) knlGS:0000000000000000
[60919.400812] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[60919.413730] CR2: 0000000000000010 CR3: 0000003e3f784006 CR4: 00000000007606e0
[60919.426479] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[60919.439339] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[60919.451608] PKRU: 55555554
[60919.463622] Call Trace:
[60919.475617]  <IRQ>
[60919.487122]  ? update_load_avg+0x89/0x5d0
[60919.498478]  ? update_load_avg+0x89/0x5d0
[60919.509822]  ? account_entity_enqueue+0xc5/0xf0
[60919.520709]  security_sock_rcv_skb+0x2a/0x40
[60919.531413]  sk_filter_trim_cap+0x47/0x1b0
[60919.542178]  ? kmem_cache_alloc+0x38/0x1b0
[60919.552444]  sock_queue_rcv_skb+0x17/0x30
[60919.562477]  raw_rcv+0x110/0x190 [can_raw]
[60919.572539]  can_rcv_filter+0xbc/0x1b0 [can]
[60919.582173]  can_receive+0x6b/0xb0 [can]
[60919.591595]  can_rcv+0x31/0x70 [can]
[60919.600783]  __netif_receive_skb_one_core+0x5a/0x80
[60919.609864]  process_backlog+0x9b/0x150
[60919.618691]  net_rx_action+0x156/0x400
[60919.627310]  ? sched_clock_cpu+0xc/0xa0
[60919.635714]  __do_softirq+0xe8/0x2e9
[60919.644161]  do_softirq_own_stack+0x2a/0x40
[60919.652154]  </IRQ>
[60919.659899]  do_softirq.part.17+0x4f/0x60
[60919.667475]  __local_bh_enable_ip+0x60/0x70
[60919.675089]  __dev_queue_xmit+0x539/0x920
[60919.682267]  ? finish_wait+0x80/0x80
[60919.689218]  ? finish_wait+0x80/0x80
[60919.695886]  ? sock_alloc_send_pskb+0x211/0x230
[60919.702395]  ? can_send+0xe5/0x1f0 [can]
[60919.708882]  can_send+0xe5/0x1f0 [can]
[60919.715037]  raw_sendmsg+0x16d/0x268 [can_raw]

It's because raw_setsockopt() concurrently with
unregister_netdevice_many(). Concurrent scenario as following.

	cpu0						cpu1
raw_bind
raw_setsockopt					unregister_netdevice_many
						unlist_netdevice
dev_get_by_index				raw_notifier
raw_enable_filters				......
can_rx_register
can_rcv_list_find(..., net->can.rx_alldev_list)

......

sock_close
raw_release(sock_a)

......

can_receive
can_rcv_filter(net->can.rx_alldev_list, ...)
raw_rcv(skb, sock_a)
BUG

After unlist_netdevice(), dev_get_by_index() return NULL in
raw_setsockopt(). Function raw_enable_filters() will add sock
and can_filter to net->can.rx_alldev_list. Then the sock is closed.
Followed by, we sock_sendmsg() to a new vcan device use the same
can_filter. Protocol stack match the old receiver whose sock has
been released on net->can.rx_alldev_list in can_rcv_filter().
Function raw_rcv() uses the freed sock. UAF BUG is triggered.

We can find that the key issue is that net_device has not been
protected in raw_setsockopt(). Use rtnl_lock to protect net_device
in raw_setsockopt().

Fixes: c18ce101f2e4 ("[CAN]: Add raw protocol")
Link: https://lore.kernel.org/r/20210722070819.1048263-1-william.xuanziyang@huawei.com
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/can/raw.c |   20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -549,10 +549,18 @@ static int raw_setsockopt(struct socket
 				return -EFAULT;
 		}
 
+		rtnl_lock();
 		lock_sock(sk);
 
-		if (ro->bound && ro->ifindex)
+		if (ro->bound && ro->ifindex) {
 			dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+			if (!dev) {
+				if (count > 1)
+					kfree(filter);
+				err = -ENODEV;
+				goto out_fil;
+			}
+		}
 
 		if (ro->bound) {
 			/* (try to) register the new filters */
@@ -591,6 +599,7 @@ static int raw_setsockopt(struct socket
 			dev_put(dev);
 
 		release_sock(sk);
+		rtnl_unlock();
 
 		break;
 
@@ -603,10 +612,16 @@ static int raw_setsockopt(struct socket
 
 		err_mask &= CAN_ERR_MASK;
 
+		rtnl_lock();
 		lock_sock(sk);
 
-		if (ro->bound && ro->ifindex)
+		if (ro->bound && ro->ifindex) {
 			dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+			if (!dev) {
+				err = -ENODEV;
+				goto out_err;
+			}
+		}
 
 		/* remove current error mask */
 		if (ro->bound) {
@@ -630,6 +645,7 @@ static int raw_setsockopt(struct socket
 			dev_put(dev);
 
 		release_sock(sk);
+		rtnl_unlock();
 
 		break;
 



  parent reply	other threads:[~2021-08-02 13:52 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-02 13:44 [PATCH 4.14 00/38] 4.14.242-rc1 review Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 01/38] selftest: fix build error in tools/testing/selftests/vm/userfaultfd.c Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 02/38] KVM: x86: determine if an exception has an error code only when injecting it Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 03/38] net: split out functions related to registering inflight socket files Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 04/38] af_unix: fix garbage collect vs MSG_PEEK Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 05/38] workqueue: fix UAF in pwq_unbound_release_workfn() Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 06/38] net/802/mrp: fix memleak in mrp_request_join() Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 07/38] net/802/garp: fix memleak in garp_request_join() Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 08/38] net: annotate data race around sk_ll_usec Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 09/38] sctp: move 198 addresses from unusable to private scope Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 10/38] hfs: add missing clean-up in hfs_fill_super Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 11/38] hfs: fix high memory mapping in hfs_bnode_read Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 12/38] hfs: add lock nesting notation to hfs_find_init Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 13/38] ARM: dts: versatile: Fix up interrupt controller node names Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 14/38] virtio_net: Do not pull payload in skb->head Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 15/38] gro: ensure frag0 meets IP header alignment Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 16/38] x86/kvm: fix vcpu-id indexed array sizes Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 17/38] ocfs2: fix zero out valid data Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 18/38] ocfs2: issue zeroout to EOF blocks Greg Kroah-Hartman
2021-08-02 13:44 ` Greg Kroah-Hartman [this message]
2021-08-02 13:44 ` [PATCH 4.14 20/38] can: mcba_usb_start(): add missing urb->transfer_dma initialization Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 21/38] can: usb_8dev: fix memory leak Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 22/38] can: ems_usb: " Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 23/38] can: esd_usb2: " Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 24/38] NIU: fix incorrect error return, missed in previous revert Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 25/38] nfc: nfcsim: fix use after free during module unload Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 26/38] x86/asm: Ensure asm/proto.h can be included stand-alone Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 27/38] cfg80211: Fix possible memory leak in function cfg80211_bss_update Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 28/38] netfilter: conntrack: adjust stop timestamp to real expiry value Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 29/38] netfilter: nft_nat: allow to specify layer 4 protocol NAT only Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 30/38] tipc: fix sleeping in tipc accept routine Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 31/38] mlx4: Fix missing error code in mlx4_load_one() Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 32/38] net: llc: fix skb_over_panic Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 33/38] net/mlx5: Fix flow table chaining Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 34/38] sctp: fix return value check in __sctp_rcv_asconf_lookup Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 35/38] tulip: windbond-840: Fix missing pci_disable_device() in probe and remove Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 36/38] sis900: " Greg Kroah-Hartman
2021-08-02 13:44 ` [PATCH 4.14 37/38] can: hi311x: fix a signedness bug in hi3110_cmd() Greg Kroah-Hartman
2021-08-02 13:45 ` [PATCH 4.14 38/38] Revert "perf map: Fix dso->nsinfo refcounting" Greg Kroah-Hartman
2021-08-03 13:17 ` [PATCH 4.14 00/38] 4.14.242-rc1 review Naresh Kamboju
2021-08-03 19:15 ` Guenter Roeck
2021-08-04  2:56 ` Samuel Zou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210802134335.438356324@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=socketcan@hartkopp.net \
    --cc=stable@vger.kernel.org \
    --cc=william.xuanziyang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).