mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	net: clamp ->msg_namelen instead of returning an error
If kmsg->msg_namelen > sizeof(struct sockaddr_storage) then in the
original code that would lead to memory corruption in the kernel if you
had audit configured.  If you didn't have audit configured it was
harmless.
There are some programs such as beta versions of Ruby which use too
large of a buffer and returning an error code breaks them.  We should
clamp the ->msg_namelen value instead.
Fixes: 1661bf364a ("net: heap overflow in __audit_sockaddr()")
Reported-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Tested-by: Eric Wong <normalperson@yhbt.net>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									ec6f809ff6
								
							
						
					
					
						commit
						db31c55a6f
					
				
					 2 changed files with 2 additions and 2 deletions
				
			
		| 
						 | 
					@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
 | 
				
			||||||
	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
 | 
						    __get_user(kmsg->msg_flags, &umsg->msg_flags))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
 | 
						if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
 | 
				
			||||||
		return -EINVAL;
 | 
							kmsg->msg_namelen = sizeof(struct sockaddr_storage);
 | 
				
			||||||
	kmsg->msg_name = compat_ptr(tmp1);
 | 
						kmsg->msg_name = compat_ptr(tmp1);
 | 
				
			||||||
	kmsg->msg_iov = compat_ptr(tmp2);
 | 
						kmsg->msg_iov = compat_ptr(tmp2);
 | 
				
			||||||
	kmsg->msg_control = compat_ptr(tmp3);
 | 
						kmsg->msg_control = compat_ptr(tmp3);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1973,7 +1973,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
 | 
				
			||||||
	if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
 | 
						if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
 | 
						if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
 | 
				
			||||||
		return -EINVAL;
 | 
							kmsg->msg_namelen = sizeof(struct sockaddr_storage);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue