diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 201 |
1 files changed, 85 insertions, 116 deletions
diff --git a/net/socket.c b/net/socket.c index fe20c319a0bb..a2c33a4dc7ba 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -113,7 +113,6 @@ unsigned int sysctl_net_busy_read __read_mostly; | |||
113 | unsigned int sysctl_net_busy_poll __read_mostly; | 113 | unsigned int sysctl_net_busy_poll __read_mostly; |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare); | ||
117 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | 116 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
118 | unsigned long nr_segs, loff_t pos); | 117 | unsigned long nr_segs, loff_t pos); |
119 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | 118 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
@@ -151,7 +150,6 @@ static const struct file_operations socket_file_ops = { | |||
151 | .compat_ioctl = compat_sock_ioctl, | 150 | .compat_ioctl = compat_sock_ioctl, |
152 | #endif | 151 | #endif |
153 | .mmap = sock_mmap, | 152 | .mmap = sock_mmap, |
154 | .open = sock_no_open, /* special open code to disallow open via /proc */ | ||
155 | .release = sock_close, | 153 | .release = sock_close, |
156 | .fasync = sock_fasync, | 154 | .fasync = sock_fasync, |
157 | .sendpage = sock_sendpage, | 155 | .sendpage = sock_sendpage, |
@@ -374,7 +372,6 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) | |||
374 | path.mnt = mntget(sock_mnt); | 372 | path.mnt = mntget(sock_mnt); |
375 | 373 | ||
376 | d_instantiate(path.dentry, SOCK_INODE(sock)); | 374 | d_instantiate(path.dentry, SOCK_INODE(sock)); |
377 | SOCK_INODE(sock)->i_fop = &socket_file_ops; | ||
378 | 375 | ||
379 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, | 376 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, |
380 | &socket_file_ops); | 377 | &socket_file_ops); |
@@ -559,23 +556,6 @@ static struct socket *sock_alloc(void) | |||
559 | return sock; | 556 | return sock; |
560 | } | 557 | } |
561 | 558 | ||
562 | /* | ||
563 | * In theory you can't get an open on this inode, but /proc provides | ||
564 | * a back door. Remember to keep it shut otherwise you'll let the | ||
565 | * creepy crawlies in. | ||
566 | */ | ||
567 | |||
568 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare) | ||
569 | { | ||
570 | return -ENXIO; | ||
571 | } | ||
572 | |||
573 | const struct file_operations bad_sock_fops = { | ||
574 | .owner = THIS_MODULE, | ||
575 | .open = sock_no_open, | ||
576 | .llseek = noop_llseek, | ||
577 | }; | ||
578 | |||
579 | /** | 559 | /** |
580 | * sock_release - close a socket | 560 | * sock_release - close a socket |
581 | * @sock: socket to close | 561 | * @sock: socket to close |
@@ -651,7 +631,8 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
651 | return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size); | 631 | return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size); |
652 | } | 632 | } |
653 | 633 | ||
654 | int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | 634 | static int do_sock_sendmsg(struct socket *sock, struct msghdr *msg, |
635 | size_t size, bool nosec) | ||
655 | { | 636 | { |
656 | struct kiocb iocb; | 637 | struct kiocb iocb; |
657 | struct sock_iocb siocb; | 638 | struct sock_iocb siocb; |
@@ -659,25 +640,22 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
659 | 640 | ||
660 | init_sync_kiocb(&iocb, NULL); | 641 | init_sync_kiocb(&iocb, NULL); |
661 | iocb.private = &siocb; | 642 | iocb.private = &siocb; |
662 | ret = __sock_sendmsg(&iocb, sock, msg, size); | 643 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : |
644 | __sock_sendmsg(&iocb, sock, msg, size); | ||
663 | if (-EIOCBQUEUED == ret) | 645 | if (-EIOCBQUEUED == ret) |
664 | ret = wait_on_sync_kiocb(&iocb); | 646 | ret = wait_on_sync_kiocb(&iocb); |
665 | return ret; | 647 | return ret; |
666 | } | 648 | } |
649 | |||
650 | int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | ||
651 | { | ||
652 | return do_sock_sendmsg(sock, msg, size, false); | ||
653 | } | ||
667 | EXPORT_SYMBOL(sock_sendmsg); | 654 | EXPORT_SYMBOL(sock_sendmsg); |
668 | 655 | ||
669 | static int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size) | 656 | static int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size) |
670 | { | 657 | { |
671 | struct kiocb iocb; | 658 | return do_sock_sendmsg(sock, msg, size, true); |
672 | struct sock_iocb siocb; | ||
673 | int ret; | ||
674 | |||
675 | init_sync_kiocb(&iocb, NULL); | ||
676 | iocb.private = &siocb; | ||
677 | ret = __sock_sendmsg_nosec(&iocb, sock, msg, size); | ||
678 | if (-EIOCBQUEUED == ret) | ||
679 | ret = wait_on_sync_kiocb(&iocb); | ||
680 | return ret; | ||
681 | } | 659 | } |
682 | 660 | ||
683 | int kernel_sendmsg(struct socket *sock, struct msghdr *msg, | 661 | int kernel_sendmsg(struct socket *sock, struct msghdr *msg, |
@@ -691,8 +669,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, | |||
691 | * the following is safe, since for compiler definitions of kvec and | 669 | * the following is safe, since for compiler definitions of kvec and |
692 | * iovec are identical, yielding the same in-core layout and alignment | 670 | * iovec are identical, yielding the same in-core layout and alignment |
693 | */ | 671 | */ |
694 | msg->msg_iov = (struct iovec *)vec; | 672 | iov_iter_init(&msg->msg_iter, WRITE, (struct iovec *)vec, num, size); |
695 | msg->msg_iovlen = num; | ||
696 | result = sock_sendmsg(sock, msg, size); | 673 | result = sock_sendmsg(sock, msg, size); |
697 | set_fs(oldfs); | 674 | set_fs(oldfs); |
698 | return result; | 675 | return result; |
@@ -855,7 +832,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, | |||
855 | * the following is safe, since for compiler definitions of kvec and | 832 | * the following is safe, since for compiler definitions of kvec and |
856 | * iovec are identical, yielding the same in-core layout and alignment | 833 | * iovec are identical, yielding the same in-core layout and alignment |
857 | */ | 834 | */ |
858 | msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num; | 835 | iov_iter_init(&msg->msg_iter, READ, (struct iovec *)vec, num, size); |
859 | result = sock_recvmsg(sock, msg, size, flags); | 836 | result = sock_recvmsg(sock, msg, size, flags); |
860 | set_fs(oldfs); | 837 | set_fs(oldfs); |
861 | return result; | 838 | return result; |
@@ -915,8 +892,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | |||
915 | msg->msg_namelen = 0; | 892 | msg->msg_namelen = 0; |
916 | msg->msg_control = NULL; | 893 | msg->msg_control = NULL; |
917 | msg->msg_controllen = 0; | 894 | msg->msg_controllen = 0; |
918 | msg->msg_iov = (struct iovec *)iov; | 895 | iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size); |
919 | msg->msg_iovlen = nr_segs; | ||
920 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | 896 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; |
921 | 897 | ||
922 | return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); | 898 | return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); |
@@ -955,8 +931,7 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | |||
955 | msg->msg_namelen = 0; | 931 | msg->msg_namelen = 0; |
956 | msg->msg_control = NULL; | 932 | msg->msg_control = NULL; |
957 | msg->msg_controllen = 0; | 933 | msg->msg_controllen = 0; |
958 | msg->msg_iov = (struct iovec *)iov; | 934 | iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size); |
959 | msg->msg_iovlen = nr_segs; | ||
960 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | 935 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; |
961 | if (sock->type == SOCK_SEQPACKET) | 936 | if (sock->type == SOCK_SEQPACKET) |
962 | msg->msg_flags |= MSG_EOR; | 937 | msg->msg_flags |= MSG_EOR; |
@@ -1800,8 +1775,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, | |||
1800 | iov.iov_base = buff; | 1775 | iov.iov_base = buff; |
1801 | iov.iov_len = len; | 1776 | iov.iov_len = len; |
1802 | msg.msg_name = NULL; | 1777 | msg.msg_name = NULL; |
1803 | msg.msg_iov = &iov; | 1778 | iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len); |
1804 | msg.msg_iovlen = 1; | ||
1805 | msg.msg_control = NULL; | 1779 | msg.msg_control = NULL; |
1806 | msg.msg_controllen = 0; | 1780 | msg.msg_controllen = 0; |
1807 | msg.msg_namelen = 0; | 1781 | msg.msg_namelen = 0; |
@@ -1858,10 +1832,9 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
1858 | 1832 | ||
1859 | msg.msg_control = NULL; | 1833 | msg.msg_control = NULL; |
1860 | msg.msg_controllen = 0; | 1834 | msg.msg_controllen = 0; |
1861 | msg.msg_iovlen = 1; | ||
1862 | msg.msg_iov = &iov; | ||
1863 | iov.iov_len = size; | 1835 | iov.iov_len = size; |
1864 | iov.iov_base = ubuf; | 1836 | iov.iov_base = ubuf; |
1837 | iov_iter_init(&msg.msg_iter, READ, &iov, 1, size); | ||
1865 | /* Save some cycles and don't copy the address if not needed */ | 1838 | /* Save some cycles and don't copy the address if not needed */ |
1866 | msg.msg_name = addr ? (struct sockaddr *)&address : NULL; | 1839 | msg.msg_name = addr ? (struct sockaddr *)&address : NULL; |
1867 | /* We assume all kernel code knows the size of sockaddr_storage */ | 1840 | /* We assume all kernel code knows the size of sockaddr_storage */ |
@@ -1988,13 +1961,27 @@ struct used_address { | |||
1988 | unsigned int name_len; | 1961 | unsigned int name_len; |
1989 | }; | 1962 | }; |
1990 | 1963 | ||
1991 | static int copy_msghdr_from_user(struct msghdr *kmsg, | 1964 | static ssize_t copy_msghdr_from_user(struct msghdr *kmsg, |
1992 | struct msghdr __user *umsg) | 1965 | struct user_msghdr __user *umsg, |
1966 | struct sockaddr __user **save_addr, | ||
1967 | struct iovec **iov) | ||
1993 | { | 1968 | { |
1994 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) | 1969 | struct sockaddr __user *uaddr; |
1970 | struct iovec __user *uiov; | ||
1971 | size_t nr_segs; | ||
1972 | ssize_t err; | ||
1973 | |||
1974 | if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || | ||
1975 | __get_user(uaddr, &umsg->msg_name) || | ||
1976 | __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || | ||
1977 | __get_user(uiov, &umsg->msg_iov) || | ||
1978 | __get_user(nr_segs, &umsg->msg_iovlen) || | ||
1979 | __get_user(kmsg->msg_control, &umsg->msg_control) || | ||
1980 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || | ||
1981 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) | ||
1995 | return -EFAULT; | 1982 | return -EFAULT; |
1996 | 1983 | ||
1997 | if (kmsg->msg_name == NULL) | 1984 | if (!uaddr) |
1998 | kmsg->msg_namelen = 0; | 1985 | kmsg->msg_namelen = 0; |
1999 | 1986 | ||
2000 | if (kmsg->msg_namelen < 0) | 1987 | if (kmsg->msg_namelen < 0) |
@@ -2002,10 +1989,35 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, | |||
2002 | 1989 | ||
2003 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | 1990 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
2004 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); | 1991 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
2005 | return 0; | 1992 | |
1993 | if (save_addr) | ||
1994 | *save_addr = uaddr; | ||
1995 | |||
1996 | if (uaddr && kmsg->msg_namelen) { | ||
1997 | if (!save_addr) { | ||
1998 | err = move_addr_to_kernel(uaddr, kmsg->msg_namelen, | ||
1999 | kmsg->msg_name); | ||
2000 | if (err < 0) | ||
2001 | return err; | ||
2002 | } | ||
2003 | } else { | ||
2004 | kmsg->msg_name = NULL; | ||
2005 | kmsg->msg_namelen = 0; | ||
2006 | } | ||
2007 | |||
2008 | if (nr_segs > UIO_MAXIOV) | ||
2009 | return -EMSGSIZE; | ||
2010 | |||
2011 | err = rw_copy_check_uvector(save_addr ? READ : WRITE, | ||
2012 | uiov, nr_segs, | ||
2013 | UIO_FASTIOV, *iov, iov); | ||
2014 | if (err >= 0) | ||
2015 | iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE, | ||
2016 | *iov, nr_segs, err); | ||
2017 | return err; | ||
2006 | } | 2018 | } |
2007 | 2019 | ||
2008 | static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 2020 | static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, |
2009 | struct msghdr *msg_sys, unsigned int flags, | 2021 | struct msghdr *msg_sys, unsigned int flags, |
2010 | struct used_address *used_address) | 2022 | struct used_address *used_address) |
2011 | { | 2023 | { |
@@ -2017,34 +2029,15 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
2017 | __attribute__ ((aligned(sizeof(__kernel_size_t)))); | 2029 | __attribute__ ((aligned(sizeof(__kernel_size_t)))); |
2018 | /* 20 is size of ipv6_pktinfo */ | 2030 | /* 20 is size of ipv6_pktinfo */ |
2019 | unsigned char *ctl_buf = ctl; | 2031 | unsigned char *ctl_buf = ctl; |
2020 | int err, ctl_len, total_len; | 2032 | int ctl_len, total_len; |
2021 | 2033 | ssize_t err; | |
2022 | err = -EFAULT; | ||
2023 | if (MSG_CMSG_COMPAT & flags) { | ||
2024 | if (get_compat_msghdr(msg_sys, msg_compat)) | ||
2025 | return -EFAULT; | ||
2026 | } else { | ||
2027 | err = copy_msghdr_from_user(msg_sys, msg); | ||
2028 | if (err) | ||
2029 | return err; | ||
2030 | } | ||
2031 | 2034 | ||
2032 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { | 2035 | msg_sys->msg_name = &address; |
2033 | err = -EMSGSIZE; | ||
2034 | if (msg_sys->msg_iovlen > UIO_MAXIOV) | ||
2035 | goto out; | ||
2036 | err = -ENOMEM; | ||
2037 | iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec), | ||
2038 | GFP_KERNEL); | ||
2039 | if (!iov) | ||
2040 | goto out; | ||
2041 | } | ||
2042 | 2036 | ||
2043 | /* This will also move the address data into kernel space */ | 2037 | if (MSG_CMSG_COMPAT & flags) |
2044 | if (MSG_CMSG_COMPAT & flags) { | 2038 | err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov); |
2045 | err = verify_compat_iovec(msg_sys, iov, &address, VERIFY_READ); | 2039 | else |
2046 | } else | 2040 | err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov); |
2047 | err = verify_iovec(msg_sys, iov, &address, VERIFY_READ); | ||
2048 | if (err < 0) | 2041 | if (err < 0) |
2049 | goto out_freeiov; | 2042 | goto out_freeiov; |
2050 | total_len = err; | 2043 | total_len = err; |
@@ -2115,7 +2108,6 @@ out_freectl: | |||
2115 | out_freeiov: | 2108 | out_freeiov: |
2116 | if (iov != iovstack) | 2109 | if (iov != iovstack) |
2117 | kfree(iov); | 2110 | kfree(iov); |
2118 | out: | ||
2119 | return err; | 2111 | return err; |
2120 | } | 2112 | } |
2121 | 2113 | ||
@@ -2123,7 +2115,7 @@ out: | |||
2123 | * BSD sendmsg interface | 2115 | * BSD sendmsg interface |
2124 | */ | 2116 | */ |
2125 | 2117 | ||
2126 | long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | 2118 | long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags) |
2127 | { | 2119 | { |
2128 | int fput_needed, err; | 2120 | int fput_needed, err; |
2129 | struct msghdr msg_sys; | 2121 | struct msghdr msg_sys; |
@@ -2140,7 +2132,7 @@ out: | |||
2140 | return err; | 2132 | return err; |
2141 | } | 2133 | } |
2142 | 2134 | ||
2143 | SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) | 2135 | SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) |
2144 | { | 2136 | { |
2145 | if (flags & MSG_CMSG_COMPAT) | 2137 | if (flags & MSG_CMSG_COMPAT) |
2146 | return -EINVAL; | 2138 | return -EINVAL; |
@@ -2177,7 +2169,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2177 | 2169 | ||
2178 | while (datagrams < vlen) { | 2170 | while (datagrams < vlen) { |
2179 | if (MSG_CMSG_COMPAT & flags) { | 2171 | if (MSG_CMSG_COMPAT & flags) { |
2180 | err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, | 2172 | err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry, |
2181 | &msg_sys, flags, &used_address); | 2173 | &msg_sys, flags, &used_address); |
2182 | if (err < 0) | 2174 | if (err < 0) |
2183 | break; | 2175 | break; |
@@ -2185,7 +2177,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2185 | ++compat_entry; | 2177 | ++compat_entry; |
2186 | } else { | 2178 | } else { |
2187 | err = ___sys_sendmsg(sock, | 2179 | err = ___sys_sendmsg(sock, |
2188 | (struct msghdr __user *)entry, | 2180 | (struct user_msghdr __user *)entry, |
2189 | &msg_sys, flags, &used_address); | 2181 | &msg_sys, flags, &used_address); |
2190 | if (err < 0) | 2182 | if (err < 0) |
2191 | break; | 2183 | break; |
@@ -2215,7 +2207,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, | |||
2215 | return __sys_sendmmsg(fd, mmsg, vlen, flags); | 2207 | return __sys_sendmmsg(fd, mmsg, vlen, flags); |
2216 | } | 2208 | } |
2217 | 2209 | ||
2218 | static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | 2210 | static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, |
2219 | struct msghdr *msg_sys, unsigned int flags, int nosec) | 2211 | struct msghdr *msg_sys, unsigned int flags, int nosec) |
2220 | { | 2212 | { |
2221 | struct compat_msghdr __user *msg_compat = | 2213 | struct compat_msghdr __user *msg_compat = |
@@ -2223,44 +2215,22 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
2223 | struct iovec iovstack[UIO_FASTIOV]; | 2215 | struct iovec iovstack[UIO_FASTIOV]; |
2224 | struct iovec *iov = iovstack; | 2216 | struct iovec *iov = iovstack; |
2225 | unsigned long cmsg_ptr; | 2217 | unsigned long cmsg_ptr; |
2226 | int err, total_len, len; | 2218 | int total_len, len; |
2219 | ssize_t err; | ||
2227 | 2220 | ||
2228 | /* kernel mode address */ | 2221 | /* kernel mode address */ |
2229 | struct sockaddr_storage addr; | 2222 | struct sockaddr_storage addr; |
2230 | 2223 | ||
2231 | /* user mode address pointers */ | 2224 | /* user mode address pointers */ |
2232 | struct sockaddr __user *uaddr; | 2225 | struct sockaddr __user *uaddr; |
2233 | int __user *uaddr_len; | 2226 | int __user *uaddr_len = COMPAT_NAMELEN(msg); |
2234 | |||
2235 | if (MSG_CMSG_COMPAT & flags) { | ||
2236 | if (get_compat_msghdr(msg_sys, msg_compat)) | ||
2237 | return -EFAULT; | ||
2238 | } else { | ||
2239 | err = copy_msghdr_from_user(msg_sys, msg); | ||
2240 | if (err) | ||
2241 | return err; | ||
2242 | } | ||
2243 | 2227 | ||
2244 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { | 2228 | msg_sys->msg_name = &addr; |
2245 | err = -EMSGSIZE; | ||
2246 | if (msg_sys->msg_iovlen > UIO_MAXIOV) | ||
2247 | goto out; | ||
2248 | err = -ENOMEM; | ||
2249 | iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec), | ||
2250 | GFP_KERNEL); | ||
2251 | if (!iov) | ||
2252 | goto out; | ||
2253 | } | ||
2254 | 2229 | ||
2255 | /* Save the user-mode address (verify_iovec will change the | ||
2256 | * kernel msghdr to use the kernel address space) | ||
2257 | */ | ||
2258 | uaddr = (__force void __user *)msg_sys->msg_name; | ||
2259 | uaddr_len = COMPAT_NAMELEN(msg); | ||
2260 | if (MSG_CMSG_COMPAT & flags) | 2230 | if (MSG_CMSG_COMPAT & flags) |
2261 | err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); | 2231 | err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov); |
2262 | else | 2232 | else |
2263 | err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); | 2233 | err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov); |
2264 | if (err < 0) | 2234 | if (err < 0) |
2265 | goto out_freeiov; | 2235 | goto out_freeiov; |
2266 | total_len = err; | 2236 | total_len = err; |
@@ -2303,7 +2273,6 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
2303 | out_freeiov: | 2273 | out_freeiov: |
2304 | if (iov != iovstack) | 2274 | if (iov != iovstack) |
2305 | kfree(iov); | 2275 | kfree(iov); |
2306 | out: | ||
2307 | return err; | 2276 | return err; |
2308 | } | 2277 | } |
2309 | 2278 | ||
@@ -2311,7 +2280,7 @@ out: | |||
2311 | * BSD recvmsg interface | 2280 | * BSD recvmsg interface |
2312 | */ | 2281 | */ |
2313 | 2282 | ||
2314 | long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) | 2283 | long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags) |
2315 | { | 2284 | { |
2316 | int fput_needed, err; | 2285 | int fput_needed, err; |
2317 | struct msghdr msg_sys; | 2286 | struct msghdr msg_sys; |
@@ -2328,7 +2297,7 @@ out: | |||
2328 | return err; | 2297 | return err; |
2329 | } | 2298 | } |
2330 | 2299 | ||
2331 | SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, | 2300 | SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, |
2332 | unsigned int, flags) | 2301 | unsigned int, flags) |
2333 | { | 2302 | { |
2334 | if (flags & MSG_CMSG_COMPAT) | 2303 | if (flags & MSG_CMSG_COMPAT) |
@@ -2373,7 +2342,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. | 2342 | * No need to ask LSM for more than the first datagram. |
2374 | */ | 2343 | */ |
2375 | if (MSG_CMSG_COMPAT & flags) { | 2344 | if (MSG_CMSG_COMPAT & flags) { |
2376 | err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, | 2345 | err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry, |
2377 | &msg_sys, flags & ~MSG_WAITFORONE, | 2346 | &msg_sys, flags & ~MSG_WAITFORONE, |
2378 | datagrams); | 2347 | datagrams); |
2379 | if (err < 0) | 2348 | if (err < 0) |
@@ -2382,7 +2351,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2382 | ++compat_entry; | 2351 | ++compat_entry; |
2383 | } else { | 2352 | } else { |
2384 | err = ___sys_recvmsg(sock, | 2353 | err = ___sys_recvmsg(sock, |
2385 | (struct msghdr __user *)entry, | 2354 | (struct user_msghdr __user *)entry, |
2386 | &msg_sys, flags & ~MSG_WAITFORONE, | 2355 | &msg_sys, flags & ~MSG_WAITFORONE, |
2387 | datagrams); | 2356 | datagrams); |
2388 | if (err < 0) | 2357 | if (err < 0) |
@@ -2571,13 +2540,13 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) | |||
2571 | (int __user *)a[4]); | 2540 | (int __user *)a[4]); |
2572 | break; | 2541 | break; |
2573 | case SYS_SENDMSG: | 2542 | case SYS_SENDMSG: |
2574 | err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); | 2543 | err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]); |
2575 | break; | 2544 | break; |
2576 | case SYS_SENDMMSG: | 2545 | case SYS_SENDMMSG: |
2577 | err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); | 2546 | err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); |
2578 | break; | 2547 | break; |
2579 | case SYS_RECVMSG: | 2548 | case SYS_RECVMSG: |
2580 | err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); | 2549 | err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]); |
2581 | break; | 2550 | break; |
2582 | case SYS_RECVMMSG: | 2551 | case SYS_RECVMMSG: |
2583 | err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], | 2552 | err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], |