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:
parent
11e980299f
commit
5e1859fbcc
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue