diff options
Diffstat (limited to 'net/compat.c')
| -rw-r--r-- | net/compat.c | 65 | 
1 files changed, 40 insertions, 25 deletions
diff --git a/net/compat.c b/net/compat.c index 6def90e0a11..73bf0e06f3d 100644 --- a/net/compat.c +++ b/net/compat.c @@ -219,8 +219,6 @@ Efault:  int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)  { -	struct compat_timeval ctv; -	struct compat_timespec cts[3];  	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;  	struct compat_cmsghdr cmhdr;  	int cmlen; @@ -230,24 +228,28 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat  		return 0; /* XXX: return error? check spec. */  	} -	if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { -		struct timeval *tv = (struct 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; -		int i; -		struct timespec *ts = (struct timespec *)data; -		for (i = 0; i < count; i++) { -			cts[i].tv_sec = ts[i].tv_sec; -			cts[i].tv_nsec = ts[i].tv_nsec; +	if (!COMPAT_USE_64BIT_TIME) { +		struct compat_timeval ctv; +		struct compat_timespec cts[3]; +		if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { +			struct timeval *tv = (struct 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; +			int i; +			struct timespec *ts = (struct timespec *)data; +			for (i = 0; i < count; i++) { +				cts[i].tv_sec = ts[i].tv_sec; +				cts[i].tv_nsec = ts[i].tv_nsec; +			} +			data = &cts; +			len = sizeof(cts[0]) * count;  		} -		data = &cts; -		len = sizeof(cts[0]) * count;  	}  	cmlen = CMSG_COMPAT_LEN(len); @@ -454,11 +456,15 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname,  int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)  { -	struct compat_timeval __user *ctv = -			(struct compat_timeval __user *) userstamp; -	int err = -ENOENT; +	struct compat_timeval __user *ctv; +	int err;  	struct timeval tv; +	if (COMPAT_USE_64BIT_TIME) +		return sock_get_timestamp(sk, userstamp); + +	ctv = (struct compat_timeval __user *) userstamp; +	err = -ENOENT;  	if (!sock_flag(sk, SOCK_TIMESTAMP))  		sock_enable_timestamp(sk, SOCK_TIMESTAMP);  	tv = ktime_to_timeval(sk->sk_stamp); @@ -478,11 +484,15 @@ EXPORT_SYMBOL(compat_sock_get_timestamp);  int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)  { -	struct compat_timespec __user *ctv = -			(struct compat_timespec __user *) userstamp; -	int err = -ENOENT; +	struct compat_timespec __user *ctv; +	int err;  	struct timespec ts; +	if (COMPAT_USE_64BIT_TIME) +		return sock_get_timestampns (sk, userstamp); + +	ctv = (struct compat_timespec __user *) userstamp; +	err = -ENOENT;  	if (!sock_flag(sk, SOCK_TIMESTAMP))  		sock_enable_timestamp(sk, SOCK_TIMESTAMP);  	ts = ktime_to_timespec(sk->sk_stamp); @@ -767,6 +777,11 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,  	int datagrams;  	struct timespec ktspec; +	if (COMPAT_USE_64BIT_TIME) +		return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, +				      flags | MSG_CMSG_COMPAT, +				      (struct timespec *) timeout); +  	if (timeout == NULL)  		return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,  				      flags | MSG_CMSG_COMPAT, NULL);  |