diff options
Diffstat (limited to 'net/compat.c')
| -rw-r--r-- | net/compat.c | 94 | 
1 files changed, 17 insertions, 77 deletions
diff --git a/net/compat.c b/net/compat.c index 959d1c51826d..eeea5eb71639 100644 --- a/net/compat.c +++ b/net/compat.c @@ -209,8 +209,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat  {  	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;  	struct compat_cmsghdr cmhdr; -	struct compat_timeval ctv; -	struct compat_timespec cts[3]; +	struct old_timeval32 ctv; +	struct old_timespec32 cts[3];  	int cmlen;  	if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) { @@ -219,16 +219,16 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat  	}  	if (!COMPAT_USE_64BIT_TIME) { -		if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { -			struct timeval *tv = (struct timeval *)data; +		if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) { +			struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;  			ctv.tv_sec = tv->tv_sec;  			ctv.tv_usec = tv->tv_usec;  			data = &ctv;  			len = sizeof(ctv);  		}  		if (level == SOL_SOCKET && -		    (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) { -			int count = type == SCM_TIMESTAMPNS ? 1 : 3; +		    (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) { +			int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;  			int i;  			struct timespec *ts = (struct timespec *)data;  			for (i = 0; i < count; i++) { @@ -348,28 +348,6 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,  			      sizeof(struct sock_fprog));  } -static int do_set_sock_timeout(struct socket *sock, int level, -		int optname, char __user *optval, unsigned int optlen) -{ -	struct compat_timeval __user *up = (struct compat_timeval __user *)optval; -	struct timeval ktime; -	mm_segment_t old_fs; -	int err; - -	if (optlen < sizeof(*up)) -		return -EINVAL; -	if (!access_ok(up, sizeof(*up)) || -	    __get_user(ktime.tv_sec, &up->tv_sec) || -	    __get_user(ktime.tv_usec, &up->tv_usec)) -		return -EFAULT; -	old_fs = get_fs(); -	set_fs(KERNEL_DS); -	err = sock_setsockopt(sock, level, optname, (char *)&ktime, sizeof(ktime)); -	set_fs(old_fs); - -	return err; -} -  static int compat_sock_setsockopt(struct socket *sock, int level, int optname,  				char __user *optval, unsigned int optlen)  { @@ -377,10 +355,6 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname,  	    optname == SO_ATTACH_REUSEPORT_CBPF)  		return do_set_attach_filter(sock, level, optname,  					    optval, optlen); -	if (!COMPAT_USE_64BIT_TIME && -	    (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) -		return do_set_sock_timeout(sock, level, optname, optval, optlen); -  	return sock_setsockopt(sock, level, optname, optval, optlen);  } @@ -388,8 +362,12 @@ static int __compat_sys_setsockopt(int fd, int level, int optname,  				   char __user *optval, unsigned int optlen)  {  	int err; -	struct socket *sock = sockfd_lookup(fd, &err); +	struct socket *sock; + +	if (optlen > INT_MAX) +		return -EINVAL; +	sock = sockfd_lookup(fd, &err);  	if (sock) {  		err = security_socket_setsockopt(sock, level, optname);  		if (err) { @@ -417,44 +395,6 @@ COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,  	return __compat_sys_setsockopt(fd, level, optname, optval, optlen);  } -static int do_get_sock_timeout(struct socket *sock, int level, int optname, -		char __user *optval, int __user *optlen) -{ -	struct compat_timeval __user *up; -	struct timeval ktime; -	mm_segment_t old_fs; -	int len, err; - -	up = (struct compat_timeval __user *) optval; -	if (get_user(len, optlen)) -		return -EFAULT; -	if (len < sizeof(*up)) -		return -EINVAL; -	len = sizeof(ktime); -	old_fs = get_fs(); -	set_fs(KERNEL_DS); -	err = sock_getsockopt(sock, level, optname, (char *) &ktime, &len); -	set_fs(old_fs); - -	if (!err) { -		if (put_user(sizeof(*up), optlen) || -		    !access_ok(up, sizeof(*up)) || -		    __put_user(ktime.tv_sec, &up->tv_sec) || -		    __put_user(ktime.tv_usec, &up->tv_usec)) -			err = -EFAULT; -	} -	return err; -} - -static int compat_sock_getsockopt(struct socket *sock, int level, int optname, -				char __user *optval, int __user *optlen) -{ -	if (!COMPAT_USE_64BIT_TIME && -	    (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) -		return do_get_sock_timeout(sock, level, optname, optval, optlen); -	return sock_getsockopt(sock, level, optname, optval, optlen); -} -  int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)  {  	struct compat_timeval __user *ctv; @@ -527,7 +467,7 @@ static int __compat_sys_getsockopt(int fd, int level, int optname,  		}  		if (level == SOL_SOCKET) -			err = compat_sock_getsockopt(sock, level, +			err = sock_getsockopt(sock, level,  					optname, optval, optlen);  		else if (sock->ops->compat_getsockopt)  			err = sock->ops->compat_getsockopt(sock, level, @@ -585,7 +525,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,  	case MCAST_JOIN_GROUP:  	case MCAST_LEAVE_GROUP:  	{ -		struct compat_group_req __user *gr32 = (void *)optval; +		struct compat_group_req __user *gr32 = (void __user *)optval;  		struct group_req __user *kgr =  			compat_alloc_user_space(sizeof(struct group_req));  		u32 interface; @@ -606,7 +546,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,  	case MCAST_BLOCK_SOURCE:  	case MCAST_UNBLOCK_SOURCE:  	{ -		struct compat_group_source_req __user *gsr32 = (void *)optval; +		struct compat_group_source_req __user *gsr32 = (void __user *)optval;  		struct group_source_req __user *kgsr = compat_alloc_user_space(  			sizeof(struct group_source_req));  		u32 interface; @@ -627,7 +567,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,  	}  	case MCAST_MSFILTER:  	{ -		struct compat_group_filter __user *gf32 = (void *)optval; +		struct compat_group_filter __user *gf32 = (void __user *)optval;  		struct group_filter __user *kgf;  		u32 interface, fmode, numsrc; @@ -665,7 +605,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname,  	char __user *optval, int __user *optlen,  	int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))  { -	struct compat_group_filter __user *gf32 = (void *)optval; +	struct compat_group_filter __user *gf32 = (void __user *)optval;  	struct group_filter __user *kgf;  	int __user	*koptlen;  	u32 interface, fmode, numsrc; @@ -822,7 +762,7 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg_time64, int, fd, struct compat_mmsghdr __user *,  }  #ifdef CONFIG_COMPAT_32BIT_TIME -COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, +COMPAT_SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct compat_mmsghdr __user *, mmsg,  		       unsigned int, vlen, unsigned int, flags,  		       struct old_timespec32 __user *, timeout)  {  |