Commit 7c1552da authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller
Browse files

ipv6: lift copy_from_user out of ipv6_route_ioctl



Prepare for better compat ioctl handling by moving the user copy out
of ipv6_route_ioctl.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a307593a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -118,7 +118,8 @@ void ip6_route_init_special_entries(void);
int ip6_route_init(void);
void ip6_route_cleanup(void);

int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);
int ipv6_route_ioctl(struct net *net, unsigned int cmd,
		struct in6_rtmsg *rtmsg);

int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags,
		  struct netlink_ext_ack *extack);
+10 −6
Original line number Diff line number Diff line
@@ -542,21 +542,25 @@ EXPORT_SYMBOL(inet6_getname);

int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct sock *sk = sock->sk;
	struct net *net = sock_net(sk);

	switch (cmd) {
	case SIOCADDRT:
	case SIOCDELRT:

		return ipv6_route_ioctl(net, cmd, (void __user *)arg);
	case SIOCDELRT: {
		struct in6_rtmsg rtmsg;

		if (copy_from_user(&rtmsg, argp, sizeof(rtmsg)))
			return -EFAULT;
		return ipv6_route_ioctl(net, cmd, &rtmsg);
	}
	case SIOCSIFADDR:
		return addrconf_add_ifaddr(net, (void __user *) arg);
		return addrconf_add_ifaddr(net, argp);
	case SIOCDIFADDR:
		return addrconf_del_ifaddr(net, (void __user *) arg);
		return addrconf_del_ifaddr(net, argp);
	case SIOCSIFDSTADDR:
		return addrconf_set_dstaddr(net, (void __user *) arg);
		return addrconf_set_dstaddr(net, argp);
	default:
		if (!sk->sk_prot->ioctl)
			return -ENOIOCTLCMD;
+16 −28
Original line number Diff line number Diff line
@@ -4336,23 +4336,17 @@ static void rtmsg_to_fib6_config(struct net *net,
	};
}

int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
int ipv6_route_ioctl(struct net *net, unsigned int cmd, struct in6_rtmsg *rtmsg)
{
	struct fib6_config cfg;
	struct in6_rtmsg rtmsg;
	int err;

	switch (cmd) {
	case SIOCADDRT:		/* Add a route */
	case SIOCDELRT:		/* Delete a route */
	if (cmd != SIOCADDRT && cmd != SIOCDELRT)
		return -EINVAL;
	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
		return -EPERM;
		err = copy_from_user(&rtmsg, arg,
				     sizeof(struct in6_rtmsg));
		if (err)
			return -EFAULT;

		rtmsg_to_fib6_config(net, &rtmsg, &cfg);
	rtmsg_to_fib6_config(net, rtmsg, &cfg);

	rtnl_lock();
	switch (cmd) {
@@ -4362,17 +4356,11 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
	case SIOCDELRT:
		err = ip6_route_del(&cfg, NULL);
		break;
		default:
			err = -EINVAL;
	}
	rtnl_unlock();

	return err;
}

	return -EINVAL;
}

/*
 *	Drop the packet on the floor
 */