* vlan/macvlan: fix NULL pointer dereferences in ethtool handlers
@ 2009-04-17 16:05 Patrick McHardy
2009-04-17 22:59 ` David Miller
0 siblings, 1 reply; 3+ messages in thread
From: Patrick McHardy @ 2009-04-17 16:05 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 2303 bytes --]
commit c9bfff86b3c8e39df7ddd34e1eac238edc5bf810
Author: Patrick McHardy <kaber@trash.net>
Date: Fri Apr 17 18:04:43 2009 +0200
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: Art van Breemen <ard@telegraafnet.nl>
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 70d3ef4..214a8cf 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -376,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
const struct macvlan_dev *vlan = netdev_priv(dev);
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 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);
struct net_device *lowerdev = vlan->lowerdev;
- if (!lowerdev->ethtool_ops->get_settings)
+ if (!lowerdev->ethtool_ops ||
+ !lowerdev->ethtool_ops->get_settings)
return -EOPNOTSUPP;
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);
struct net_device *lowerdev = vlan->lowerdev;
- if (!lowerdev->ethtool_ops->get_flags)
+ if (!lowerdev->ethtool_ops ||
+ !lowerdev->ethtool_ops->get_flags)
return 0;
return lowerdev->ethtool_ops->get_flags(lowerdev);
}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 1b34135..6b09213 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -668,7 +668,8 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
const struct vlan_dev_info *vlan = vlan_dev_info(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 real_dev->ethtool_ops->get_settings(real_dev, cmd);
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: vlan/macvlan: fix NULL pointer dereferences in ethtool handlers
2009-04-17 16:05 vlan/macvlan: fix NULL pointer dereferences in ethtool handlers Patrick McHardy
@ 2009-04-17 22:59 ` David Miller
2009-04-20 14:49 ` Patrick McHardy
0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2009-04-17 22:59 UTC (permalink / raw)
To: kaber; +Cc: netdev
From: Patrick McHardy <kaber@trash.net>
Date: Fri, 17 Apr 2009 18:05:32 +0200
> 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: Art van Breemen <ard@telegraafnet.nl>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
Applied, thanks Patrick.
These things beg for helper functions in my opinion.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: vlan/macvlan: fix NULL pointer dereferences in ethtool handlers
2009-04-17 22:59 ` David Miller
@ 2009-04-20 14:49 ` Patrick McHardy
0 siblings, 0 replies; 3+ messages in thread
From: Patrick McHardy @ 2009-04-20 14:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 574 bytes --]
David Miller wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Fri, 17 Apr 2009 18:05:32 +0200
>
>> 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: Art van Breemen <ard@telegraafnet.nl>
>> Signed-off-by: Patrick McHardy <kaber@trash.net>
>
> Applied, thanks Patrick.
>
> These things beg for helper functions in my opinion.
Something like this?
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 4615 bytes --]
commit ff0b17b20d79b5aecc86fff587d957fe11c638fb
Author: Patrick McHardy <kaber@trash.net>
Date: Mon Apr 20 16:46:48 2009 +0200
net: factor out ethtool invocation of vlan/macvlan drivers
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 214a8cf..329cd50 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -374,36 +374,20 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (lowerdev->ethtool_ops == NULL ||
- lowerdev->ethtool_ops->get_rx_csum == NULL)
- return 0;
- return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
+ return dev_ethtool_get_rx_csum(vlan->lowerdev);
}
static int macvlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
-
- return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
+ return dev_ethtool_get_settings(vlan->lowerdev, cmd);
}
static u32 macvlan_ethtool_get_flags(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_flags)
- return 0;
- return lowerdev->ethtool_ops->get_flags(lowerdev);
+ return dev_ethtool_get_flags(vlan->lowerdev);
}
static const struct ethtool_ops macvlan_ethtool_ops = {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 2e7783f..04679ca 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -42,6 +42,7 @@
#include <linux/dmaengine.h>
#include <linux/workqueue.h>
+#include <linux/ethtool.h>
#include <net/net_namespace.h>
#include <net/dsa.h>
#ifdef CONFIG_DCB
@@ -49,7 +50,6 @@
#endif
struct vlan_group;
-struct ethtool_ops;
struct netpoll_info;
/* 802.11 specific */
struct wireless_dev;
@@ -1908,6 +1908,28 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
}
extern struct pernet_operations __net_initdata loopback_net_ops;
+
+static inline int dev_ethtool_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+ return -EOPNOTSUPP;
+ return dev->ethtool_ops->get_settings(dev, cmd);
+}
+
+static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
+ return 0;
+ return dev->ethtool_ops->get_rx_csum(dev);
+}
+
+static inline u32 dev_ethtool_get_flags(struct net_device *dev)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags)
+ return 0;
+ return dev->ethtool_ops->get_flags(dev);
+}
#endif /* __KERNEL__ */
#endif /* _LINUX_DEV_H */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 6b09213..04dc8c8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -666,13 +666,7 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (!real_dev->ethtool_ops ||
- !real_dev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
-
- return real_dev->ethtool_ops->get_settings(real_dev, cmd);
+ return dev_ethtool_get_settings(vlan->real_dev, cmd);
}
static void vlan_ethtool_get_drvinfo(struct net_device *dev,
@@ -686,24 +680,13 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (real_dev->ethtool_ops == NULL ||
- real_dev->ethtool_ops->get_rx_csum == NULL)
- return 0;
- return real_dev->ethtool_ops->get_rx_csum(real_dev);
+ return dev_ethtool_get_rx_csum(vlan->real_dev);
}
static u32 vlan_ethtool_get_flags(struct net_device *dev)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (!(real_dev->features & NETIF_F_HW_VLAN_RX) ||
- real_dev->ethtool_ops == NULL ||
- real_dev->ethtool_ops->get_flags == NULL)
- return 0;
- return real_dev->ethtool_ops->get_flags(real_dev);
+ return dev_ethtool_get_flags(vlan->real_dev);
}
static const struct ethtool_ops vlan_ethtool_ops = {
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-04-20 14:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-17 16:05 vlan/macvlan: fix NULL pointer dereferences in ethtool handlers Patrick McHardy
2009-04-17 22:59 ` David Miller
2009-04-20 14:49 ` Patrick McHardy
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).