mirror of https://gitee.com/openkylin/linux.git
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);
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 in6_rtmsg rtmsg;
|
||||
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) {
|
||||
case SIOCADDRT: /* Add a route */
|
||||
case SIOCDELRT: /* Delete a route */
|
||||
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);
|
||||
|
||||
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;
|
||||
case SIOCADDRT:
|
||||
err = ip6_route_add(&cfg, GFP_KERNEL, NULL);
|
||||
break;
|
||||
case SIOCDELRT:
|
||||
err = ip6_route_del(&cfg, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue