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: Christoph Hellwig <hch@lst.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a307593a64
commit
7c1552da90
@ -118,7 +118,8 @@ void ip6_route_init_special_entries(void);
|
|||||||
int ip6_route_init(void);
|
int ip6_route_init(void);
|
||||||
void ip6_route_cleanup(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,
|
int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags,
|
||||||
struct netlink_ext_ack *extack);
|
struct netlink_ext_ack *extack);
|
||||||
|
@ -542,21 +542,25 @@ EXPORT_SYMBOL(inet6_getname);
|
|||||||
|
|
||||||
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
|
void __user *argp = (void __user *)arg;
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct net *net = sock_net(sk);
|
struct net *net = sock_net(sk);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCADDRT:
|
case SIOCADDRT:
|
||||||
case SIOCDELRT:
|
case SIOCDELRT: {
|
||||||
|
struct in6_rtmsg rtmsg;
|
||||||
return ipv6_route_ioctl(net, cmd, (void __user *)arg);
|
|
||||||
|
|
||||||
|
if (copy_from_user(&rtmsg, argp, sizeof(rtmsg)))
|
||||||
|
return -EFAULT;
|
||||||
|
return ipv6_route_ioctl(net, cmd, &rtmsg);
|
||||||
|
}
|
||||||
case SIOCSIFADDR:
|
case SIOCSIFADDR:
|
||||||
return addrconf_add_ifaddr(net, (void __user *) arg);
|
return addrconf_add_ifaddr(net, argp);
|
||||||
case SIOCDIFADDR:
|
case SIOCDIFADDR:
|
||||||
return addrconf_del_ifaddr(net, (void __user *) arg);
|
return addrconf_del_ifaddr(net, argp);
|
||||||
case SIOCSIFDSTADDR:
|
case SIOCSIFDSTADDR:
|
||||||
return addrconf_set_dstaddr(net, (void __user *) arg);
|
return addrconf_set_dstaddr(net, argp);
|
||||||
default:
|
default:
|
||||||
if (!sk->sk_prot->ioctl)
|
if (!sk->sk_prot->ioctl)
|
||||||
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
||||||
|
@ -4336,41 +4336,29 @@ 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 fib6_config cfg;
|
||||||
struct in6_rtmsg rtmsg;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (cmd != SIOCADDRT && cmd != SIOCDELRT)
|
||||||
|
return -EINVAL;
|
||||||
|
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
rtmsg_to_fib6_config(net, rtmsg, &cfg);
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCADDRT: /* Add a route */
|
case SIOCADDRT:
|
||||||
case SIOCDELRT: /* Delete a route */
|
err = ip6_route_add(&cfg, GFP_KERNEL, NULL);
|
||||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
break;
|
||||||
return -EPERM;
|
case SIOCDELRT:
|
||||||
err = copy_from_user(&rtmsg, arg,
|
err = ip6_route_del(&cfg, NULL);
|
||||||
sizeof(struct in6_rtmsg));
|
break;
|
||||||
if (err)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
rtmsg_to_fib6_config(net, &rtmsg, &cfg);
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
switch (cmd) {
|
|
||||||
case SIOCADDRT:
|
|
||||||
err = ip6_route_add(&cfg, GFP_KERNEL, NULL);
|
|
||||||
break;
|
|
||||||
case SIOCDELRT:
|
|
||||||
err = ip6_route_del(&cfg, NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = -EINVAL;
|
|
||||||
}
|
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
rtnl_unlock();
|
||||||
return -EINVAL;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user