All of lore.kernel.org
 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, Hulk Robot <hulkci@huawei.com>,
	Jason Wang <jasowang@redhat.com>,
	Yang Yingliang <yangyingliang@huawei.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.14 13/45] tun: fix use-after-free when register netdev failed
Date: Wed, 18 Sep 2019 08:18:51 +0200	[thread overview]
Message-ID: <20190918061224.247780405@linuxfoundation.org> (raw)
In-Reply-To: <20190918061222.854132812@linuxfoundation.org>

From: Yang Yingliang <yangyingliang@huawei.com>

[ Upstream commit 77f22f92dff8e7b45c7786a430626d38071d4670 ]

I got a UAF repport in tun driver when doing fuzzy test:

[  466.269490] ==================================================================
[  466.271792] BUG: KASAN: use-after-free in tun_chr_read_iter+0x2ca/0x2d0
[  466.271806] Read of size 8 at addr ffff888372139250 by task tun-test/2699
[  466.271810]
[  466.271824] CPU: 1 PID: 2699 Comm: tun-test Not tainted 5.3.0-rc1-00001-g5a9433db2614-dirty #427
[  466.271833] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
[  466.271838] Call Trace:
[  466.271858]  dump_stack+0xca/0x13e
[  466.271871]  ? tun_chr_read_iter+0x2ca/0x2d0
[  466.271890]  print_address_description+0x79/0x440
[  466.271906]  ? vprintk_func+0x5e/0xf0
[  466.271920]  ? tun_chr_read_iter+0x2ca/0x2d0
[  466.271935]  __kasan_report+0x15c/0x1df
[  466.271958]  ? tun_chr_read_iter+0x2ca/0x2d0
[  466.271976]  kasan_report+0xe/0x20
[  466.271987]  tun_chr_read_iter+0x2ca/0x2d0
[  466.272013]  do_iter_readv_writev+0x4b7/0x740
[  466.272032]  ? default_llseek+0x2d0/0x2d0
[  466.272072]  do_iter_read+0x1c5/0x5e0
[  466.272110]  vfs_readv+0x108/0x180
[  466.299007]  ? compat_rw_copy_check_uvector+0x440/0x440
[  466.299020]  ? fsnotify+0x888/0xd50
[  466.299040]  ? __fsnotify_parent+0xd0/0x350
[  466.299064]  ? fsnotify_first_mark+0x1e0/0x1e0
[  466.304548]  ? vfs_write+0x264/0x510
[  466.304569]  ? ksys_write+0x101/0x210
[  466.304591]  ? do_preadv+0x116/0x1a0
[  466.304609]  do_preadv+0x116/0x1a0
[  466.309829]  do_syscall_64+0xc8/0x600
[  466.309849]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[  466.309861] RIP: 0033:0x4560f9
[  466.309875] Code: 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
[  466.309889] RSP: 002b:00007ffffa5166e8 EFLAGS: 00000206 ORIG_RAX: 0000000000000127
[  466.322992] RAX: ffffffffffffffda RBX: 0000000000400460 RCX: 00000000004560f9
[  466.322999] RDX: 0000000000000003 RSI: 00000000200008c0 RDI: 0000000000000003
[  466.323007] RBP: 00007ffffa516700 R08: 0000000000000004 R09: 0000000000000000
[  466.323014] R10: 0000000000000000 R11: 0000000000000206 R12: 000000000040cb10
[  466.323021] R13: 0000000000000000 R14: 00000000006d7018 R15: 0000000000000000
[  466.323057]
[  466.323064] Allocated by task 2605:
[  466.335165]  save_stack+0x19/0x80
[  466.336240]  __kasan_kmalloc.constprop.8+0xa0/0xd0
[  466.337755]  kmem_cache_alloc+0xe8/0x320
[  466.339050]  getname_flags+0xca/0x560
[  466.340229]  user_path_at_empty+0x2c/0x50
[  466.341508]  vfs_statx+0xe6/0x190
[  466.342619]  __do_sys_newstat+0x81/0x100
[  466.343908]  do_syscall_64+0xc8/0x600
[  466.345303]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[  466.347034]
[  466.347517] Freed by task 2605:
[  466.348471]  save_stack+0x19/0x80
[  466.349476]  __kasan_slab_free+0x12e/0x180
[  466.350726]  kmem_cache_free+0xc8/0x430
[  466.351874]  putname+0xe2/0x120
[  466.352921]  filename_lookup+0x257/0x3e0
[  466.354319]  vfs_statx+0xe6/0x190
[  466.355498]  __do_sys_newstat+0x81/0x100
[  466.356889]  do_syscall_64+0xc8/0x600
[  466.358037]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[  466.359567]
[  466.360050] The buggy address belongs to the object at ffff888372139100
[  466.360050]  which belongs to the cache names_cache of size 4096
[  466.363735] The buggy address is located 336 bytes inside of
[  466.363735]  4096-byte region [ffff888372139100, ffff88837213a100)
[  466.367179] The buggy address belongs to the page:
[  466.368604] page:ffffea000dc84e00 refcount:1 mapcount:0 mapping:ffff8883df1b4f00 index:0x0 compound_mapcount: 0
[  466.371582] flags: 0x2fffff80010200(slab|head)
[  466.372910] raw: 002fffff80010200 dead000000000100 dead000000000122 ffff8883df1b4f00
[  466.375209] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
[  466.377778] page dumped because: kasan: bad access detected
[  466.379730]
[  466.380288] Memory state around the buggy address:
[  466.381844]  ffff888372139100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  466.384009]  ffff888372139180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  466.386131] >ffff888372139200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  466.388257]                                                  ^
[  466.390234]  ffff888372139280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  466.392512]  ffff888372139300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  466.394667] ==================================================================

tun_chr_read_iter() accessed the memory which freed by free_netdev()
called by tun_set_iff():

        CPUA                                           CPUB
  tun_set_iff()
    alloc_netdev_mqs()
    tun_attach()
                                                  tun_chr_read_iter()
                                                    tun_get()
                                                    tun_do_read()
                                                      tun_ring_recv()
    register_netdevice() <-- inject error
    goto err_detach
    tun_detach_all() <-- set RCV_SHUTDOWN
    free_netdev() <-- called from
                     err_free_dev path
      netdev_freemem() <-- free the memory
                        without check refcount
      (In this path, the refcount cannot prevent
       freeing the memory of dev, and the memory
       will be used by dev_put() called by
       tun_chr_read_iter() on CPUB.)
                                                     (Break from tun_ring_recv(),
                                                     because RCV_SHUTDOWN is set)
                                                   tun_put()
                                                     dev_put() <-- use the memory
                                                                   freed by netdev_freemem()

Put the publishing of tfile->tun after register_netdevice(),
so tun_get() won't get the tun pointer that freed by
err_detach path if register_netdevice() failed.

Fixes: eb0fb363f920 ("tuntap: attach queue 0 before registering netdevice")
Reported-by: Hulk Robot <hulkci@huawei.com>
Suggested-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/tun.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -630,7 +630,8 @@ static void tun_detach_all(struct net_de
 		module_put(THIS_MODULE);
 }
 
-static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter)
+static int tun_attach(struct tun_struct *tun, struct file *file,
+		      bool skip_filter, bool publish_tun)
 {
 	struct tun_file *tfile = file->private_data;
 	struct net_device *dev = tun->dev;
@@ -672,7 +673,8 @@ static int tun_attach(struct tun_struct
 
 	tfile->queue_index = tun->numqueues;
 	tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
-	rcu_assign_pointer(tfile->tun, tun);
+	if (publish_tun)
+		rcu_assign_pointer(tfile->tun, tun);
 	rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
 	tun->numqueues++;
 
@@ -2011,7 +2013,7 @@ static int tun_set_iff(struct net *net,
 		if (err < 0)
 			return err;
 
-		err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER);
+		err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER, true);
 		if (err < 0)
 			return err;
 
@@ -2100,13 +2102,17 @@ static int tun_set_iff(struct net *net,
 				       NETIF_F_HW_VLAN_STAG_TX);
 
 		INIT_LIST_HEAD(&tun->disabled);
-		err = tun_attach(tun, file, false);
+		err = tun_attach(tun, file, false, false);
 		if (err < 0)
 			goto err_free_flow;
 
 		err = register_netdevice(tun->dev);
 		if (err < 0)
 			goto err_detach;
+		/* free_netdev() won't check refcnt, to aovid race
+		 * with dev_put() we need publish tun after registration.
+		 */
+		rcu_assign_pointer(tfile->tun, tun);
 	}
 
 	netif_carrier_on(tun->dev);
@@ -2252,7 +2258,7 @@ static int tun_set_queue(struct file *fi
 		ret = security_tun_dev_attach_queue(tun->security);
 		if (ret < 0)
 			goto unlock;
-		ret = tun_attach(tun, file, false);
+		ret = tun_attach(tun, file, false, true);
 	} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
 		tun = rtnl_dereference(tfile->tun);
 		if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached)



  parent reply	other threads:[~2019-09-18  6:20 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-18  6:18 [PATCH 4.14 00/45] 4.14.145-stable review Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 01/45] bridge/mdb: remove wrong use of NLM_F_MULTI Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 02/45] cdc_ether: fix rndis support for Mediatek based smartphones Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 03/45] ipv6: Fix the link time qualifier of ping_v6_proc_exit_net() Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 04/45] isdn/capi: check message length in capi_write() Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 05/45] net: Fix null de-reference of device refcount Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 06/45] net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 07/45] net: phylink: Fix flow control resolution Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 08/45] sch_hhf: ensure quantum and hhf_non_hh_weight are non-zero Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 09/45] sctp: Fix the link time qualifier of sctp_ctrlsock_exit() Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 10/45] sctp: use transport pf_retrans in sctp_do_8_2_transport_strike Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 11/45] tcp: fix tcp_ecn_withdraw_cwr() to clear TCP_ECN_QUEUE_CWR Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 12/45] tipc: add NULL pointer check before calling kfree_rcu Greg Kroah-Hartman
2019-09-18  6:18 ` Greg Kroah-Hartman [this message]
2019-09-18  6:18 ` [PATCH 4.14 14/45] btrfs: compression: add helper for type to string conversion Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 15/45] btrfs: correctly validate compression type Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 16/45] Revert "MIPS: SiByte: Enable swiotlb for SWARM, LittleSur and BigSur" Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 17/45] gpiolib: acpi: Add gpiolib_acpi_run_edge_events_on_boot option and blacklist Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 18/45] gpio: fix line flag validation in linehandle_create Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 19/45] gpio: fix line flag validation in lineevent_create Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 20/45] Btrfs: fix assertion failure during fsync and use of stale transaction Greg Kroah-Hartman
2019-09-18  6:18 ` [PATCH 4.14 21/45] genirq: Prevent NULL pointer dereference in resend_irqs() Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 22/45] KVM: s390: Do not leak kernel stack data in the KVM_S390_INTERRUPT ioctl Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 23/45] KVM: x86: work around leak of uninitialized stack contents Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 24/45] KVM: nVMX: handle page fault in vmread Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 25/45] MIPS: VDSO: Prevent use of smp_processor_id() Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 26/45] MIPS: VDSO: Use same -m%-float cflag as the kernel proper Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 27/45] powerpc: Add barrier_nospec to raw_copy_in_user() Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 28/45] drm/meson: Add support for XBGR8888 & ABGR8888 formats Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 29/45] clk: rockchip: Dont yell about bad mmc phases when getting Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 30/45] mtd: rawnand: mtk: Fix wrongly assigned OOB buffer pointer issue Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 31/45] PCI: Always allow probing with driver_override Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 32/45] ubifs: Correctly use tnc_next() in search_dh_cookie() Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 33/45] driver core: Fix use-after-free and double free on glue directory Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 34/45] crypto: talitos - check AES key size Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 35/45] crypto: talitos - fix CTR alg blocksize Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 36/45] crypto: talitos - check data blocksize in ablkcipher Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 37/45] crypto: talitos - fix ECB algs ivsize Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 38/45] crypto: talitos - Do not modify req->cryptlen on decryption Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 39/45] crypto: talitos - HMAC SNOOP NO AFEU mode requires SW icv checking Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 40/45] firmware: ti_sci: Always request response from firmware Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 41/45] drm/mediatek: mtk_drm_drv.c: Add of_node_put() before goto Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 42/45] Revert "Bluetooth: btusb: driver to enable the usb-wakeup feature" Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 43/45] platform/x86: pmc_atom: Add CB4063 Beckhoff Automation board to critclk_systems DMI table Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 44/45] nvmem: Use the same permissions for eeprom as for nvmem Greg Kroah-Hartman
2019-09-18  6:19 ` [PATCH 4.14 45/45] x86/build: Add -Wnoaddress-of-packed-member to REALMODE_CFLAGS, to silence GCC9 build warning Greg Kroah-Hartman
2019-09-18 13:19 ` [PATCH 4.14 00/45] 4.14.145-stable review kernelci.org bot
2019-09-18 13:55 ` Naresh Kamboju
2019-09-18 16:28 ` Jon Hunter
2019-09-18 16:28   ` Jon Hunter
2019-09-18 19:37 ` Guenter Roeck
2019-09-19  1:26 ` shuah

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=20190918061224.247780405@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=davem@davemloft.net \
    --cc=hulkci@huawei.com \
    --cc=jasowang@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=yangyingliang@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 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.