mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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:
		
							parent
							
								
									11e980299f
								
							
						
					
					
						commit
						5e1859fbcc
					
				
					 1 changed files with 17 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -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,7 +1330,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
 | 
			
		|||
		} else {
 | 
			
		||||
			if (!ipmr_new_table(net, v))
 | 
			
		||||
				ret = -ENOMEM;
 | 
			
		||||
			raw_sk(sk)->ipmr_table = v;
 | 
			
		||||
			else
 | 
			
		||||
				raw_sk(sk)->ipmr_table = v;
 | 
			
		||||
		}
 | 
			
		||||
		rtnl_unlock();
 | 
			
		||||
		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 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue