Commit 561d8352 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

bridge: use ndo_siocdevprivate

The bridge driver has an old set of ioctls using the SIOCDEVPRIVATE
namespace that have never worked in compat mode and are explicitly
forbidden already.

Move them over to ndo_siocdevprivate and fix compat mode for these,
because we can.

Cc: Roopa Prabhu <roopa@nvidia.com>
Cc: Nikolay Aleksandrov <nikolay@nvidia.com>
Cc: bridge@lists.linux-foundation.org
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3f3fa534
...@@ -455,6 +455,7 @@ static const struct net_device_ops br_netdev_ops = { ...@@ -455,6 +455,7 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_change_rx_flags = br_dev_change_rx_flags, .ndo_change_rx_flags = br_dev_change_rx_flags,
.ndo_change_mtu = br_change_mtu, .ndo_change_mtu = br_change_mtu,
.ndo_do_ioctl = br_dev_ioctl, .ndo_do_ioctl = br_dev_ioctl,
.ndo_siocdevprivate = br_dev_siocdevprivate,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_netpoll_setup = br_netpoll_setup, .ndo_netpoll_setup = br_netpoll_setup,
.ndo_netpoll_cleanup = br_netpoll_cleanup, .ndo_netpoll_cleanup = br_netpoll_cleanup,
......
...@@ -106,15 +106,32 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) ...@@ -106,15 +106,32 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd)
* This interface is deprecated because it was too difficult * This interface is deprecated because it was too difficult
* to do the translation for 32/64bit ioctl compatibility. * to do the translation for 32/64bit ioctl compatibility.
*/ */
static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd)
{ {
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
struct net_bridge_port *p = NULL; struct net_bridge_port *p = NULL;
unsigned long args[4]; unsigned long args[4];
void __user *argp;
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
if (copy_from_user(args, rq->ifr_data, sizeof(args))) if (in_compat_syscall()) {
return -EFAULT; unsigned int cargs[4];
if (copy_from_user(cargs, data, sizeof(cargs)))
return -EFAULT;
args[0] = cargs[0];
args[1] = cargs[1];
args[2] = cargs[2];
args[3] = cargs[3];
argp = compat_ptr(args[1]);
} else {
if (copy_from_user(args, data, sizeof(args)))
return -EFAULT;
argp = (void __user *)args[1];
}
switch (args[0]) { switch (args[0]) {
case BRCTL_ADD_IF: case BRCTL_ADD_IF:
...@@ -171,7 +188,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -171,7 +188,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return -ENOMEM; return -ENOMEM;
get_port_ifindices(br, indices, num); get_port_ifindices(br, indices, num);
if (copy_to_user((void __user *)args[1], indices, num*sizeof(int))) if (copy_to_user(argp, indices, num * sizeof(int)))
num = -EFAULT; num = -EFAULT;
kfree(indices); kfree(indices);
return num; return num;
...@@ -232,7 +249,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -232,7 +249,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
rcu_read_unlock(); rcu_read_unlock();
if (copy_to_user((void __user *)args[1], &p, sizeof(p))) if (copy_to_user(argp, &p, sizeof(p)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -282,8 +299,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -282,8 +299,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
} }
case BRCTL_GET_FDB_ENTRIES: case BRCTL_GET_FDB_ENTRIES:
return get_fdb_entries(br, (void __user *)args[1], return get_fdb_entries(br, argp, args[2], args[3]);
args[2], args[3]);
} }
if (!ret) { if (!ret) {
...@@ -320,7 +336,7 @@ static int old_deviceless(struct net *net, void __user *uarg) ...@@ -320,7 +336,7 @@ static int old_deviceless(struct net *net, void __user *uarg)
args[2] = get_bridge_ifindices(net, indices, args[2]); args[2] = get_bridge_ifindices(net, indices, args[2]);
ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) ret = copy_to_user(uarg, indices, args[2]*sizeof(int))
? -EFAULT : args[2]; ? -EFAULT : args[2];
kfree(indices); kfree(indices);
...@@ -335,7 +351,7 @@ static int old_deviceless(struct net *net, void __user *uarg) ...@@ -335,7 +351,7 @@ static int old_deviceless(struct net *net, void __user *uarg)
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM; return -EPERM;
if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ)) if (copy_from_user(buf, uarg, IFNAMSIZ))
return -EFAULT; return -EFAULT;
buf[IFNAMSIZ-1] = 0; buf[IFNAMSIZ-1] = 0;
...@@ -383,9 +399,6 @@ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -383,9 +399,6 @@ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
switch (cmd) { switch (cmd) {
case SIOCDEVPRIVATE:
return old_dev_ioctl(dev, rq, cmd);
case SIOCBRADDIF: case SIOCBRADDIF:
case SIOCBRDELIF: case SIOCBRDELIF:
return add_del_if(br, rq->ifr_ifindex, cmd == SIOCBRADDIF); return add_del_if(br, rq->ifr_ifindex, cmd == SIOCBRADDIF);
......
...@@ -852,6 +852,8 @@ br_port_get_check_rtnl(const struct net_device *dev) ...@@ -852,6 +852,8 @@ br_port_get_check_rtnl(const struct net_device *dev)
/* br_ioctl.c */ /* br_ioctl.c */
int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
void __user *data, int cmd);
int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd,
void __user *arg); void __user *arg);
......
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