Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7816a0a8 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

vlan/macvlan: fix NULL pointer dereferences in ethtool handlers



Check whether the underlying device provides a set of ethtool ops before
checking for individual handlers to avoid NULL pointer dereferences.

Reported-by: default avatarArt van Breemen <ard@telegraafnet.nl>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 75a241f9
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -376,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
	const struct macvlan_dev *vlan = netdev_priv(dev);
	const struct macvlan_dev *vlan = netdev_priv(dev);
	struct net_device *lowerdev = vlan->lowerdev;
	struct net_device *lowerdev = vlan->lowerdev;


	if (lowerdev->ethtool_ops->get_rx_csum == NULL)
	if (lowerdev->ethtool_ops == NULL ||
	    lowerdev->ethtool_ops->get_rx_csum == NULL)
		return 0;
		return 0;
	return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
	return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
}
}
@@ -387,7 +388,8 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
	const struct macvlan_dev *vlan = netdev_priv(dev);
	const struct macvlan_dev *vlan = netdev_priv(dev);
	struct net_device *lowerdev = vlan->lowerdev;
	struct net_device *lowerdev = vlan->lowerdev;


	if (!lowerdev->ethtool_ops->get_settings)
	if (!lowerdev->ethtool_ops ||
	    !lowerdev->ethtool_ops->get_settings)
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;


	return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
	return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
@@ -398,7 +400,8 @@ static u32 macvlan_ethtool_get_flags(struct net_device *dev)
	const struct macvlan_dev *vlan = netdev_priv(dev);
	const struct macvlan_dev *vlan = netdev_priv(dev);
	struct net_device *lowerdev = vlan->lowerdev;
	struct net_device *lowerdev = vlan->lowerdev;


	if (!lowerdev->ethtool_ops->get_flags)
	if (!lowerdev->ethtool_ops ||
	    !lowerdev->ethtool_ops->get_flags)
		return 0;
		return 0;
	return lowerdev->ethtool_ops->get_flags(lowerdev);
	return lowerdev->ethtool_ops->get_flags(lowerdev);
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -668,7 +668,8 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
	const struct vlan_dev_info *vlan = vlan_dev_info(dev);
	const struct vlan_dev_info *vlan = vlan_dev_info(dev);
	struct net_device *real_dev = vlan->real_dev;
	struct net_device *real_dev = vlan->real_dev;


	if (!real_dev->ethtool_ops->get_settings)
	if (!real_dev->ethtool_ops ||
	    !real_dev->ethtool_ops->get_settings)
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;


	return real_dev->ethtool_ops->get_settings(real_dev, cmd);
	return real_dev->ethtool_ops->get_settings(real_dev, cmd);