Thread (8 messages) flat view 8 messages, 4 authors, 2021-08-27

Re: [PATCH] net: don't unconditionally copy_from_user a struct ifreq for socket ioctls

From: Arnd Bergmann <arnd@kernel.org>
Date: 2021-08-26 08:59:04
Also in: lkml, stable

On Thu, Aug 26, 2021 at 3:28 AM Peter Collingbourne [off-list ref] wrote:
quoted hunk ↗ jump to hunk
-       } else {
+       } else if (is_dev_ioctl_cmd(cmd)) {
                struct ifreq ifr;
                bool need_copyout;
                if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
@@ -1118,6 +1118,8 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
                if (!err && need_copyout)
                        if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
                                return -EFAULT;
+       } else {
+               err = -ENOTTY;
        }
        return err;
 }
@@ -3306,6 +3308,8 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
        struct ifreq ifreq;
        u32 data32;

+       if (!is_dev_ioctl_cmd(cmd))
+               return -ENOTTY;
        if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
                return -EFAULT;
        if (get_user(data32, &u_ifreq32->ifr_data))
This adds yet another long switch() statement into the socket ioctl
case, when there
is already one in compat_sock_ioctl_trans(), one in dev_ifsioc() and one in
dev_ioctl(), all with roughly the same set of ioctl command codes. If
any of them
are called frequently, that makes it all even slower, so I wonder if
there should
be a larger rework altogether. Maybe something based on a single lookup table
that we search through directly from sock_ioctl()/compat_sock_ioctl() to deal
with the differences in handling (ifreq based, compat handler, proto_ops
override, dev_load, rtnl_lock, rcu_read_lock, CAP_NET_ADMIN, copyout, ...).

You are also adding the checks into different places for native and compat
mode, which makes them diverge more when we should be trying to
make them more common.

I think based on my recent changes, some other simplifications are possible,
based on how the compat path already enumerates all the dev ioctls.

        Arnd
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help