aboutsummaryrefslogtreecommitdiffstats
path: root/net/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/compat.c')
-rw-r--r--net/compat.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/net/compat.c b/net/compat.c
index a407c3addbae..e1a56ade803b 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -390,9 +390,6 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
390 int err; 390 int err;
391 struct socket *sock; 391 struct socket *sock;
392 392
393 if (optlen < 0)
394 return -EINVAL;
395
396 if ((sock = sockfd_lookup(fd, &err))!=NULL) 393 if ((sock = sockfd_lookup(fd, &err))!=NULL)
397 { 394 {
398 err = security_socket_setsockopt(sock,level,optname); 395 err = security_socket_setsockopt(sock,level,optname);
@@ -727,10 +724,10 @@ EXPORT_SYMBOL(compat_mc_getsockopt);
727 724
728/* Argument list sizes for compat_sys_socketcall */ 725/* Argument list sizes for compat_sys_socketcall */
729#define AL(x) ((x) * sizeof(u32)) 726#define AL(x) ((x) * sizeof(u32))
730static unsigned char nas[19]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 727static unsigned char nas[20]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
731 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 728 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
732 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), 729 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
733 AL(4)}; 730 AL(4),AL(5)};
734#undef AL 731#undef AL
735 732
736asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) 733asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags)
@@ -755,13 +752,40 @@ asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
755 return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen); 752 return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen);
756} 753}
757 754
755asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
756 unsigned vlen, unsigned int flags,
757 struct timespec __user *timeout)
758{
759 int datagrams;
760 struct timespec ktspec;
761 struct compat_timespec __user *utspec;
762
763 if (timeout == NULL)
764 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
765 flags | MSG_CMSG_COMPAT, NULL);
766
767 utspec = (struct compat_timespec __user *)timeout;
768 if (get_user(ktspec.tv_sec, &utspec->tv_sec) ||
769 get_user(ktspec.tv_nsec, &utspec->tv_nsec))
770 return -EFAULT;
771
772 datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
773 flags | MSG_CMSG_COMPAT, &ktspec);
774 if (datagrams > 0 &&
775 (put_user(ktspec.tv_sec, &utspec->tv_sec) ||
776 put_user(ktspec.tv_nsec, &utspec->tv_nsec)))
777 datagrams = -EFAULT;
778
779 return datagrams;
780}
781
758asmlinkage long compat_sys_socketcall(int call, u32 __user *args) 782asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
759{ 783{
760 int ret; 784 int ret;
761 u32 a[6]; 785 u32 a[6];
762 u32 a0, a1; 786 u32 a0, a1;
763 787
764 if (call < SYS_SOCKET || call > SYS_ACCEPT4) 788 if (call < SYS_SOCKET || call > SYS_RECVMMSG)
765 return -EINVAL; 789 return -EINVAL;
766 if (copy_from_user(a, args, nas[call])) 790 if (copy_from_user(a, args, nas[call]))
767 return -EFAULT; 791 return -EFAULT;
@@ -823,6 +847,10 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
823 case SYS_RECVMSG: 847 case SYS_RECVMSG:
824 ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); 848 ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
825 break; 849 break;
850 case SYS_RECVMMSG:
851 ret = compat_sys_recvmmsg(a0, compat_ptr(a1), a[2], a[3],
852 compat_ptr(a[4]));
853 break;
826 case SYS_ACCEPT4: 854 case SYS_ACCEPT4:
827 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); 855 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);
828 break; 856 break;