Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e1859fb authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 11e98029
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -1207,6 +1207,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
	struct net *net = sock_net(sk);
	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);
	if (mrt == NULL)
		return -ENOENT;
@@ -1219,11 +1223,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi

	switch (optname) {
	case MRT_INIT:
		if (sk->sk_type != SOCK_RAW ||
		    inet_sk(sk)->inet_num != IPPROTO_IGMP)
			return -EOPNOTSUPP;
		if (optlen != sizeof(int))
			return -ENOPROTOOPT;
			return -EINVAL;

		rtnl_lock();
		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:
	{
		int v;
		if (optlen != sizeof(v))
			return -EINVAL;
		if (get_user(v, (int __user *)optval))
			return -EFAULT;
		mrt->mroute_do_assert = (v) ? 1 : 0;
		mrt->mroute_do_assert = !!v;
		return 0;
	}
#ifdef CONFIG_IP_PIMSM
@@ -1294,9 +1297,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
	{
		int v;

		if (optlen != sizeof(v))
			return -EINVAL;
		if (get_user(v, (int __user *)optval))
			return -EFAULT;
		v = (v) ? 1 : 0;
		v = !!v;

		rtnl_lock();
		ret = 0;
@@ -1325,6 +1330,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
		} else {
			if (!ipmr_new_table(net, v))
				ret = -ENOMEM;
			else
				raw_sk(sk)->ipmr_table = v;
		}
		rtnl_unlock();
@@ -1351,6 +1357,10 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int
	struct net *net = sock_net(sk);
	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);
	if (mrt == NULL)
		return -ENOENT;