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, "Gong, Sishuai" <sishuai@purdue.edu>,
	Eric Dumazet <eric.dumazet@gmail.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Cong Wang <cong.wang@bytedance.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 5.4 20/72] net: fix dev_ifsioc_locked() race condition
Date: Fri,  5 Mar 2021 13:21:22 +0100	[thread overview]
Message-ID: <20210305120858.329000993@linuxfoundation.org> (raw)
In-Reply-To: <20210305120857.341630346@linuxfoundation.org>

From: Cong Wang <cong.wang@bytedance.com>

commit 3b23a32a63219f51a5298bc55a65ecee866e79d0 upstream.

dev_ifsioc_locked() is called with only RCU read lock, so when
there is a parallel writer changing the mac address, it could
get a partially updated mac address, as shown below:

Thread 1			Thread 2
// eth_commit_mac_addr_change()
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
				// dev_ifsioc_locked()
				memcpy(ifr->ifr_hwaddr.sa_data,
					dev->dev_addr,...);

Close this race condition by guarding them with a RW semaphore,
like netdev_get_name(). We can not use seqlock here as it does not
allow blocking. The writers already take RTNL anyway, so this does
not affect the slow path. To avoid bothering existing
dev_set_mac_address() callers in drivers, introduce a new wrapper
just for user-facing callers on ioctl and rtnetlink paths.

Note, bonding also changes slave mac addresses but that requires
a separate patch due to the complexity of bonding code.

Fixes: 3710becf8a58 ("net: RCU locking for simple ioctl()")
Reported-by: "Gong, Sishuai" <sishuai@purdue.edu>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/tap.c         |    7 +++----
 drivers/net/tun.c         |    4 ++--
 include/linux/netdevice.h |    3 +++
 net/core/dev.c            |   42 ++++++++++++++++++++++++++++++++++++++++++
 net/core/dev_ioctl.c      |   20 +++++++-------------
 net/core/rtnetlink.c      |    2 +-
 6 files changed, 58 insertions(+), 20 deletions(-)

--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -1095,10 +1095,9 @@ static long tap_ioctl(struct file *file,
 			return -ENOLINK;
 		}
 		ret = 0;
-		u = tap->dev->type;
+		dev_get_mac_address(&sa, dev_net(tap->dev), tap->dev->name);
 		if (copy_to_user(&ifr->ifr_name, tap->dev->name, IFNAMSIZ) ||
-		    copy_to_user(&ifr->ifr_hwaddr.sa_data, tap->dev->dev_addr, ETH_ALEN) ||
-		    put_user(u, &ifr->ifr_hwaddr.sa_family))
+		    copy_to_user(&ifr->ifr_hwaddr, &sa, sizeof(sa)))
 			ret = -EFAULT;
 		tap_put_tap_dev(tap);
 		rtnl_unlock();
@@ -1113,7 +1112,7 @@ static long tap_ioctl(struct file *file,
 			rtnl_unlock();
 			return -ENOLINK;
 		}
-		ret = dev_set_mac_address(tap->dev, &sa, NULL);
+		ret = dev_set_mac_address_user(tap->dev, &sa, NULL);
 		tap_put_tap_dev(tap);
 		rtnl_unlock();
 		return ret;
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -3224,7 +3224,7 @@ static long __tun_chr_ioctl(struct file
 	case SIOCGIFHWADDR:
 		/* Get hw address */
 		memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
-		ifr.ifr_hwaddr.sa_family = tun->dev->type;
+		dev_get_mac_address(&ifr.ifr_hwaddr, net, tun->dev->name);
 		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
 		break;
@@ -3234,7 +3234,7 @@ static long __tun_chr_ioctl(struct file
 		tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n",
 			  ifr.ifr_hwaddr.sa_data);
 
-		ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr, NULL);
+		ret = dev_set_mac_address_user(tun->dev, &ifr.ifr_hwaddr, NULL);
 		break;
 
 	case TUNGETSNDBUF:
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3679,6 +3679,9 @@ int dev_pre_changeaddr_notify(struct net
 			      struct netlink_ext_ack *extack);
 int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
 			struct netlink_ext_ack *extack);
+int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
+			     struct netlink_ext_ack *extack);
+int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name);
 int dev_change_carrier(struct net_device *, bool new_carrier);
 int dev_get_phys_port_id(struct net_device *dev,
 			 struct netdev_phys_item_id *ppid);
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -8144,6 +8144,48 @@ int dev_set_mac_address(struct net_devic
 }
 EXPORT_SYMBOL(dev_set_mac_address);
 
+static DECLARE_RWSEM(dev_addr_sem);
+
+int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
+			     struct netlink_ext_ack *extack)
+{
+	int ret;
+
+	down_write(&dev_addr_sem);
+	ret = dev_set_mac_address(dev, sa, extack);
+	up_write(&dev_addr_sem);
+	return ret;
+}
+EXPORT_SYMBOL(dev_set_mac_address_user);
+
+int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name)
+{
+	size_t size = sizeof(sa->sa_data);
+	struct net_device *dev;
+	int ret = 0;
+
+	down_read(&dev_addr_sem);
+	rcu_read_lock();
+
+	dev = dev_get_by_name_rcu(net, dev_name);
+	if (!dev) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+	if (!dev->addr_len)
+		memset(sa->sa_data, 0, size);
+	else
+		memcpy(sa->sa_data, dev->dev_addr,
+		       min_t(size_t, size, dev->addr_len));
+	sa->sa_family = dev->type;
+
+unlock:
+	rcu_read_unlock();
+	up_read(&dev_addr_sem);
+	return ret;
+}
+EXPORT_SYMBOL(dev_get_mac_address);
+
 /**
  *	dev_change_carrier - Change device carrier
  *	@dev: device
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -122,17 +122,6 @@ static int dev_ifsioc_locked(struct net
 		ifr->ifr_mtu = dev->mtu;
 		return 0;
 
-	case SIOCGIFHWADDR:
-		if (!dev->addr_len)
-			memset(ifr->ifr_hwaddr.sa_data, 0,
-			       sizeof(ifr->ifr_hwaddr.sa_data));
-		else
-			memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
-			       min(sizeof(ifr->ifr_hwaddr.sa_data),
-				   (size_t)dev->addr_len));
-		ifr->ifr_hwaddr.sa_family = dev->type;
-		return 0;
-
 	case SIOCGIFSLAVE:
 		err = -EINVAL;
 		break;
@@ -246,7 +235,7 @@ static int dev_ifsioc(struct net *net, s
 	case SIOCSIFHWADDR:
 		if (dev->addr_len > sizeof(struct sockaddr))
 			return -EINVAL;
-		return dev_set_mac_address(dev, &ifr->ifr_hwaddr, NULL);
+		return dev_set_mac_address_user(dev, &ifr->ifr_hwaddr, NULL);
 
 	case SIOCSIFHWBROADCAST:
 		if (ifr->ifr_hwaddr.sa_family != dev->type)
@@ -396,6 +385,12 @@ int dev_ioctl(struct net *net, unsigned
 	 */
 
 	switch (cmd) {
+	case SIOCGIFHWADDR:
+		dev_load(net, ifr->ifr_name);
+		ret = dev_get_mac_address(&ifr->ifr_hwaddr, net, ifr->ifr_name);
+		if (colon)
+			*colon = ':';
+		return ret;
 	/*
 	 *	These ioctl calls:
 	 *	- can be done by all.
@@ -405,7 +400,6 @@ int dev_ioctl(struct net *net, unsigned
 	case SIOCGIFFLAGS:
 	case SIOCGIFMETRIC:
 	case SIOCGIFMTU:
-	case SIOCGIFHWADDR:
 	case SIOCGIFSLAVE:
 	case SIOCGIFMAP:
 	case SIOCGIFINDEX:
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2471,7 +2471,7 @@ static int do_setlink(const struct sk_bu
 		sa->sa_family = dev->type;
 		memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
 		       dev->addr_len);
-		err = dev_set_mac_address(dev, sa, extack);
+		err = dev_set_mac_address_user(dev, sa, extack);
 		kfree(sa);
 		if (err)
 			goto errout;



  parent reply	other threads:[~2021-03-05 12:34 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-05 12:21 [PATCH 5.4 00/72] 5.4.103-rc1 review Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 01/72] net: usb: qmi_wwan: support ZTE P685M modem Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 02/72] Input: elantech - fix protocol errors for some trackpoints in SMBus mode Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 03/72] nvme-pci: refactor nvme_unmap_data Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 04/72] nvme-pci: fix error unwind in nvme_map_data Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 05/72] arm64 module: set plt* section addresses to 0x0 Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 06/72] MIPS: VDSO: Use CLANG_FLAGS instead of filtering out --target= Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 07/72] JFS: more checks for invalid superblock Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 08/72] udlfb: Fix memory leak in dlfb_usb_probe Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 09/72] media: mceusb: sanity check for prescaler value Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 10/72] erofs: fix shift-out-of-bounds of blkszbits Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 11/72] media: v4l2-ctrls.c: fix shift-out-of-bounds in std_validate Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 12/72] xfs: Fix assert failure in xfs_setattr_size() Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 13/72] net/af_iucv: remove WARN_ONCE on malformed RX packets Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 14/72] smackfs: restrict bytes count in smackfs write functions Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 15/72] net: fix up truesize of cloned skb in skb_prepare_for_shift() Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 16/72] nbd: handle device refs for DESTROY_ON_DISCONNECT properly Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 17/72] mm/hugetlb.c: fix unnecessary address expansion of pmd sharing Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 18/72] net: bridge: use switchdev for port flags set through sysfs too Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 19/72] net: ag71xx: remove unnecessary MTU reservation Greg Kroah-Hartman
2021-03-05 12:21 ` Greg Kroah-Hartman [this message]
2021-03-05 12:21 ` [PATCH 5.4 21/72] dt-bindings: ethernet-controller: fix fixed-link specification Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 22/72] dt-bindings: net: btusb: DT fix s/interrupt-name/interrupt-names/ Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 23/72] MIPS: Drop 32-bit asm string functions Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 24/72] drm/virtio: use kvmalloc for large allocations Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 25/72] rsi: Fix TX EAPOL packet handling against iwlwifi AP Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 26/72] rsi: Move card interrupt handling to RX thread Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 27/72] rcu/nocb: Trigger self-IPI on late deferred wake up before user resume Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 28/72] staging: fwserial: Fix error handling in fwserial_create Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 29/72] x86/reboot: Add Zotac ZBOX CI327 nano PCI reboot quirk Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 30/72] vt/consolemap: do font sum unsigned Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 31/72] wlcore: Fix command execute failure 19 for wl12xx Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 32/72] Bluetooth: hci_h5: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for btrtl Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 33/72] pktgen: fix misuse of BUG_ON() in pktgen_thread_worker() Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 34/72] ath10k: fix wmi mgmt tx queue full due to race condition Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 35/72] x86/build: Treat R_386_PLT32 relocation as R_386_PC32 Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 36/72] Bluetooth: Fix null pointer dereference in amp_read_loc_assoc_final_data Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 37/72] staging: most: sound: add sanity check for function argument Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 38/72] staging: bcm2835-audio: Replace unsafe strcpy() with strscpy() Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 39/72] brcmfmac: Add DMI nvram filename quirk for Predia Basic tablet Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 40/72] brcmfmac: Add DMI nvram filename quirk for Voyo winpad A15 tablet Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 41/72] drm/hisilicon: Fix use-after-free Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 42/72] crypto: tcrypt - avoid signed overflow in byte count Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 43/72] drm/amdgpu: Add check to prevent IH overflow Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 44/72] PCI: Add a REBAR size quirk for Sapphire RX 5600 XT Pulse Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 45/72] drm/amd/display: Guard against NULL pointer deref when get_i2c_info fails Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 46/72] media: uvcvideo: Allow entities with no pads Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 47/72] f2fs: handle unallocated section and zone on pinned/atgc Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 48/72] f2fs: fix to set/clear I_LINKABLE under i_lock Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 49/72] nvme-core: add cancel tagset helpers Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 50/72] nvme-rdma: add clean action for failed reconnection Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 51/72] nvme-tcp: " Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 52/72] ASoC: Intel: Add DMI quirk table to soc_intel_is_byt_cr() Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 53/72] btrfs: fix error handling in commit_fs_roots Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 54/72] perf/x86/kvm: Add Cascade Lake Xeon steppings to isolation_ucodes[] Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 55/72] parisc: Bump 64-bit IRQ stack size to 64 KB Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 56/72] sched/features: Fix hrtick reprogramming Greg Kroah-Hartman
2021-03-05 12:21 ` [PATCH 5.4 57/72] ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R tablet Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 58/72] ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 59/72] ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 60/72] ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 61/72] scsi: iscsi: Restrict sessions and handles to admin capabilities Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 62/72] sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 63/72] scsi: iscsi: Ensure sysfs attributes are limited to PAGE_SIZE Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 64/72] scsi: iscsi: Verify lengths on passthrough PDUs Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 65/72] Xen/gnttab: handle p2m update errors on a per-slot basis Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 66/72] xen-netback: respect gnttab_map_refs()s return value Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 67/72] zsmalloc: account the number of compacted pages correctly Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 68/72] swap: fix swapfile read/write offset Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 69/72] media: v4l: ioctl: Fix memory leak in video_usercopy Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 70/72] ALSA: hda/realtek: Add quirk for Clevo NH55RZQ Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 71/72] ALSA: hda/realtek: Add quirk for Intel NUC 10 Greg Kroah-Hartman
2021-03-05 12:22 ` [PATCH 5.4 72/72] ALSA: hda/realtek: Apply dual codec quirks for MSI Godlike X570 board Greg Kroah-Hartman
2021-03-06  0:57 ` [PATCH 5.4 00/72] 5.4.103-rc1 review Samuel Zou
2021-03-06  9:55   ` Greg Kroah-Hartman
2021-03-06  3:23 ` Guenter Roeck
2021-03-06  9:55   ` Greg Kroah-Hartman
2021-03-06  5:25 ` Florian Fainelli
2021-03-06  9:55 ` Naresh Kamboju
2021-03-06 16:33 ` Guenter Roeck

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=20210305120858.329000993@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=cong.wang@bytedance.com \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sishuai@purdue.edu \
    --cc=stable@vger.kernel.org \
    /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).