* [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-22 16:40 ` Christoph Hellwig
2018-01-18 19:37 ` [PATCH 03/10] ip_rt_ioctl(): take copyin " Al Viro
` (8 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/inetdevice.h | 2 +-
net/ipv4/af_inet.c | 21 ++++++++++++++++-----
net/ipv4/devinet.c | 41 +++++++++++++++--------------------------
net/ipv4/ipconfig.c | 17 +++--------------
4 files changed, 35 insertions(+), 46 deletions(-)
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 1ac5bf95bfdd..e16fe7d44a71 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -173,7 +173,7 @@ static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
}
int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
-int devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
+int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *);
void devinet_init(void);
struct in_device *inetdev_by_index(struct net *, int);
__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 54cccdd8b1e3..1c2bfee2e249 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -872,6 +872,8 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct sock *sk = sock->sk;
int err = 0;
struct net *net = sock_net(sk);
+ void __user *p = (void __user *)arg;
+ struct ifreq ifr;
switch (cmd) {
case SIOCGSTAMP:
@@ -891,17 +893,26 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
err = arp_ioctl(net, cmd, (void __user *)arg);
break;
case SIOCGIFADDR:
- case SIOCSIFADDR:
case SIOCGIFBRDADDR:
- case SIOCSIFBRDADDR:
case SIOCGIFNETMASK:
- case SIOCSIFNETMASK:
case SIOCGIFDSTADDR:
+ case SIOCGIFPFLAGS:
+ if (copy_from_user(&ifr, p, sizeof(struct ifreq)))
+ return -EFAULT;
+ err = devinet_ioctl(net, cmd, &ifr);
+ if (!err && copy_to_user(p, &ifr, sizeof(struct ifreq)))
+ err = -EFAULT;
+ break;
+
+ case SIOCSIFADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCSIFNETMASK:
case SIOCSIFDSTADDR:
case SIOCSIFPFLAGS:
- case SIOCGIFPFLAGS:
case SIOCSIFFLAGS:
- err = devinet_ioctl(net, cmd, (void __user *)arg);
+ if (copy_from_user(&ifr, p, sizeof(struct ifreq)))
+ return -EFAULT;
+ err = devinet_ioctl(net, cmd, &ifr);
break;
default:
if (sk->sk_prot->ioctl)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 1771549d2438..e056c0067f2c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -946,11 +946,10 @@ static int inet_abc_len(__be32 addr)
}
-int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
{
- struct ifreq ifr;
struct sockaddr_in sin_orig;
- struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;
struct in_device *in_dev;
struct in_ifaddr **ifap = NULL;
struct in_ifaddr *ifa = NULL;
@@ -959,22 +958,16 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
int ret = -EFAULT;
int tryaddrmatch = 0;
- /*
- * Fetch the caller's info block into kernel space
- */
-
- if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
- goto out;
- ifr.ifr_name[IFNAMSIZ - 1] = 0;
+ ifr->ifr_name[IFNAMSIZ - 1] = 0;
/* save original address for comparison */
memcpy(&sin_orig, sin, sizeof(*sin));
- colon = strchr(ifr.ifr_name, ':');
+ colon = strchr(ifr->ifr_name, ':');
if (colon)
*colon = 0;
- dev_load(net, ifr.ifr_name);
+ dev_load(net, ifr->ifr_name);
switch (cmd) {
case SIOCGIFADDR: /* Get interface address */
@@ -1014,7 +1007,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
rtnl_lock();
ret = -ENODEV;
- dev = __dev_get_by_name(net, ifr.ifr_name);
+ dev = __dev_get_by_name(net, ifr->ifr_name);
if (!dev)
goto done;
@@ -1031,7 +1024,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
This is checked above. */
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
ifap = &ifa->ifa_next) {
- if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
+ if (!strcmp(ifr->ifr_name, ifa->ifa_label) &&
sin_orig.sin_addr.s_addr ==
ifa->ifa_local) {
break; /* found */
@@ -1044,7 +1037,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!ifa) {
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
ifap = &ifa->ifa_next)
- if (!strcmp(ifr.ifr_name, ifa->ifa_label))
+ if (!strcmp(ifr->ifr_name, ifa->ifa_label))
break;
}
}
@@ -1056,19 +1049,19 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
switch (cmd) {
case SIOCGIFADDR: /* Get interface address */
sin->sin_addr.s_addr = ifa->ifa_local;
- goto rarok;
+ break;
case SIOCGIFBRDADDR: /* Get the broadcast address */
sin->sin_addr.s_addr = ifa->ifa_broadcast;
- goto rarok;
+ break;
case SIOCGIFDSTADDR: /* Get the destination address */
sin->sin_addr.s_addr = ifa->ifa_address;
- goto rarok;
+ break;
case SIOCGIFNETMASK: /* Get the netmask for the interface */
sin->sin_addr.s_addr = ifa->ifa_mask;
- goto rarok;
+ break;
case SIOCSIFFLAGS:
if (colon) {
@@ -1076,11 +1069,11 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!ifa)
break;
ret = 0;
- if (!(ifr.ifr_flags & IFF_UP))
+ if (!(ifr->ifr_flags & IFF_UP))
inet_del_ifa(in_dev, ifap, 1);
break;
}
- ret = dev_change_flags(dev, ifr.ifr_flags);
+ ret = dev_change_flags(dev, ifr->ifr_flags);
break;
case SIOCSIFADDR: /* Set interface address (and family) */
@@ -1095,7 +1088,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
break;
INIT_HLIST_NODE(&ifa->hash);
if (colon)
- memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
+ memcpy(ifa->ifa_label, ifr->ifr_name, IFNAMSIZ);
else
memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
} else {
@@ -1182,10 +1175,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
rtnl_unlock();
out:
return ret;
-rarok:
- rtnl_unlock();
- ret = copy_to_user(arg, &ifr, sizeof(struct ifreq)) ? -EFAULT : 0;
- goto out;
}
static int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index e9e488e72900..6895fff609b1 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -329,17 +329,6 @@ set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
sin->sin_port = port;
}
-static int __init ic_devinet_ioctl(unsigned int cmd, struct ifreq *arg)
-{
- int res;
-
- mm_segment_t oldfs = get_fs();
- set_fs(get_ds());
- res = devinet_ioctl(&init_net, cmd, (struct ifreq __user *) arg);
- set_fs(oldfs);
- return res;
-}
-
static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
{
int res;
@@ -375,19 +364,19 @@ static int __init ic_setup_if(void)
memset(&ir, 0, sizeof(ir));
strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->dev->name);
set_sockaddr(sin, ic_myaddr, 0);
- if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
+ if ((err = devinet_ioctl(&init_net, SIOCSIFADDR, &ir)) < 0) {
pr_err("IP-Config: Unable to set interface address (%d)\n",
err);
return -1;
}
set_sockaddr(sin, ic_netmask, 0);
- if ((err = ic_devinet_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
+ if ((err = devinet_ioctl(&init_net, SIOCSIFNETMASK, &ir)) < 0) {
pr_err("IP-Config: Unable to set interface netmask (%d)\n",
err);
return -1;
}
set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
- if ((err = ic_devinet_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
+ if ((err = devinet_ioctl(&init_net, SIOCSIFBRDADDR, &ir)) < 0) {
pr_err("IP-Config: Unable to set interface broadcast address (%d)\n",
err);
return -1;
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 03/10] ip_rt_ioctl(): take copyin to caller
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
2018-01-18 19:37 ` [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-22 16:43 ` Christoph Hellwig
2018-01-18 19:37 ` [PATCH 04/10] kill dev_ifsioc() Al Viro
` (7 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/net/route.h | 2 +-
net/ipv4/af_inet.c | 7 ++++++-
net/ipv4/fib_frontend.c | 8 ++------
net/ipv4/ipconfig.c | 13 +------------
4 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index d538e6db1afe..1eb9ce470e25 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -217,7 +217,7 @@ unsigned int inet_addr_type_dev_table(struct net *net,
const struct net_device *dev,
__be32 addr);
void ip_rt_multicast_event(struct in_device *);
-int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
+int ip_rt_ioctl(struct net *, unsigned int cmd, struct rtentry *rt);
void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
struct rtable *rt_dst_alloc(struct net_device *dev,
unsigned int flags, u16 type,
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 1c2bfee2e249..c24008daa3d8 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -874,6 +874,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct net *net = sock_net(sk);
void __user *p = (void __user *)arg;
struct ifreq ifr;
+ struct rtentry rt;
switch (cmd) {
case SIOCGSTAMP:
@@ -884,8 +885,12 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
case SIOCADDRT:
case SIOCDELRT:
+ if (copy_from_user(&rt, p, sizeof(struct rtentry)))
+ return -EFAULT;
+ err = ip_rt_ioctl(net, cmd, &rt);
+ break;
case SIOCRTMSG:
- err = ip_rt_ioctl(net, cmd, (void __user *)arg);
+ err = -EINVAL;
break;
case SIOCDARP:
case SIOCGARP:
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 08259d078b1c..f05afaf3235c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -587,10 +587,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
* Handle IP routing ioctl calls.
* These are used to manipulate the routing tables
*/
-int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+int ip_rt_ioctl(struct net *net, unsigned int cmd, struct rtentry *rt)
{
struct fib_config cfg;
- struct rtentry rt;
int err;
switch (cmd) {
@@ -599,11 +598,8 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(&rt, arg, sizeof(rt)))
- return -EFAULT;
-
rtnl_lock();
- err = rtentry_to_fib_config(net, cmd, &rt, &cfg);
+ err = rtentry_to_fib_config(net, cmd, rt, &cfg);
if (err == 0) {
struct fib_table *tb;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 6895fff609b1..5f396afaa08d 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -340,17 +340,6 @@ static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
return res;
}
-static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
-{
- int res;
-
- mm_segment_t oldfs = get_fs();
- set_fs(get_ds());
- res = ip_rt_ioctl(&init_net, cmd, (void __user *) arg);
- set_fs(oldfs);
- return res;
-}
-
/*
* Set up interface addresses and routes.
*/
@@ -412,7 +401,7 @@ static int __init ic_setup_routes(void)
set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
rm.rt_flags = RTF_UP | RTF_GATEWAY;
- if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
+ if ((err = ip_rt_ioctl(&init_net, SIOCADDRT, &rm)) < 0) {
pr_err("IP-Config: Cannot add default route (%d)\n",
err);
return -1;
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 03/10] ip_rt_ioctl(): take copyin to caller
2018-01-18 19:37 ` [PATCH 03/10] ip_rt_ioctl(): take copyin " Al Viro
@ 2018-01-22 16:43 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-22 16:43 UTC (permalink / raw)
To: Al Viro
Cc: netdev, David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig
> case SIOCGSTAMP:
> @@ -884,8 +885,12 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> break;
> case SIOCADDRT:
> case SIOCDELRT:
> + if (copy_from_user(&rt, p, sizeof(struct rtentry)))
> + return -EFAULT;
> + err = ip_rt_ioctl(net, cmd, &rt);
> + break;
> case SIOCRTMSG:
> - err = ip_rt_ioctl(net, cmd, (void __user *)arg);
> + err = -EINVAL;
This looks odd, but ip_rt_ioctl never handled SIOCRTMSG to start with,
so it looks fine. Might be worth splitting into another prep patch
with a good changelog.
ip_rt_ioctl could also use some additional simplification if it's only
called for SIOCADDRT/SIOCDELRT and lose a level of indentation while
we're at it.
But otherwise this looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 04/10] kill dev_ifsioc()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
2018-01-18 19:37 ` [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller Al Viro
2018-01-18 19:37 ` [PATCH 03/10] ip_rt_ioctl(): take copyin " Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-22 16:47 ` Christoph Hellwig
2018-01-18 19:37 ` [PATCH 05/10] kill bond_ioctl() Al Viro
` (6 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
it's been equivalent to sock_do_ioctl() since 2009...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/socket.c | 38 --------------------------------------
1 file changed, 38 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index 112216c537e7..f280258bd6a4 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2915,42 +2915,6 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
return dev_ioctl(net, cmd, u_ifreq64);
}
-static int dev_ifsioc(struct net *net, struct socket *sock,
- unsigned int cmd, struct compat_ifreq __user *uifr32)
-{
- struct ifreq __user *uifr;
- int err;
-
- uifr = compat_alloc_user_space(sizeof(*uifr));
- if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
- return -EFAULT;
-
- err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
-
- if (!err) {
- switch (cmd) {
- case SIOCGIFFLAGS:
- case SIOCGIFMETRIC:
- case SIOCGIFMTU:
- case SIOCGIFMEM:
- case SIOCGIFHWADDR:
- case SIOCGIFINDEX:
- case SIOCGIFADDR:
- case SIOCGIFBRDADDR:
- case SIOCGIFDSTADDR:
- case SIOCGIFNETMASK:
- case SIOCGIFPFLAGS:
- case SIOCGIFTXQLEN:
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
- err = -EFAULT;
- break;
- }
- }
- return err;
-}
-
static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
struct compat_ifreq __user *uifr32)
{
@@ -3181,8 +3145,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCGMIIPHY:
case SIOCGMIIREG:
case SIOCSMIIREG:
- return dev_ifsioc(net, sock, cmd, argp);
-
case SIOCSARP:
case SIOCGARP:
case SIOCDARP:
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 04/10] kill dev_ifsioc()
2018-01-18 19:37 ` [PATCH 04/10] kill dev_ifsioc() Al Viro
@ 2018-01-22 16:47 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-22 16:47 UTC (permalink / raw)
To: Al Viro
Cc: netdev, David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig
On Thu, Jan 18, 2018 at 07:37:49PM +0000, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
>
> it's been equivalent to sock_do_ioctl() since 2009...
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Note that we have two different dev_ifsioc() defintions, which
is a little weird.
But the net/socket.c one does indeed seem superflous as there is no
point in doing the compat_alloc_user_space / copy_in_user as far
as I can tell. compat_ifreq differs from ifreq in the size of
ifru_data, but it seems none of these ioctls actually use it.
A better changelog would be nice, though.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 05/10] kill bond_ioctl()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (2 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 04/10] kill dev_ifsioc() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-22 16:48 ` Christoph Hellwig
2018-01-18 19:37 ` [PATCH 06/10] kill dev_ifname32() Al Viro
` (5 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
another sock_do_ioctl() equivalent
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/socket.c | 36 ++++--------------------------------
1 file changed, 4 insertions(+), 32 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index f280258bd6a4..b267d051b50d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2861,33 +2861,6 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32
return dev_ioctl(net, SIOCWANDEV, uifr);
}
-static int bond_ioctl(struct net *net, unsigned int cmd,
- struct compat_ifreq __user *ifr32)
-{
- struct ifreq kifr;
- mm_segment_t old_fs;
- int err;
-
- switch (cmd) {
- case SIOCBONDENSLAVE:
- case SIOCBONDRELEASE:
- case SIOCBONDSETHWADDR:
- case SIOCBONDCHANGEACTIVE:
- if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = dev_ioctl(net, cmd,
- (struct ifreq __user __force *) &kifr);
- set_fs(old_fs);
-
- return err;
- default:
- return -ENOIOCTLCMD;
- }
-}
-
/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
struct compat_ifreq __user *u_ifreq32)
@@ -3081,11 +3054,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCGIFMAP:
case SIOCSIFMAP:
return compat_sioc_ifmap(net, cmd, argp);
- case SIOCBONDENSLAVE:
- case SIOCBONDRELEASE:
- case SIOCBONDSETHWADDR:
- case SIOCBONDCHANGEACTIVE:
- return bond_ioctl(net, cmd, argp);
case SIOCADDRT:
case SIOCDELRT:
return routing_ioctl(net, sock, cmd, argp);
@@ -3149,6 +3117,10 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCGARP:
case SIOCDARP:
case SIOCATMARK:
+ case SIOCBONDENSLAVE:
+ case SIOCBONDRELEASE:
+ case SIOCBONDSETHWADDR:
+ case SIOCBONDCHANGEACTIVE:
return sock_do_ioctl(net, sock, cmd, arg);
}
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 06/10] kill dev_ifname32()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (3 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 05/10] kill bond_ioctl() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-18 19:37 ` [PATCH 07/10] lift handling of SIOCIW... out of dev_ioctl() Al Viro
` (4 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
same story...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/socket.c | 22 +---------------------
1 file changed, 1 insertion(+), 21 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index b267d051b50d..6d29ebce93dd 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2675,25 +2675,6 @@ static int do_siocgstampns(struct net *net, struct socket *sock,
return err;
}
-static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
-{
- struct ifreq __user *uifr;
- int err;
-
- uifr = compat_alloc_user_space(sizeof(struct ifreq));
- if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
- return -EFAULT;
-
- err = dev_ioctl(net, SIOCGIFNAME, uifr);
- if (err)
- return err;
-
- if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
- return -EFAULT;
-
- return 0;
-}
-
static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
{
struct compat_ifconf ifc32;
@@ -3043,8 +3024,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCSIFBR:
case SIOCGIFBR:
return old_bridge_ioctl(argp);
- case SIOCGIFNAME:
- return dev_ifname32(net, argp);
case SIOCGIFCONF:
return compat_dev_ifconf(net, argp);
case SIOCETHTOOL:
@@ -3121,6 +3100,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCBONDRELEASE:
case SIOCBONDSETHWADDR:
case SIOCBONDCHANGEACTIVE:
+ case SIOCGIFNAME:
return sock_do_ioctl(net, sock, cmd, arg);
}
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 07/10] lift handling of SIOCIW... out of dev_ioctl()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (4 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 06/10] kill dev_ifname32() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-18 19:37 ` [PATCH 08/10] ipconfig: use dev_set_mtu() Al Viro
` (3 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/net/wext.h | 4 ++--
net/core/dev_ioctl.c | 18 ------------------
net/socket.c | 2 +-
net/wireless/wext-core.c | 13 +++++++++----
4 files changed, 12 insertions(+), 25 deletions(-)
diff --git a/include/net/wext.h b/include/net/wext.h
index e51f067fdb3a..aa192a670304 100644
--- a/include/net/wext.h
+++ b/include/net/wext.h
@@ -7,7 +7,7 @@
struct net;
#ifdef CONFIG_WEXT_CORE
-int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
+int wext_handle_ioctl(struct net *net, unsigned int cmd,
void __user *arg);
int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
unsigned long arg);
@@ -15,7 +15,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
struct iw_statistics *get_wireless_stats(struct net_device *dev);
int call_commit_handler(struct net_device *dev);
#else
-static inline int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
+static inline int wext_handle_ioctl(struct net *net, unsigned int cmd,
void __user *arg)
{
return -EINVAL;
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 5cdec23dd28e..d262f159f9fd 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -411,24 +411,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (cmd == SIOCGIFNAME)
return dev_ifname(net, (struct ifreq __user *)arg);
- /*
- * Take care of Wireless Extensions. Unfortunately struct iwreq
- * isn't a proper subset of struct ifreq (it's 8 byte shorter)
- * so we need to treat it specially, otherwise applications may
- * fault if the struct they're passing happens to land at the
- * end of a mapped page.
- */
- if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
- struct iwreq iwr;
-
- if (copy_from_user(&iwr, arg, sizeof(iwr)))
- return -EFAULT;
-
- iwr.ifr_name[sizeof(iwr.ifr_name) - 1] = 0;
-
- return wext_handle_ioctl(net, &iwr, cmd, arg);
- }
-
if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
return -EFAULT;
diff --git a/net/socket.c b/net/socket.c
index 6d29ebce93dd..d0e24f6ec1a9 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1005,7 +1005,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
} else
#ifdef CONFIG_WEXT_CORE
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
- err = dev_ioctl(net, cmd, argp);
+ err = wext_handle_ioctl(net, cmd, argp);
} else
#endif
switch (cmd) {
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 6cdb054484d6..9efbfc753347 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -1035,18 +1035,23 @@ static int ioctl_standard_call(struct net_device * dev,
}
-int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
- void __user *arg)
+int wext_handle_ioctl(struct net *net, unsigned int cmd, void __user *arg)
{
struct iw_request_info info = { .cmd = cmd, .flags = 0 };
+ struct iwreq iwr;
int ret;
- ret = wext_ioctl_dispatch(net, iwr, cmd, &info,
+ if (copy_from_user(&iwr, arg, sizeof(iwr)))
+ return -EFAULT;
+
+ iwr.ifr_name[sizeof(iwr.ifr_name) - 1] = 0;
+
+ ret = wext_ioctl_dispatch(net, &iwr, cmd, &info,
ioctl_standard_call,
ioctl_private_call);
if (ret >= 0 &&
IW_IS_GET(cmd) &&
- copy_to_user(arg, iwr, sizeof(struct iwreq)))
+ copy_to_user(arg, &iwr, sizeof(struct iwreq)))
return -EFAULT;
return ret;
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 08/10] ipconfig: use dev_set_mtu()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (5 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 07/10] lift handling of SIOCIW... out of dev_ioctl() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-18 19:37 ` [PATCH 09/10] dev_ioctl(): move copyin/copyout to callers Al Viro
` (2 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/ipv4/ipconfig.c | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 5f396afaa08d..f75802ad960f 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -329,17 +329,6 @@ set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
sin->sin_port = port;
}
-static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
-{
- int res;
-
- mm_segment_t oldfs = get_fs();
- set_fs(get_ds());
- res = dev_ioctl(&init_net, cmd, (struct ifreq __user *) arg);
- set_fs(oldfs);
- return res;
-}
-
/*
* Set up interface addresses and routes.
*/
@@ -375,11 +364,11 @@ static int __init ic_setup_if(void)
* out, we'll try to muddle along.
*/
if (ic_dev_mtu != 0) {
- strcpy(ir.ifr_name, ic_dev->dev->name);
- ir.ifr_mtu = ic_dev_mtu;
- if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
+ rtnl_lock();
+ if ((err = dev_set_mtu(ic_dev->dev, ic_dev_mtu)) < 0)
pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n",
ic_dev_mtu, err);
+ rtnl_unlock();
}
return 0;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 09/10] dev_ioctl(): move copyin/copyout to callers
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (6 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 08/10] ipconfig: use dev_set_mtu() Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-18 19:37 ` [PATCH 10/10] kill kernel_sock_ioctl() Al Viro
2018-01-22 16:40 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Christoph Hellwig
9 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/netdevice.h | 3 +-
net/core/dev_ioctl.c | 85 +++++++++++++------------------------------
net/socket.c | 91 +++++++++++++++++++++++------------------------
3 files changed, 71 insertions(+), 108 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 221487f5b214..3b4f603bc360 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3313,7 +3313,8 @@ int netdev_rx_handler_register(struct net_device *dev,
void netdev_rx_handler_unregister(struct net_device *dev);
bool dev_valid_name(const char *name);
-int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
+int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
+ bool *need_copyout);
int dev_ifconf(struct net *net, struct ifconf *, int);
int dev_ethtool(struct net *net, struct ifreq *);
unsigned int dev_get_flags(const struct net_device *);
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index d262f159f9fd..0ab1af04296c 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -18,26 +18,10 @@
* match. --pb
*/
-static int dev_ifname(struct net *net, struct ifreq __user *arg)
+static int dev_ifname(struct net *net, struct ifreq *ifr)
{
- struct ifreq ifr;
- int error;
-
- /*
- * Fetch the caller's info block.
- */
-
- if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
- return -EFAULT;
- ifr.ifr_name[IFNAMSIZ-1] = 0;
-
- error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex);
- if (error)
- return error;
-
- if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
- return -EFAULT;
- return 0;
+ ifr->ifr_name[IFNAMSIZ-1] = 0;
+ return netdev_get_name(net, ifr->ifr_name, ifr->ifr_ifindex);
}
static gifconf_func_t *gifconf_list[NPROTO];
@@ -402,24 +386,24 @@ EXPORT_SYMBOL(dev_load);
* positive or a negative errno code on error.
*/
-int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_copyout)
{
- struct ifreq ifr;
int ret;
char *colon;
+ if (need_copyout)
+ *need_copyout = true;
if (cmd == SIOCGIFNAME)
- return dev_ifname(net, (struct ifreq __user *)arg);
-
- if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
- return -EFAULT;
+ return dev_ifname(net, ifr);
- ifr.ifr_name[IFNAMSIZ-1] = 0;
+ ifr->ifr_name[IFNAMSIZ-1] = 0;
- colon = strchr(ifr.ifr_name, ':');
+ colon = strchr(ifr->ifr_name, ':');
if (colon)
*colon = 0;
+ dev_load(net, ifr->ifr_name);
+
/*
* See which interface the caller is talking about.
*/
@@ -439,31 +423,19 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case SIOCGIFMAP:
case SIOCGIFINDEX:
case SIOCGIFTXQLEN:
- dev_load(net, ifr.ifr_name);
rcu_read_lock();
- ret = dev_ifsioc_locked(net, &ifr, cmd);
+ ret = dev_ifsioc_locked(net, ifr, cmd);
rcu_read_unlock();
- if (!ret) {
- if (colon)
- *colon = ':';
- if (copy_to_user(arg, &ifr,
- sizeof(struct ifreq)))
- ret = -EFAULT;
- }
+ if (colon)
+ *colon = ':';
return ret;
case SIOCETHTOOL:
- dev_load(net, ifr.ifr_name);
rtnl_lock();
- ret = dev_ethtool(net, &ifr);
+ ret = dev_ethtool(net, ifr);
rtnl_unlock();
- if (!ret) {
- if (colon)
- *colon = ':';
- if (copy_to_user(arg, &ifr,
- sizeof(struct ifreq)))
- ret = -EFAULT;
- }
+ if (colon)
+ *colon = ':';
return ret;
/*
@@ -477,17 +449,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case SIOCSIFNAME:
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
- dev_load(net, ifr.ifr_name);
rtnl_lock();
- ret = dev_ifsioc(net, &ifr, cmd);
+ ret = dev_ifsioc(net, ifr, cmd);
rtnl_unlock();
- if (!ret) {
- if (colon)
- *colon = ':';
- if (copy_to_user(arg, &ifr,
- sizeof(struct ifreq)))
- ret = -EFAULT;
- }
+ if (colon)
+ *colon = ':';
return ret;
/*
@@ -528,10 +494,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
/* fall through */
case SIOCBONDSLAVEINFOQUERY:
case SIOCBONDINFOQUERY:
- dev_load(net, ifr.ifr_name);
rtnl_lock();
- ret = dev_ifsioc(net, &ifr, cmd);
+ ret = dev_ifsioc(net, ifr, cmd);
rtnl_unlock();
+ if (need_copyout)
+ *need_copyout = false;
return ret;
case SIOCGIFMEM:
@@ -551,13 +518,9 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
cmd == SIOCGHWTSTAMP ||
(cmd >= SIOCDEVPRIVATE &&
cmd <= SIOCDEVPRIVATE + 15)) {
- dev_load(net, ifr.ifr_name);
rtnl_lock();
- ret = dev_ifsioc(net, &ifr, cmd);
+ ret = dev_ifsioc(net, ifr, cmd);
rtnl_unlock();
- if (!ret && copy_to_user(arg, &ifr,
- sizeof(struct ifreq)))
- ret = -EFAULT;
return ret;
}
return -ENOTTY;
diff --git a/net/socket.c b/net/socket.c
index d0e24f6ec1a9..982e9585fa31 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -973,10 +973,17 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
rtnl_unlock();
if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
err = -EFAULT;
- return err;
+ } else {
+ struct ifreq ifr;
+ bool need_copyout;
+ if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
+ return -EFAULT;
+ err = dev_ioctl(net, cmd, &ifr, &need_copyout);
+ if (!err && need_copyout)
+ if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
+ return -EFAULT;
}
-
- return dev_ioctl(net, cmd, argp);
+ return err;
}
/*
@@ -1000,8 +1007,15 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
sock = file->private_data;
sk = sock->sk;
net = sock_net(sk);
- if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
- err = dev_ioctl(net, cmd, argp);
+ if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
+ struct ifreq ifr;
+ bool need_copyout;
+ if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
+ return -EFAULT;
+ err = dev_ioctl(net, cmd, &ifr, &need_copyout);
+ if (!err && need_copyout)
+ if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
+ return -EFAULT;
} else
#ifdef CONFIG_WEXT_CORE
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
@@ -2704,9 +2718,9 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
{
struct compat_ethtool_rxnfc __user *compat_rxnfc;
bool convert_in = false, convert_out = false;
- size_t buf_size = ALIGN(sizeof(struct ifreq), 8);
- struct ethtool_rxnfc __user *rxnfc;
- struct ifreq __user *ifr;
+ size_t buf_size = 0;
+ struct ethtool_rxnfc __user *rxnfc = NULL;
+ struct ifreq ifr;
u32 rule_cnt = 0, actual_rule_cnt;
u32 ethcmd;
u32 data;
@@ -2743,18 +2757,14 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
case ETHTOOL_SRXCLSRLDEL:
buf_size += sizeof(struct ethtool_rxnfc);
convert_in = true;
+ rxnfc = compat_alloc_user_space(buf_size);
break;
}
- ifr = compat_alloc_user_space(buf_size);
- rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
-
- if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
+ if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
return -EFAULT;
- if (put_user(convert_in ? rxnfc : compat_ptr(data),
- &ifr->ifr_ifru.ifru_data))
- return -EFAULT;
+ ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
if (convert_in) {
/* We expect there to be holes between fs.m_ext and
@@ -2782,7 +2792,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
return -EFAULT;
}
- ret = dev_ioctl(net, SIOCETHTOOL, ifr);
+ ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
if (ret)
return ret;
@@ -2823,50 +2833,43 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
{
- void __user *uptr;
compat_uptr_t uptr32;
- struct ifreq __user *uifr;
+ struct ifreq ifr;
+ void __user *saved;
+ int err;
- uifr = compat_alloc_user_space(sizeof(*uifr));
- if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
+ if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
return -EFAULT;
if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
return -EFAULT;
- uptr = compat_ptr(uptr32);
-
- if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
- return -EFAULT;
+ saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
+ ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
- return dev_ioctl(net, SIOCWANDEV, uifr);
+ err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
+ if (!err) {
+ ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
+ if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
+ err = -EFAULT;
+ }
+ return err;
}
/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
struct compat_ifreq __user *u_ifreq32)
{
- struct ifreq __user *u_ifreq64;
- char tmp_buf[IFNAMSIZ];
- void __user *data64;
+ struct ifreq ifreq;
u32 data32;
- if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
- IFNAMSIZ))
+ if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
return -EFAULT;
- if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
+ if (get_user(data32, &u_ifreq32->ifr_data))
return -EFAULT;
- data64 = compat_ptr(data32);
+ ifreq.ifr_data = compat_ptr(data32);
- u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
-
- if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
- IFNAMSIZ))
- return -EFAULT;
- if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
- return -EFAULT;
-
- return dev_ioctl(net, cmd, u_ifreq64);
+ return dev_ioctl(net, cmd, &ifreq, NULL);
}
static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
@@ -2874,7 +2877,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
{
struct ifreq ifr;
struct compat_ifmap __user *uifmap32;
- mm_segment_t old_fs;
int err;
uifmap32 = &uifr32->ifr_ifru.ifru_map;
@@ -2888,10 +2890,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
if (err)
return -EFAULT;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = dev_ioctl(net, cmd, (void __user __force *)&ifr);
- set_fs(old_fs);
+ err = dev_ioctl(net, cmd, &ifr, NULL);
if (cmd == SIOCGIFMAP && !err) {
err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (7 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 09/10] dev_ioctl(): move copyin/copyout to callers Al Viro
@ 2018-01-18 19:37 ` Al Viro
2018-01-22 16:49 ` Christoph Hellwig
2018-01-24 20:52 ` David Miller
2018-01-22 16:40 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Christoph Hellwig
9 siblings, 2 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:37 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig,
Al Viro
From: Al Viro <viro@zeniv.linux.org.uk>
no users since 2014
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/net.h | 1 -
net/socket.c | 13 -------------
2 files changed, 14 deletions(-)
diff --git a/include/linux/net.h b/include/linux/net.h
index caeb159abda5..68acc54976bf 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -306,7 +306,6 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags);
int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
size_t size, int flags);
-int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how);
/* Routine returns the IP overhead imposed by a (caller-protected) socket. */
diff --git a/net/socket.c b/net/socket.c
index 982e9585fa31..3184573f58df 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -3254,19 +3254,6 @@ int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
}
EXPORT_SYMBOL(kernel_sendpage_locked);
-int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
-{
- mm_segment_t oldfs = get_fs();
- int err;
-
- set_fs(KERNEL_DS);
- err = sock->ops->ioctl(sock, cmd, arg);
- set_fs(oldfs);
-
- return err;
-}
-EXPORT_SYMBOL(kernel_sock_ioctl);
-
int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
{
return sock->ops->shutdown(sock, how);
--
2.11.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-18 19:37 ` [PATCH 10/10] kill kernel_sock_ioctl() Al Viro
@ 2018-01-22 16:49 ` Christoph Hellwig
2018-01-24 20:52 ` David Miller
1 sibling, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-22 16:49 UTC (permalink / raw)
To: Al Viro
Cc: netdev, David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig
Looks fine,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-18 19:37 ` [PATCH 10/10] kill kernel_sock_ioctl() Al Viro
2018-01-22 16:49 ` Christoph Hellwig
@ 2018-01-24 20:52 ` David Miller
2018-01-25 0:01 ` Al Viro
1 sibling, 1 reply; 28+ messages in thread
From: David Miller @ 2018-01-24 20:52 UTC (permalink / raw)
To: viro; +Cc: netdev, torvalds, linux-kernel, hch
Al this series looks fine to me, want me to toss it into net-next?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-24 20:52 ` David Miller
@ 2018-01-25 0:01 ` Al Viro
2018-01-25 0:21 ` Al Viro
2018-01-25 4:11 ` David Miller
0 siblings, 2 replies; 28+ messages in thread
From: Al Viro @ 2018-01-25 0:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, torvalds, linux-kernel, hch
On Wed, Jan 24, 2018 at 03:52:44PM -0500, David Miller wrote:
>
> Al this series looks fine to me, want me to toss it into net-next?
Do you want them reposted (with updated commit messages), or would
you prefer a pull request (with or without rebase to current tip
of net-next)?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-25 0:01 ` Al Viro
@ 2018-01-25 0:21 ` Al Viro
2018-01-25 4:11 ` David Miller
1 sibling, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-25 0:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev, torvalds, linux-kernel, hch
On Thu, Jan 25, 2018 at 12:01:25AM +0000, Al Viro wrote:
> On Wed, Jan 24, 2018 at 03:52:44PM -0500, David Miller wrote:
> >
> > Al this series looks fine to me, want me to toss it into net-next?
>
> Do you want them reposted (with updated commit messages), or would
> you prefer a pull request (with or without rebase to current tip
> of net-next)?
Below is a pull request for rebased branch. Patches themselves are
identical to what had been posted, Reviewed-by added and commit message
for "kill dev_ifsioc()" made more detailed.
The following changes since commit be1b6e8b5470e8311bfa1a3dfd7bd59e85a99759:
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue (2018-01-24 18:02:17 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git rebased-net-ioctl
for you to fetch changes up to 5c59e564e46dcbab2ee7a4e9e0243562a39679a2:
kill kernel_sock_ioctl() (2018-01-24 19:13:45 -0500)
----------------------------------------------------------------
Al Viro (10):
net: separate SIOCGIFCONF handling from dev_ioctl()
devinet_ioctl(): take copyin/copyout to caller
ip_rt_ioctl(): take copyin to caller
kill dev_ifsioc()
kill bond_ioctl()
kill dev_ifname32()
lift handling of SIOCIW... out of dev_ioctl()
ipconfig: use dev_set_mtu()
dev_ioctl(): move copyin/copyout to callers
kill kernel_sock_ioctl()
include/linux/inetdevice.h | 2 +-
include/linux/net.h | 1 -
include/linux/netdevice.h | 7 +-
include/net/route.h | 2 +-
include/net/wext.h | 4 +-
net/core/dev_ioctl.c | 132 ++++++----------------
net/ipv4/af_inet.c | 28 ++++-
net/ipv4/devinet.c | 57 ++++------
net/ipv4/fib_frontend.c | 8 +-
net/ipv4/ipconfig.c | 47 ++------
net/socket.c | 271 ++++++++++++---------------------------------
net/wireless/wext-core.c | 13 ++-
12 files changed, 173 insertions(+), 399 deletions(-)
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 10/10] kill kernel_sock_ioctl()
2018-01-25 0:01 ` Al Viro
2018-01-25 0:21 ` Al Viro
@ 2018-01-25 4:11 ` David Miller
1 sibling, 0 replies; 28+ messages in thread
From: David Miller @ 2018-01-25 4:11 UTC (permalink / raw)
To: viro; +Cc: netdev, torvalds, linux-kernel, hch
From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Thu, 25 Jan 2018 00:01:25 +0000
> On Wed, Jan 24, 2018 at 03:52:44PM -0500, David Miller wrote:
>>
>> Al this series looks fine to me, want me to toss it into net-next?
>
> Do you want them reposted (with updated commit messages), or would
> you prefer a pull request (with or without rebase to current tip
> of net-next)?
A pull request works for me. Rebasing to net-next tip is pilot's
discretion.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl()
2018-01-18 19:37 ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
` (8 preceding siblings ...)
2018-01-18 19:37 ` [PATCH 10/10] kill kernel_sock_ioctl() Al Viro
@ 2018-01-22 16:40 ` Christoph Hellwig
9 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-22 16:40 UTC (permalink / raw)
To: Al Viro
Cc: netdev, David S. Miller, Linus Torvalds, linux-kernel, Christoph Hellwig
Looks nice:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 28+ messages in thread