Commit 029a4fef authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

tulip: use ndo_siocdevprivate

The tulip driver has a debugging method over ioctl built-in, but it
does not actually check the command type, which may end up leading
to random behavior when trying to run other ioctls on it.

Change the driver to use ndo_siocdevprivate and limit the execution
further to the first private command code. If anyone still has tools
to run these debugging commands, they might have to be patched for
it if they pass different ioctl command.

The function has existed in this form since the driver was merged in
Linux-1.1.86.

Cc: linux-parisc@vger.kernel.org
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4747c1a8
...@@ -443,6 +443,7 @@ ...@@ -443,6 +443,7 @@
========================================================================= =========================================================================
*/ */
#include <linux/compat.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -902,7 +903,8 @@ static int de4x5_close(struct net_device *dev); ...@@ -902,7 +903,8 @@ static int de4x5_close(struct net_device *dev);
static struct net_device_stats *de4x5_get_stats(struct net_device *dev); static struct net_device_stats *de4x5_get_stats(struct net_device *dev);
static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len); static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len);
static void set_multicast_list(struct net_device *dev); static void set_multicast_list(struct net_device *dev);
static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int de4x5_siocdevprivate(struct net_device *dev, struct ifreq *rq,
void __user *data, int cmd);
/* /*
** Private functions ** Private functions
...@@ -1084,7 +1086,7 @@ static const struct net_device_ops de4x5_netdev_ops = { ...@@ -1084,7 +1086,7 @@ static const struct net_device_ops de4x5_netdev_ops = {
.ndo_start_xmit = de4x5_queue_pkt, .ndo_start_xmit = de4x5_queue_pkt,
.ndo_get_stats = de4x5_get_stats, .ndo_get_stats = de4x5_get_stats,
.ndo_set_rx_mode = set_multicast_list, .ndo_set_rx_mode = set_multicast_list,
.ndo_do_ioctl = de4x5_ioctl, .ndo_siocdevprivate = de4x5_siocdevprivate,
.ndo_set_mac_address= eth_mac_addr, .ndo_set_mac_address= eth_mac_addr,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
...@@ -5357,7 +5359,7 @@ de4x5_dbg_rx(struct sk_buff *skb, int len) ...@@ -5357,7 +5359,7 @@ de4x5_dbg_rx(struct sk_buff *skb, int len)
** this function is only used for my testing. ** this function is only used for my testing.
*/ */
static int static int
de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) de4x5_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd)
{ {
struct de4x5_private *lp = netdev_priv(dev); struct de4x5_private *lp = netdev_priv(dev);
struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_ifru; struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_ifru;
...@@ -5371,6 +5373,9 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -5371,6 +5373,9 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
} tmp; } tmp;
u_long flags = 0; u_long flags = 0;
if (cmd != SIOCDEVPRIVATE || in_compat_syscall())
return -EOPNOTSUPP;
switch(ioc->cmd) { switch(ioc->cmd) {
case DE4X5_GET_HWADDR: /* Get the hardware address */ case DE4X5_GET_HWADDR: /* Get the hardware address */
ioc->len = ETH_ALEN; ioc->len = ETH_ALEN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment