Commit ae9fcd5a authored by Kees Cook's avatar Kees Cook Committed by Paolo Abeni
Browse files

net: core: Convert dev_set_mac_address_user() to use struct sockaddr_storage



Convert callers of dev_set_mac_address_user() to use struct
sockaddr_storage. Add sanity checks on dev->addr_len usage.

Signed-off-by: default avatarKees Cook <kees@kernel.org>
Acked-by: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
Link: https://patch.msgid.link/20250521204619.2301870-8-kees@kernel.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6b12e0a3
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -923,7 +923,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
	unsigned int __user *up = argp;
	unsigned short u;
	int __user *sp = argp;
	struct sockaddr sa;
	struct sockaddr_storage ss;
	int s;
	int ret;

@@ -1000,16 +1000,17 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
			return -ENOLINK;
		}
		ret = 0;
		dev_get_mac_address(&sa, dev_net(tap->dev), tap->dev->name);
		dev_get_mac_address((struct sockaddr *)&ss, 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, sizeof(sa)))
		    copy_to_user(&ifr->ifr_hwaddr, &ss, sizeof(ifr->ifr_hwaddr)))
			ret = -EFAULT;
		tap_put_tap_dev(tap);
		rtnl_unlock();
		return ret;

	case SIOCSIFHWADDR:
		if (copy_from_user(&sa, &ifr->ifr_hwaddr, sizeof(sa)))
		if (copy_from_user(&ss, &ifr->ifr_hwaddr, sizeof(ifr->ifr_hwaddr)))
			return -EFAULT;
		rtnl_lock();
		tap = tap_get_tap_dev(q);
@@ -1017,7 +1018,10 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
			rtnl_unlock();
			return -ENOLINK;
		}
		ret = dev_set_mac_address_user(tap->dev, &sa, NULL);
		if (tap->dev->addr_len > sizeof(ifr->ifr_hwaddr))
			ret = -EINVAL;
		else
			ret = dev_set_mac_address_user(tap->dev, &ss, NULL);
		tap_put_tap_dev(tap);
		rtnl_unlock();
		return ret;
+7 −1
Original line number Diff line number Diff line
@@ -3193,7 +3193,13 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,

	case SIOCSIFHWADDR:
		/* Set hw address */
		ret = dev_set_mac_address_user(tun->dev, &ifr.ifr_hwaddr, NULL);
		if (tun->dev->addr_len > sizeof(ifr.ifr_hwaddr)) {
			ret = -EINVAL;
			break;
		}
		ret = dev_set_mac_address_user(tun->dev,
					       (struct sockaddr_storage *)&ifr.ifr_hwaddr,
					       NULL);
		break;

	case TUNGETSNDBUF:
+1 −1
Original line number Diff line number Diff line
@@ -4216,7 +4216,7 @@ int netif_set_mac_address(struct net_device *dev, struct sockaddr_storage *ss,
			  struct netlink_ext_ack *extack);
int dev_set_mac_address(struct net_device *dev, struct sockaddr_storage *ss,
			struct netlink_ext_ack *extack);
int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
int dev_set_mac_address_user(struct net_device *dev, struct sockaddr_storage *ss,
			     struct netlink_ext_ack *extack);
int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name);
int dev_get_port_parent_id(struct net_device *dev,
+3 −2
Original line number Diff line number Diff line
@@ -84,14 +84,15 @@ void dev_set_group(struct net_device *dev, int new_group)
	netdev_unlock_ops(dev);
}

int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
int dev_set_mac_address_user(struct net_device *dev,
			     struct sockaddr_storage *ss,
			     struct netlink_ext_ack *extack)
{
	int ret;

	down_write(&dev_addr_sem);
	netdev_lock_ops(dev);
	ret = netif_set_mac_address(dev, (struct sockaddr_storage *)sa, extack);
	ret = netif_set_mac_address(dev, ss, extack);
	netdev_unlock_ops(dev);
	up_write(&dev_addr_sem);

+4 −2
Original line number Diff line number Diff line
@@ -572,9 +572,11 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
		return dev_set_mtu(dev, ifr->ifr_mtu);

	case SIOCSIFHWADDR:
		if (dev->addr_len > sizeof(struct sockaddr))
		if (dev->addr_len > sizeof(ifr->ifr_hwaddr))
			return -EINVAL;
		return dev_set_mac_address_user(dev, &ifr->ifr_hwaddr, NULL);
		return dev_set_mac_address_user(dev,
						(struct sockaddr_storage *)&ifr->ifr_hwaddr,
						NULL);

	case SIOCSIFHWBROADCAST:
		if (ifr->ifr_hwaddr.sa_family != dev->type)