2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-13 15:53:56 +08:00

ipv4: ipmr: various fixes and cleanups

1) ip_mroute_setsockopt() & ip_mroute_getsockopt() should not
   access/set raw_sk(sk)->ipmr_table before making sure the socket
   is a raw socket, and protocol is IGMP

2) MRT_INIT should return -EINVAL if optlen != sizeof(int), not
   -ENOPROTOOPT

3) MRT_ASSERT & MRT_PIM should validate optlen

4) " (v) ? 1 : 0 " can be written as " !!v "

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric Dumazet 2012-11-25 06:41:45 +00:00 committed by David S. Miller
parent 11e980299f
commit 5e1859fbcc

View File

@ -1207,6 +1207,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct mr_table *mrt; struct mr_table *mrt;
if (sk->sk_type != SOCK_RAW ||
inet_sk(sk)->inet_num != IPPROTO_IGMP)
return -EOPNOTSUPP;
mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
if (mrt == NULL) if (mrt == NULL)
return -ENOENT; return -ENOENT;
@ -1219,11 +1223,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
switch (optname) { switch (optname) {
case MRT_INIT: case MRT_INIT:
if (sk->sk_type != SOCK_RAW ||
inet_sk(sk)->inet_num != IPPROTO_IGMP)
return -EOPNOTSUPP;
if (optlen != sizeof(int)) if (optlen != sizeof(int))
return -ENOPROTOOPT; return -EINVAL;
rtnl_lock(); rtnl_lock();
if (rtnl_dereference(mrt->mroute_sk)) { if (rtnl_dereference(mrt->mroute_sk)) {
@ -1284,9 +1285,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
case MRT_ASSERT: case MRT_ASSERT:
{ {
int v; int v;
if (optlen != sizeof(v))
return -EINVAL;
if (get_user(v, (int __user *)optval)) if (get_user(v, (int __user *)optval))
return -EFAULT; return -EFAULT;
mrt->mroute_do_assert = (v) ? 1 : 0; mrt->mroute_do_assert = !!v;
return 0; return 0;
} }
#ifdef CONFIG_IP_PIMSM #ifdef CONFIG_IP_PIMSM
@ -1294,9 +1297,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
{ {
int v; int v;
if (optlen != sizeof(v))
return -EINVAL;
if (get_user(v, (int __user *)optval)) if (get_user(v, (int __user *)optval))
return -EFAULT; return -EFAULT;
v = (v) ? 1 : 0; v = !!v;
rtnl_lock(); rtnl_lock();
ret = 0; ret = 0;
@ -1325,7 +1330,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
} else { } else {
if (!ipmr_new_table(net, v)) if (!ipmr_new_table(net, v))
ret = -ENOMEM; ret = -ENOMEM;
raw_sk(sk)->ipmr_table = v; else
raw_sk(sk)->ipmr_table = v;
} }
rtnl_unlock(); rtnl_unlock();
return ret; return ret;
@ -1351,6 +1357,10 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct mr_table *mrt; struct mr_table *mrt;
if (sk->sk_type != SOCK_RAW ||
inet_sk(sk)->inet_num != IPPROTO_IGMP)
return -EOPNOTSUPP;
mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
if (mrt == NULL) if (mrt == NULL)
return -ENOENT; return -ENOENT;