aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c4
-rw-r--r--include/linux/socket.h16
-rw-r--r--include/linux/syscalls.h6
-rw-r--r--net/compat.c4
-rw-r--r--net/socket.c29
5 files changed, 36 insertions, 23 deletions
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index e90a3148f385..b83f3b7737fb 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -400,7 +400,7 @@ asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
400 return sys_sendto(fd, buff, len, flags, addr, addrlen); 400 return sys_sendto(fd, buff, len, flags, addr, addrlen);
401} 401}
402 402
403asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) 403asmlinkage long sys_oabi_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
404{ 404{
405 struct sockaddr __user *addr; 405 struct sockaddr __user *addr;
406 int msg_namelen; 406 int msg_namelen;
@@ -446,7 +446,7 @@ asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args)
446 break; 446 break;
447 case SYS_SENDMSG: 447 case SYS_SENDMSG:
448 if (copy_from_user(a, args, 3 * sizeof(long)) == 0) 448 if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
449 r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]); 449 r = sys_oabi_sendmsg(a[0], (struct user_msghdr __user *)a[1], a[2]);
450 break; 450 break;
451 default: 451 default:
452 r = sys_socketcall(call, args); 452 r = sys_socketcall(call, args);
diff --git a/include/linux/socket.h b/include/linux/socket.h
index bb9b83640070..51bd6668b80e 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -53,10 +53,20 @@ struct msghdr {
53 __kernel_size_t msg_controllen; /* ancillary data buffer length */ 53 __kernel_size_t msg_controllen; /* ancillary data buffer length */
54 unsigned int msg_flags; /* flags on received message */ 54 unsigned int msg_flags; /* flags on received message */
55}; 55};
56
57struct user_msghdr {
58 void __user *msg_name; /* ptr to socket address structure */
59 int msg_namelen; /* size of socket address structure */
60 struct iovec __user *msg_iov; /* scatter/gather array */
61 __kernel_size_t msg_iovlen; /* # elements in msg_iov */
62 void __user *msg_control; /* ancillary data */
63 __kernel_size_t msg_controllen; /* ancillary data buffer length */
64 unsigned int msg_flags; /* flags on received message */
65};
56 66
57/* For recvmmsg/sendmmsg */ 67/* For recvmmsg/sendmmsg */
58struct mmsghdr { 68struct mmsghdr {
59 struct msghdr msg_hdr; 69 struct user_msghdr msg_hdr;
60 unsigned int msg_len; 70 unsigned int msg_len;
61}; 71};
62 72
@@ -319,8 +329,8 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
319struct timespec; 329struct timespec;
320 330
321/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ 331/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
322extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); 332extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags);
323extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); 333extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags);
324extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, 334extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
325 unsigned int flags, struct timespec *timeout); 335 unsigned int flags, struct timespec *timeout);
326extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, 336extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index bda9b81357cc..c9afdc7a7f84 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -25,7 +25,7 @@ struct linux_dirent64;
25struct list_head; 25struct list_head;
26struct mmap_arg_struct; 26struct mmap_arg_struct;
27struct msgbuf; 27struct msgbuf;
28struct msghdr; 28struct user_msghdr;
29struct mmsghdr; 29struct mmsghdr;
30struct msqid_ds; 30struct msqid_ds;
31struct new_utsname; 31struct new_utsname;
@@ -601,13 +601,13 @@ asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *);
601asmlinkage long sys_send(int, void __user *, size_t, unsigned); 601asmlinkage long sys_send(int, void __user *, size_t, unsigned);
602asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, 602asmlinkage long sys_sendto(int, void __user *, size_t, unsigned,
603 struct sockaddr __user *, int); 603 struct sockaddr __user *, int);
604asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); 604asmlinkage long sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags);
605asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg, 605asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg,
606 unsigned int vlen, unsigned flags); 606 unsigned int vlen, unsigned flags);
607asmlinkage long sys_recv(int, void __user *, size_t, unsigned); 607asmlinkage long sys_recv(int, void __user *, size_t, unsigned);
608asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, 608asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned,
609 struct sockaddr __user *, int __user *); 609 struct sockaddr __user *, int __user *);
610asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); 610asmlinkage long sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags);
611asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, 611asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg,
612 unsigned int vlen, unsigned flags, 612 unsigned int vlen, unsigned flags,
613 struct timespec __user *timeout); 613 struct timespec __user *timeout);
diff --git a/net/compat.c b/net/compat.c
index bc8aeefddf3f..562e920b07f0 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -740,7 +740,7 @@ COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, uns
740{ 740{
741 if (flags & MSG_CMSG_COMPAT) 741 if (flags & MSG_CMSG_COMPAT)
742 return -EINVAL; 742 return -EINVAL;
743 return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 743 return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
744} 744}
745 745
746COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, 746COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
@@ -756,7 +756,7 @@ COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, uns
756{ 756{
757 if (flags & MSG_CMSG_COMPAT) 757 if (flags & MSG_CMSG_COMPAT)
758 return -EINVAL; 758 return -EINVAL;
759 return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 759 return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
760} 760}
761 761
762COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags) 762COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
diff --git a/net/socket.c b/net/socket.c
index fe20c319a0bb..0ae8147e3acc 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1989,8 +1989,11 @@ struct used_address {
1989}; 1989};
1990 1990
1991static int copy_msghdr_from_user(struct msghdr *kmsg, 1991static int copy_msghdr_from_user(struct msghdr *kmsg,
1992 struct msghdr __user *umsg) 1992 struct user_msghdr __user *umsg)
1993{ 1993{
1994 /* We are relying on the (currently) identical layouts. Once
1995 * the kernel-side changes, this place will need to be updated
1996 */
1994 if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) 1997 if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
1995 return -EFAULT; 1998 return -EFAULT;
1996 1999
@@ -2005,7 +2008,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
2005 return 0; 2008 return 0;
2006} 2009}
2007 2010
2008static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, 2011static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
2009 struct msghdr *msg_sys, unsigned int flags, 2012 struct msghdr *msg_sys, unsigned int flags,
2010 struct used_address *used_address) 2013 struct used_address *used_address)
2011{ 2014{
@@ -2123,7 +2126,7 @@ out:
2123 * BSD sendmsg interface 2126 * BSD sendmsg interface
2124 */ 2127 */
2125 2128
2126long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) 2129long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
2127{ 2130{
2128 int fput_needed, err; 2131 int fput_needed, err;
2129 struct msghdr msg_sys; 2132 struct msghdr msg_sys;
@@ -2140,7 +2143,7 @@ out:
2140 return err; 2143 return err;
2141} 2144}
2142 2145
2143SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) 2146SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
2144{ 2147{
2145 if (flags & MSG_CMSG_COMPAT) 2148 if (flags & MSG_CMSG_COMPAT)
2146 return -EINVAL; 2149 return -EINVAL;
@@ -2177,7 +2180,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2177 2180
2178 while (datagrams < vlen) { 2181 while (datagrams < vlen) {
2179 if (MSG_CMSG_COMPAT & flags) { 2182 if (MSG_CMSG_COMPAT & flags) {
2180 err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, 2183 err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
2181 &msg_sys, flags, &used_address); 2184 &msg_sys, flags, &used_address);
2182 if (err < 0) 2185 if (err < 0)
2183 break; 2186 break;
@@ -2185,7 +2188,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2185 ++compat_entry; 2188 ++compat_entry;
2186 } else { 2189 } else {
2187 err = ___sys_sendmsg(sock, 2190 err = ___sys_sendmsg(sock,
2188 (struct msghdr __user *)entry, 2191 (struct user_msghdr __user *)entry,
2189 &msg_sys, flags, &used_address); 2192 &msg_sys, flags, &used_address);
2190 if (err < 0) 2193 if (err < 0)
2191 break; 2194 break;
@@ -2215,7 +2218,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
2215 return __sys_sendmmsg(fd, mmsg, vlen, flags); 2218 return __sys_sendmmsg(fd, mmsg, vlen, flags);
2216} 2219}
2217 2220
2218static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, 2221static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
2219 struct msghdr *msg_sys, unsigned int flags, int nosec) 2222 struct msghdr *msg_sys, unsigned int flags, int nosec)
2220{ 2223{
2221 struct compat_msghdr __user *msg_compat = 2224 struct compat_msghdr __user *msg_compat =
@@ -2311,7 +2314,7 @@ out:
2311 * BSD recvmsg interface 2314 * BSD recvmsg interface
2312 */ 2315 */
2313 2316
2314long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) 2317long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
2315{ 2318{
2316 int fput_needed, err; 2319 int fput_needed, err;
2317 struct msghdr msg_sys; 2320 struct msghdr msg_sys;
@@ -2328,7 +2331,7 @@ out:
2328 return err; 2331 return err;
2329} 2332}
2330 2333
2331SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, 2334SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
2332 unsigned int, flags) 2335 unsigned int, flags)
2333{ 2336{
2334 if (flags & MSG_CMSG_COMPAT) 2337 if (flags & MSG_CMSG_COMPAT)
@@ -2373,7 +2376,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2373 * No need to ask LSM for more than the first datagram. 2376 * No need to ask LSM for more than the first datagram.
2374 */ 2377 */
2375 if (MSG_CMSG_COMPAT & flags) { 2378 if (MSG_CMSG_COMPAT & flags) {
2376 err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, 2379 err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
2377 &msg_sys, flags & ~MSG_WAITFORONE, 2380 &msg_sys, flags & ~MSG_WAITFORONE,
2378 datagrams); 2381 datagrams);
2379 if (err < 0) 2382 if (err < 0)
@@ -2382,7 +2385,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2382 ++compat_entry; 2385 ++compat_entry;
2383 } else { 2386 } else {
2384 err = ___sys_recvmsg(sock, 2387 err = ___sys_recvmsg(sock,
2385 (struct msghdr __user *)entry, 2388 (struct user_msghdr __user *)entry,
2386 &msg_sys, flags & ~MSG_WAITFORONE, 2389 &msg_sys, flags & ~MSG_WAITFORONE,
2387 datagrams); 2390 datagrams);
2388 if (err < 0) 2391 if (err < 0)
@@ -2571,13 +2574,13 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2571 (int __user *)a[4]); 2574 (int __user *)a[4]);
2572 break; 2575 break;
2573 case SYS_SENDMSG: 2576 case SYS_SENDMSG:
2574 err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); 2577 err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]);
2575 break; 2578 break;
2576 case SYS_SENDMMSG: 2579 case SYS_SENDMMSG:
2577 err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); 2580 err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
2578 break; 2581 break;
2579 case SYS_RECVMSG: 2582 case SYS_RECVMSG:
2580 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); 2583 err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]);
2581 break; 2584 break;
2582 case SYS_RECVMMSG: 2585 case SYS_RECVMMSG:
2583 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], 2586 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],