netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
       [not found]               ` <20180117185232.GW13338@ZenIV.linux.org.uk>
@ 2018-01-18  3:06                 ` Al Viro
  2018-01-18  3:16                   ` Linus Torvalds
  0 siblings, 1 reply; 28+ messages in thread
From: Al Viro @ 2018-01-18  3:06 UTC (permalink / raw)
  To: netdev
  Cc: Linus Torvalds, Dan Williams, Linux Kernel Mailing List,
	linux-arch, Andi Kleen, Kees Cook, kernel-hardening,
	Greg Kroah-Hartman, the arch/x86 maintainers, Ingo Molnar,
	H. Peter Anvin, Thomas Gleixner, Andrew Morton, Alan Cox,
	David Miller

On Wed, Jan 17, 2018 at 06:52:32PM +0000, Al Viro wrote:

[use of set_fs() by sunrpc]
> We are asking for recvmsg() with zero data length; what we really want is
> ->msg_control.  And _that_ is why we need that set_fs() - we want the damn
> thing to go into local variable.
> 
> But note that filling ->msg_control will happen in put_cmsg(), called
> from ip_cmsg_recv_pktinfo(), called from ip_cmsg_recv_offset(),
> called from udp_recvmsg(), called from sock_recvmsg_nosec(), called
> from sock_recvmsg().  Or in another path in case of IPv6.
> Sure, we can arrange for propagation of that all way down those
> call chains.  My preference would be to try and mark that (one and
> only) case in ->msg_flags, so that put_cmsg() would be able to
> check.  ___sys_recvmsg() sets that as
>         msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
> so we ought to be free to use any bit other than those two.  Since
> put_cmsg() already checks ->msg_flags, that shouldn't put too much
> overhead.

Folks, does anybody have objections against the following:

Get rid of kernel_recvmsg() (and thus set_fs()) use in sunrpc

In net/sunrpc/svcsock.c:svc_udp_recvfrom() we want to get
IP_PKTINFO; currently we stash the address of local variable
into ->msg_control (which normall contains a userland pointer
in recepients) and issue zero-length ->recvmsg() under
set_fs(KERNEL_DS).

Similar to the way put_cmsg() handles 32bit case on biarch
targets, introduce a flag telling put_cmsg() to treat
->msg_control as kernel pointer, using memcpy instead of
copy_to_user().  That allows to avoid the use of kernel_recvmsg()
with its set_fs().

All places that might have non-NULL ->msg_control either pass the
msghdr only to ->sendmsg() and its ilk, or have ->msg_flags
sanitized before passing msghdr anywhere.  IOW, there no
way the new flag to reach put_cmsg() in the mainline kernel,
and after this change it will only be seen in sunrpc case.

Incidentally, all other kernel_recvmsg() users are very easy to
convert to sock_recvmsg(), so that would allow to kill
kernel_recvmsg() off...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 9286a5a8c60c..60947da9c806 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -298,6 +298,7 @@ struct ucred {
 #else
 #define MSG_CMSG_COMPAT	0		/* We never have 32 bit fixups */
 #endif
+#define MSG_CMSG_KERNEL	0x10000000
 
 
 /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
diff --git a/net/core/scm.c b/net/core/scm.c
index b1ff8a441748..1b73b682e441 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -237,10 +237,17 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
 	cmhdr.cmsg_len = cmlen;
 
 	err = -EFAULT;
-	if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
-		goto out;
-	if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
-		goto out;
+	if (unlikely(MSG_CMSG_KERNEL & msg->msg_flags)) {
+		struct cmsghdr *p = msg->msg_control;
+		memcpy(p, &cmhdr, sizeof cmhdr);
+		memcpy(CMSG_DATA(p), data, cmlen - sizeof(struct cmsghdr));
+	} else {
+		if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
+			goto out;
+		if (copy_to_user(CMSG_DATA(cm), data,
+				 cmlen - sizeof(struct cmsghdr)))
+			goto out;
+	}
 	cmlen = CMSG_SPACE(len);
 	if (msg->msg_controllen < cmlen)
 		cmlen = msg->msg_controllen;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5570719e4787..774904f67c93 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -545,7 +545,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
 		.msg_name = svc_addr(rqstp),
 		.msg_control = cmh,
 		.msg_controllen = sizeof(buffer),
-		.msg_flags = MSG_DONTWAIT,
+		.msg_flags = MSG_DONTWAIT | MSG_CMSG_KERNEL,
 	};
 	size_t len;
 	int err;
@@ -565,8 +565,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
 
 	clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
 	skb = NULL;
-	err = kernel_recvmsg(svsk->sk_sock, &msg, NULL,
-			     0, 0, MSG_PEEK | MSG_DONTWAIT);
+	err = sock_recvmsg(svsk->sk_sock, &msg, MSG_PEEK | MSG_DONTWAIT);
 	if (err >= 0)
 		skb = skb_recv_udp(svsk->sk_sk, 0, 1, &err);
 

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18  3:06                 ` [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc Al Viro
@ 2018-01-18  3:16                   ` Linus Torvalds
  2018-01-18  4:43                     ` Al Viro
  0 siblings, 1 reply; 28+ messages in thread
From: Linus Torvalds @ 2018-01-18  3:16 UTC (permalink / raw)
  To: Al Viro
  Cc: Network Development, Dan Williams, Linux Kernel Mailing List,
	linux-arch, Andi Kleen, Kees Cook, kernel-hardening,
	Greg Kroah-Hartman, the arch/x86 maintainers, Ingo Molnar,
	H. Peter Anvin, Thomas Gleixner, Andrew Morton, Alan Cox,
	David Miller

On Wed, Jan 17, 2018 at 7:06 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> Similar to the way put_cmsg() handles 32bit case on biarch
> targets, introduce a flag telling put_cmsg() to treat
> ->msg_control as kernel pointer, using memcpy instead of
> copy_to_user().  That allows to avoid the use of kernel_recvmsg()
> with its set_fs().

If this is the only case that kernel_recvmsg() exists for, then by all
means, that patch certainly looks like a good thing.

                 Linus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18  3:16                   ` Linus Torvalds
@ 2018-01-18  4:43                     ` Al Viro
  2018-01-18 16:29                       ` Christoph Hellwig
  2018-01-18 19:31                       ` Al Viro
  0 siblings, 2 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18  4:43 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Network Development, Dan Williams, Linux Kernel Mailing List,
	linux-arch, Andi Kleen, Kees Cook, kernel-hardening,
	Greg Kroah-Hartman, the arch/x86 maintainers, Ingo Molnar,
	H. Peter Anvin, Thomas Gleixner, Andrew Morton, Alan Cox,
	David Miller

On Wed, Jan 17, 2018 at 07:16:02PM -0800, Linus Torvalds wrote:
> On Wed, Jan 17, 2018 at 7:06 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> > Similar to the way put_cmsg() handles 32bit case on biarch
> > targets, introduce a flag telling put_cmsg() to treat
> > ->msg_control as kernel pointer, using memcpy instead of
> > copy_to_user().  That allows to avoid the use of kernel_recvmsg()
> > with its set_fs().
> 
> If this is the only case that kernel_recvmsg() exists for, then by all
> means, that patch certainly looks like a good thing.

In -next that's the only remaining caller.  kernel_recvmsg() is
{
        mm_segment_t oldfs = get_fs();
        int result;

        iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size);
        set_fs(KERNEL_DS);
        result = sock_recvmsg(sock, msg, flags);
        set_fs(oldfs);
        return result;
}
and 
        iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size);
        result = sock_recvmsg(sock, msg, flags);
works just fine for copying the data - that gets handled by copy_to_iter()
and copy_page_to_iter().  Those don't care about set_fs(); the trouble with
sunrpc call site is that we want to fill msg_control-pointed kernel object.
That gets copied by put_cmsg().

	We could turn ->msg_control/->msg_controllen into another
iov_iter, but seeing that we never do scatter-gather for those
IMO that would be a massive overkill.  A flag controlling whether
->msg_control is kernel or userland pointer would do, especially
since we already have a flag for "do we want a native or compat
layout for cmsg" in there.

	That's the only caller we need it for, but that thing looks cheap
enough.  Obviously needs to pass testing, including "is it too ugly to
live as far as Davem is concerned" test, though...

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18  4:43                     ` Al Viro
@ 2018-01-18 16:29                       ` Christoph Hellwig
  2018-01-18 17:10                         ` Al Viro
  2018-01-18 19:31                       ` Al Viro
  1 sibling, 1 reply; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-18 16:29 UTC (permalink / raw)
  To: Al Viro
  Cc: Linus Torvalds, Network Development, Dan Williams,
	Linux Kernel Mailing List, linux-arch, Andi Kleen, Kees Cook,
	kernel-hardening, Greg Kroah-Hartman, the arch/x86 maintainers,
	Ingo Molnar, H. Peter Anvin, Thomas Gleixner, Andrew Morton,
	Alan Cox, David Miller

> 	We could turn ->msg_control/->msg_controllen into another
> iov_iter, but seeing that we never do scatter-gather for those
> IMO that would be a massive overkill.  A flag controlling whether
> ->msg_control is kernel or userland pointer would do, especially
> since we already have a flag for "do we want a native or compat
> layout for cmsg" in there.

While your current hack seems like a nice short term improvement
I think we need an iov_iter or iov_iter-light there in the long run.
Same for ioctl so that we can pass properly typed kernel or user
buffers through without all these set_fs hacks.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18 16:29                       ` Christoph Hellwig
@ 2018-01-18 17:10                         ` Al Viro
  0 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 17:10 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linus Torvalds, Network Development, Dan Williams,
	Linux Kernel Mailing List, linux-arch, Andi Kleen, Kees Cook,
	kernel-hardening, Greg Kroah-Hartman, the arch/x86 maintainers,
	Ingo Molnar, H. Peter Anvin, Thomas Gleixner, Andrew Morton,
	Alan Cox, David Miller

On Thu, Jan 18, 2018 at 08:29:57AM -0800, Christoph Hellwig wrote:
> > 	We could turn ->msg_control/->msg_controllen into another
> > iov_iter, but seeing that we never do scatter-gather for those
> > IMO that would be a massive overkill.  A flag controlling whether
> > ->msg_control is kernel or userland pointer would do, especially
> > since we already have a flag for "do we want a native or compat
> > layout for cmsg" in there.
> 
> While your current hack seems like a nice short term improvement
> I think we need an iov_iter or iov_iter-light there in the long run.

For one caller in the entire history of the kernel?

> Same for ioctl so that we can pass properly typed kernel or user
> buffers through without all these set_fs hacks.

Umm...  Most of the PITA with ioctls is due to compat ones being
reformatted for native and fed under set_fs().  I actually have
a series dealing with most of such places for net ioctls.  Sure,
there's also ioctl_by_bdev(), but for those we might be better
off exposing the things like ->get_last_session() and its ilk to
filesystems that want to deal with cdroms...

It's kernel_setsockopt() that is the real PITA...

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18  4:43                     ` Al Viro
  2018-01-18 16:29                       ` Christoph Hellwig
@ 2018-01-18 19:31                       ` Al Viro
  2018-01-18 19:37                         ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
                                           ` (2 more replies)
  1 sibling, 3 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 19:31 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Network Development, Dan Williams, Linux Kernel Mailing List,
	linux-arch, Andi Kleen, Kees Cook, kernel-hardening,
	Greg Kroah-Hartman, the arch/x86 maintainers, Ingo Molnar,
	H. Peter Anvin, Thomas Gleixner, Andrew Morton, Alan Cox,
	David Miller

On Thu, Jan 18, 2018 at 04:43:02AM +0000, Al Viro wrote:

> 	We could turn ->msg_control/->msg_controllen into another
> iov_iter, but seeing that we never do scatter-gather for those
> IMO that would be a massive overkill.  A flag controlling whether
> ->msg_control is kernel or userland pointer would do, especially
> since we already have a flag for "do we want a native or compat
> layout for cmsg" in there.
> 
> 	That's the only caller we need it for, but that thing looks cheap
> enough.  Obviously needs to pass testing, including "is it too ugly to
> live as far as Davem is concerned" test, though...

	BTW, there's another series of set_fs-removal patches in
net ioctls; still needs review, though.  With that one we would be down
to 11 instances in the entire net/*:

* SO_RCVTIMEO/SO_SNDTIMEO handling in compat [sg]etsockopt()
* passing SIOC{ADD,DEL}TUNNEL down (ipmr_del_tunnel(),ipmr_new_tunnel(),
  addrconf_set_dstaddr())
* SIOCGSTAMP/SIOCGSTAMPNS in compat ioctls
* SIOCADDRT/SIOCDELRT in compat ioctls
* kernel_[gs]etsockopt()
* ipv6_renew_options_kern()

I don't know if all of that stuff can be realistically done without set_fs().
kernel_setsockopt(), in particular, is unpleasant...

The patches need review and testing, obviously; I'll post them in followups,
the entire series (on top of net/master) is in
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #work.net-ioctl

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl()
  2018-01-18 19:31                       ` Al Viro
@ 2018-01-18 19:37                         ` Al Viro
  2018-01-18 19:37                           ` [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller Al Viro
                                             ` (9 more replies)
  2018-01-18 20:33                         ` [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc Al Viro
  2018-01-19  3:27                         ` Al Viro
  2 siblings, 10 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>

Only two of dev_ioctl() callers may pass SIOCGIFCONF to it.
Separating that codepath from the rest of dev_ioctl() allows both
to simplify dev_ioctl() itself (all other cases work with struct ifreq *)
*and* seriously simplify the compat side of that beast: all it takes
is passing to inet_gifconf() an extra argument - the size of individual
records (sizeof(struct ifreq) or sizeof(struct compat_ifreq)).  With
dev_ifconf() called directly from sock_do_ioctl()/compat_dev_ifconf()
that's easy to arrange.

As the result, compat side of SIOCGIFCONF doesn't need any
allocations, copy_in_user() back and forth, etc.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 include/linux/netdevice.h |  4 ++-
 net/core/dev_ioctl.c      | 29 +++++------------
 net/ipv4/devinet.c        | 16 +++++-----
 net/socket.c              | 79 ++++++++++++++---------------------------------
 4 files changed, 42 insertions(+), 86 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ed0799a12bf2..221487f5b214 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2759,7 +2759,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
 	return false;
 }
 
-typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
+typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr,
+			   int len, int size);
 int register_gifconf(unsigned int family, gifconf_func_t *gifconf);
 static inline int unregister_gifconf(unsigned int family)
 {
@@ -3313,6 +3314,7 @@ 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_ifconf(struct net *net, struct ifconf *, int);
 int dev_ethtool(struct net *net, struct ifreq *);
 unsigned int dev_get_flags(const struct net_device *);
 int __dev_change_flags(struct net_device *, unsigned int flags);
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 7e690d0ccd05..5cdec23dd28e 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -66,9 +66,8 @@ EXPORT_SYMBOL(register_gifconf);
  *	Thus we will need a 'compatibility mode'.
  */
 
-static int dev_ifconf(struct net *net, char __user *arg)
+int dev_ifconf(struct net *net, struct ifconf *ifc, int size)
 {
-	struct ifconf ifc;
 	struct net_device *dev;
 	char __user *pos;
 	int len;
@@ -79,11 +78,8 @@ static int dev_ifconf(struct net *net, char __user *arg)
 	 *	Fetch the caller's info block.
 	 */
 
-	if (copy_from_user(&ifc, arg, sizeof(struct ifconf)))
-		return -EFAULT;
-
-	pos = ifc.ifc_buf;
-	len = ifc.ifc_len;
+	pos = ifc->ifc_buf;
+	len = ifc->ifc_len;
 
 	/*
 	 *	Loop over the interfaces, and write an info block for each.
@@ -95,10 +91,10 @@ static int dev_ifconf(struct net *net, char __user *arg)
 			if (gifconf_list[i]) {
 				int done;
 				if (!pos)
-					done = gifconf_list[i](dev, NULL, 0);
+					done = gifconf_list[i](dev, NULL, 0, size);
 				else
 					done = gifconf_list[i](dev, pos + total,
-							       len - total);
+							       len - total, size);
 				if (done < 0)
 					return -EFAULT;
 				total += done;
@@ -109,12 +105,12 @@ static int dev_ifconf(struct net *net, char __user *arg)
 	/*
 	 *	All done.  Write the updated control block back to the caller.
 	 */
-	ifc.ifc_len = total;
+	ifc->ifc_len = total;
 
 	/*
 	 * 	Both BSD and Solaris return 0 here, so we do too.
 	 */
-	return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
+	return 0;
 }
 
 /*
@@ -412,17 +408,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	int ret;
 	char *colon;
 
-	/* One special case: SIOCGIFCONF takes ifconf argument
-	   and requires shared lock, because it sleeps writing
-	   to user space.
-	 */
-
-	if (cmd == SIOCGIFCONF) {
-		rtnl_lock();
-		ret = dev_ifconf(net, (char __user *) arg);
-		rtnl_unlock();
-		return ret;
-	}
 	if (cmd == SIOCGIFNAME)
 		return dev_ifname(net, (struct ifreq __user *)arg);
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 7a93359fbc72..1771549d2438 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1188,22 +1188,25 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	goto out;
 }
 
-static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
+static int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size)
 {
 	struct in_device *in_dev = __in_dev_get_rtnl(dev);
 	struct in_ifaddr *ifa;
 	struct ifreq ifr;
 	int done = 0;
 
+	if (WARN_ON(size > sizeof(struct ifreq)))
+		goto out;
+
 	if (!in_dev)
 		goto out;
 
 	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
 		if (!buf) {
-			done += sizeof(ifr);
+			done += size;
 			continue;
 		}
-		if (len < (int) sizeof(ifr))
+		if (len < size)
 			break;
 		memset(&ifr, 0, sizeof(struct ifreq));
 		strcpy(ifr.ifr_name, ifa->ifa_label);
@@ -1212,13 +1215,12 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
 		(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr =
 								ifa->ifa_local;
 
-		if (copy_to_user(buf, &ifr, sizeof(struct ifreq))) {
+		if (copy_to_user(buf + done, &ifr, size)) {
 			done = -EFAULT;
 			break;
 		}
-		buf  += sizeof(struct ifreq);
-		len  -= sizeof(struct ifreq);
-		done += sizeof(struct ifreq);
+		len  -= size;
+		done += size;
 	}
 out:
 	return done;
diff --git a/net/socket.c b/net/socket.c
index fbfae1ed3ff5..112216c537e7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -961,10 +961,22 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
 	 * If this ioctl is unknown try to hand it down
 	 * to the NIC driver.
 	 */
-	if (err == -ENOIOCTLCMD)
-		err = dev_ioctl(net, cmd, argp);
+	if (err != -ENOIOCTLCMD)
+		return err;
 
-	return err;
+	if (cmd == SIOCGIFCONF) {
+		struct ifconf ifc;
+		if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
+			return -EFAULT;
+		rtnl_lock();
+		err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
+		rtnl_unlock();
+		if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
+			err = -EFAULT;
+		return err;
+	}
+
+	return dev_ioctl(net, cmd, argp);
 }
 
 /*
@@ -2682,70 +2694,25 @@ static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
 	return 0;
 }
 
-static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
+static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
 {
 	struct compat_ifconf ifc32;
 	struct ifconf ifc;
-	struct ifconf __user *uifc;
-	struct compat_ifreq __user *ifr32;
-	struct ifreq __user *ifr;
-	unsigned int i, j;
 	int err;
 
 	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
 		return -EFAULT;
 
-	memset(&ifc, 0, sizeof(ifc));
-	if (ifc32.ifcbuf == 0) {
-		ifc32.ifc_len = 0;
-		ifc.ifc_len = 0;
-		ifc.ifc_req = NULL;
-		uifc = compat_alloc_user_space(sizeof(struct ifconf));
-	} else {
-		size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
-			sizeof(struct ifreq);
-		uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
-		ifc.ifc_len = len;
-		ifr = ifc.ifc_req = (void __user *)(uifc + 1);
-		ifr32 = compat_ptr(ifc32.ifcbuf);
-		for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
-			if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
-				return -EFAULT;
-			ifr++;
-			ifr32++;
-		}
-	}
-	if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
-		return -EFAULT;
+	ifc.ifc_len = ifc32.ifc_len;
+	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
 
-	err = dev_ioctl(net, SIOCGIFCONF, uifc);
+	rtnl_lock();
+	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
+	rtnl_unlock();
 	if (err)
 		return err;
 
-	if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
-		return -EFAULT;
-
-	ifr = ifc.ifc_req;
-	ifr32 = compat_ptr(ifc32.ifcbuf);
-	for (i = 0, j = 0;
-	     i + sizeof(struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
-	     i += sizeof(struct compat_ifreq), j += sizeof(struct ifreq)) {
-		if (copy_in_user(ifr32, ifr, sizeof(struct compat_ifreq)))
-			return -EFAULT;
-		ifr32++;
-		ifr++;
-	}
-
-	if (ifc32.ifcbuf == 0) {
-		/* Translate from 64-bit structure multiple to
-		 * a 32-bit one.
-		 */
-		i = ifc.ifc_len;
-		i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
-		ifc32.ifc_len = i;
-	} else {
-		ifc32.ifc_len = i;
-	}
+	ifc32.ifc_len = ifc.ifc_len;
 	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
 		return -EFAULT;
 
@@ -3142,7 +3109,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
 	case SIOCGIFNAME:
 		return dev_ifname32(net, argp);
 	case SIOCGIFCONF:
-		return dev_ifconf(net, argp);
+		return compat_dev_ifconf(net, argp);
 	case SIOCETHTOOL:
 		return ethtool_ioctl(net, argp);
 	case SIOCWANDEV:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [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

* [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

* [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: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18 19:31                       ` Al Viro
  2018-01-18 19:37                         ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
@ 2018-01-18 20:33                         ` Al Viro
  2018-01-19  3:27                         ` Al Viro
  2 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-18 20:33 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Network Development, Dan Williams, Linux Kernel Mailing List,
	linux-arch, Andi Kleen, Kees Cook, kernel-hardening,
	Greg Kroah-Hartman, the arch/x86 maintainers, Ingo Molnar,
	H. Peter Anvin, Thomas Gleixner, Andrew Morton, Alan Cox,
	David Miller

On Thu, Jan 18, 2018 at 07:31:56PM +0000, Al Viro wrote:

> * SO_RCVTIMEO/SO_SNDTIMEO handling in compat [sg]etsockopt()
> * passing SIOC{ADD,DEL}TUNNEL down (ipmr_del_tunnel(),ipmr_new_tunnel(),
>   addrconf_set_dstaddr())
> * SIOCGSTAMP/SIOCGSTAMPNS in compat ioctls
> * SIOCADDRT/SIOCDELRT in compat ioctls
> * kernel_[gs]etsockopt()
> * ipv6_renew_options_kern()
> 
> I don't know if all of that stuff can be realistically done without set_fs().
> kernel_setsockopt(), in particular, is unpleasant...

Speaking of weird indirect calls: in net/packet/af_packet.c:packet_ioctl() we
have this:
#ifdef CONFIG_INET
        case SIOCADDRT:
        case SIOCDELRT:
        case SIOCDARP:
        case SIOCGARP:
        case SIOCSARP:
        case SIOCGIFADDR:
        case SIOCSIFADDR:
        case SIOCGIFBRDADDR:
        case SIOCSIFBRDADDR:
        case SIOCGIFNETMASK:
        case SIOCSIFNETMASK:
        case SIOCGIFDSTADDR:
        case SIOCSIFDSTADDR:
        case SIOCSIFFLAGS:
                return inet_dgram_ops.ioctl(sock, cmd, arg);
#endif

That's inet_ioctl(sock, cmd, arg) disguised by indirect.  AFAICS,
that line dates back to 2.1.89; back then inet_dgram_ops had been
exported and inet_ioctl() had been static.  When SCTP went in
they'd exported inet_ioctl() rather than playing that kind of
games.

Is there anything subtle I'm missing here that would make it
wrong to replace that with explicit call of inet_ioctl()?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc
  2018-01-18 19:31                       ` Al Viro
  2018-01-18 19:37                         ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Al Viro
  2018-01-18 20:33                         ` [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc Al Viro
@ 2018-01-19  3:27                         ` Al Viro
  2 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2018-01-19  3:27 UTC (permalink / raw)
  To: Network Development
  Cc: Dan Williams, Linux Kernel Mailing List, linux-arch, Andi Kleen,
	Kees Cook, kernel-hardening, Greg Kroah-Hartman,
	the arch/x86 maintainers, Ingo Molnar, H. Peter Anvin,
	Thomas Gleixner, Andrew Morton, Alan Cox, David Miller,
	Linus Torvalds, Ralf Baechle

On Thu, Jan 18, 2018 at 07:31:56PM +0000, Al Viro wrote:

> * SIOCADDRT/SIOCDELRT in compat ioctls

To bring back a question I'd asked back in October - what do
we do about SIOC...RT compat?

To recap:
	* AF_INET sockets expect struct rtentry; it differs
between 32bit and 64bit, so routing_ioctl() in net/socket.c
is called from compat_sock_ioctl_trans() and does the right
thing.  All proto_ops instances with .family = PF_INET (and
only they) have inet_ioctl() as ->ioctl(), and end up with
ip_rt_ioctl() called for native ones.  Three of those have
->compat_ioctl() set to inet_compat_ioctl(), the rest have
it NULL.  In any case, inet_compat_ioctl() ignores those,
leaving them to compat_sock_ioctl_trans() to pick up.
	* for AF_INET6 the situation is similar, except that
they use struct in6_rtmsg.  Compat is also dealt with in
routing_ioctl().  inet6_ioctl() for all such proto_ops
(and only those), ipv6_route_ioctl() is what ends up
handling the native ones.  No ->compat_ioctl() in any
of those.
	* AF_PACKET sockets expect struct rt_entry and
actually bounce the native calls to inet_ioctl().  No
->compat_ioctl() there, but routing_ioctl() in net/socket.c
does the right thing.
	* AF_APPLETALK sockets expect struct rt_entry.
Native handled in atrtr_ioctl(); there is ->compat_ioctl(),
but it ignores those ioctls, so we go through the conversion
in net/socket.c.  Also happens to work correctly.

	* ax25, ipx, netrom, rose and x25 use structures
of their own, and those structures have identical layouts on
32bit and 64bit.  x25 has ->compat_ioctl() that does the
right thing (bounces to native), the rest either have
->compat_ioctl() ignoring those ioctls (ipx) or do not
have ->compat_ioctl() at all.  That ends up with generic
code picking those and buggering them up - routing_ioctl()
assumes that we want either in6_rtmsg (ipv6) or rtentry
(everything else).  Unfortunately, in case of these
protocols we should just leave the suckers alone.
	Back then Ralf has verified that the bug exists
and said he'd put together a fix.  Looks like that fix
has fallen through the cracks, though.

	* all other protocols fail those; usually with
ENOTTY, except for AF_QIPCRTR that fails with EINVAL.
Either way, compat is not an issue.

	Note that handling of SIOCADDRT on e.g. raw ipv4
sockets from 32bit process is convoluted as hell.  The
call chain is
	compat_sys_ioctl()
		compat_sock_ioctl()
			inet_compat_ioctl()
				compat_raw_ioctl()
					=> -ENOIOCTLCMD, possibly
					    by way of ipmr_compat_ioctl()
			compat_sock_ioctl_trans()
				routing_ioctl() [conversion done here]
					sock_do_ioctl()
						inet_ioctl()
							ip_rt_ioctl()
A lot of those are method calls, BTW, and the overhead on those has
just grown...

Does anybody have objections against the following?

1) Somewhere in net/core (or net/compat.c, for that matter) add
int compat_get_rtentry(struct rtentry *r, struct rtentry32 __user *p);

2) In inet_compat_ioctl() recognize SIOC{ADD,DEL}RT and do
		err = compat_get_rtentry(&r, (void __user *)arg);
		if (!err)
			err = ip_rt_ioctl(...)
		return err;

3) Add inet_compat_ioctl() as ->compat_ioctl in all PF_INET proto_ops.

4) Lift copyin from atrtr_ioctl() to atalk_ioctl(), teach
atalk_compat_ioctl() about these ioctls (using compat_get_rtentry()
and atrtr_ioctl(), that is).

5) Add ->compat_ioctl() to AF_PACKET, let it just call inet_compat_ioctl()
for those two.

6) Lift copyin from ipv6_route_ioctl() to inet6_ioctl().  
Add inet6_compat_ioctl() that would recognize those two, do compat copyin
and call ipv6_route_ioctl().  Make it ->compat_ioctl for all PF_INET6
proto_ops.

7) Tell compat_sock_ioctl_trans() to move these two into the "just call
sock_do_ioctl()" group of cases.  Or, with Ralf's fix, just remove these
two cases from compat_sock_ioctl_trans() completely.  Either way,
routing_ioctl() becomes dead code and can be removed.

^ 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

* Re: [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller
  2018-01-18 19:37                           ` [PATCH 02/10] devinet_ioctl(): take copyin/copyout to caller Al Viro
@ 2018-01-22 16:40                             ` Christoph Hellwig
  0 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 good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[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

* 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

* Re: [PATCH 05/10] kill bond_ioctl()
  2018-01-18 19:37                           ` [PATCH 05/10] kill bond_ioctl() Al Viro
@ 2018-01-22 16:48                             ` Christoph Hellwig
  0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-01-22 16:48 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:50PM +0000, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
> 
> another sock_do_ioctl() equivalent

Except for the additional data copy.  Which might be worth mentioning
in the changelog.

^ 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
  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

end of thread, other threads:[~2018-01-25  4:11 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com>
     [not found] ` <151586748981.5820.14559543798744763404.stgit@dwillia2-desk3.amr.corp.intel.com>
     [not found]   ` <CA+55aFzoAR+MYX+ub0xZ32OsT7WtD5Kru2t6LhwB1buLWPResQ@mail.gmail.com>
     [not found]     ` <CA+55aFxsg5+u7bCHj1N8xyyVf7-RMm-5ACNp=ENNrKL78omaow@mail.gmail.com>
     [not found]       ` <CAPcyv4hfUx8gLScuNewY3+BWi4YBS_Z9dhvYf1D+WEWDDCShXA@mail.gmail.com>
     [not found]         ` <CA+55aFxAFG5czVmCyhYMyHmXLNJ7pcXxWzusjZvLRh_qTGHj6Q@mail.gmail.com>
     [not found]           ` <CA+55aFxB01XEEpdPynwYmzQMfTJdJnUrN+ZLqSV_UdnKLBgAZw@mail.gmail.com>
     [not found]             ` <1516198646.4184.13.camel@linux.intel.com>
     [not found]               ` <20180117185232.GW13338@ZenIV.linux.org.uk>
2018-01-18  3:06                 ` [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc Al Viro
2018-01-18  3:16                   ` Linus Torvalds
2018-01-18  4:43                     ` Al Viro
2018-01-18 16:29                       ` Christoph Hellwig
2018-01-18 17:10                         ` Al Viro
2018-01-18 19:31                       ` Al Viro
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-22 16:40                             ` Christoph Hellwig
2018-01-18 19:37                           ` [PATCH 03/10] ip_rt_ioctl(): take copyin " Al Viro
2018-01-22 16:43                             ` Christoph Hellwig
2018-01-18 19:37                           ` [PATCH 04/10] kill dev_ifsioc() Al Viro
2018-01-22 16:47                             ` Christoph Hellwig
2018-01-18 19:37                           ` [PATCH 05/10] kill bond_ioctl() Al Viro
2018-01-22 16:48                             ` Christoph Hellwig
2018-01-18 19:37                           ` [PATCH 06/10] kill dev_ifname32() Al Viro
2018-01-18 19:37                           ` [PATCH 07/10] lift handling of SIOCIW... out of dev_ioctl() Al Viro
2018-01-18 19:37                           ` [PATCH 08/10] ipconfig: use dev_set_mtu() Al Viro
2018-01-18 19:37                           ` [PATCH 09/10] dev_ioctl(): move copyin/copyout to callers Al Viro
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
2018-01-25  0:21                                 ` Al Viro
2018-01-25  4:11                                 ` David Miller
2018-01-22 16:40                           ` [PATCH 01/10] net: separate SIOCGIFCONF handling from dev_ioctl() Christoph Hellwig
2018-01-18 20:33                         ` [RFC][PATCH] get rid of the use of set_fs() (by way of kernel_recvmsg()) in sunrpc Al Viro
2018-01-19  3:27                         ` Al Viro

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).