net: ravb: Keep reverse order of operations in ravb_remove()
[platform/kernel/linux-starfive.git] / net / socket.c
index 00da9ce..04cba91 100644 (file)
@@ -449,7 +449,9 @@ static struct file_system_type sock_fs_type = {
  *
  *     Returns the &file bound with @sock, implicitly storing it
  *     in sock->file. If dname is %NULL, sets to "".
- *     On failure the return is a ERR pointer (see linux/err.h).
+ *
+ *     On failure @sock is released, and an ERR pointer is returned.
+ *
  *     This function uses GFP_KERNEL internally.
  */
 
@@ -718,6 +720,14 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
        return ret;
 }
 
+static int __sock_sendmsg(struct socket *sock, struct msghdr *msg)
+{
+       int err = security_socket_sendmsg(sock, msg,
+                                         msg_data_left(msg));
+
+       return err ?: sock_sendmsg_nosec(sock, msg);
+}
+
 /**
  *     sock_sendmsg - send a message through @sock
  *     @sock: socket
@@ -728,10 +738,19 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
  */
 int sock_sendmsg(struct socket *sock, struct msghdr *msg)
 {
-       int err = security_socket_sendmsg(sock, msg,
-                                         msg_data_left(msg));
+       struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name;
+       struct sockaddr_storage address;
+       int ret;
 
-       return err ?: sock_sendmsg_nosec(sock, msg);
+       if (msg->msg_name) {
+               memcpy(&address, msg->msg_name, msg->msg_namelen);
+               msg->msg_name = &address;
+       }
+
+       ret = __sock_sendmsg(sock, msg);
+       msg->msg_name = save_addr;
+
+       return ret;
 }
 EXPORT_SYMBOL(sock_sendmsg);
 
@@ -750,7 +769,7 @@ EXPORT_SYMBOL(sock_sendmsg);
 int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size)
 {
-       iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
+       iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size);
        return sock_sendmsg(sock, msg);
 }
 EXPORT_SYMBOL(kernel_sendmsg);
@@ -776,7 +795,7 @@ int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
        if (!sock->ops->sendmsg_locked)
                return sock_no_sendmsg_locked(sk, msg, size);
 
-       iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
+       iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size);
 
        return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
 }
@@ -971,9 +990,12 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
 static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
                           struct sk_buff *skb)
 {
-       if (sock_flag(sk, SOCK_RCVMARK) && skb)
-               put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
-                        &skb->mark);
+       if (sock_flag(sk, SOCK_RCVMARK) && skb) {
+               /* We must use a bounce buffer for CONFIG_HARDENED_USERCOPY=y */
+               __u32 mark = skb->mark;
+
+               put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32), &mark);
+       }
 }
 
 void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
@@ -1034,7 +1056,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size, int flags)
 {
        msg->msg_control_is_user = false;
-       iov_iter_kvec(&msg->msg_iter, READ, vec, num, size);
+       iov_iter_kvec(&msg->msg_iter, ITER_DEST, vec, num, size);
        return sock_recvmsg(sock, msg, flags);
 }
 EXPORT_SYMBOL(kernel_recvmsg);
@@ -1105,7 +1127,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (sock->type == SOCK_SEQPACKET)
                msg.msg_flags |= MSG_EOR;
 
-       res = sock_sendmsg(sock, &msg);
+       res = __sock_sendmsg(sock, &msg);
        *from = msg.msg_iter;
        return res;
 }
@@ -1610,7 +1632,6 @@ static struct socket *__sys_socket_create(int family, int type, int protocol)
 struct file *__sys_socket_file(int family, int type, int protocol)
 {
        struct socket *sock;
-       struct file *file;
        int flags;
 
        sock = __sys_socket_create(family, type, protocol);
@@ -1621,11 +1642,7 @@ struct file *__sys_socket_file(int family, int type, int protocol)
        if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
                flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
 
-       file = sock_alloc_file(sock, flags, NULL);
-       if (IS_ERR(file))
-               sock_release(sock);
-
-       return file;
+       return sock_alloc_file(sock, flags, NULL);
 }
 
 int __sys_socket(int family, int type, int protocol)
@@ -2092,7 +2109,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
        struct iovec iov;
        int fput_needed;
 
-       err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
+       err = import_single_range(ITER_SOURCE, buff, len, &iov, &msg.msg_iter);
        if (unlikely(err))
                return err;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
@@ -2114,7 +2131,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        msg.msg_flags = flags;
-       err = sock_sendmsg(sock, &msg);
+       err = __sock_sendmsg(sock, &msg);
 
 out_put:
        fput_light(sock->file, fput_needed);
@@ -2157,7 +2174,7 @@ int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
        int err, err2;
        int fput_needed;
 
-       err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
+       err = import_single_range(ITER_DEST, ubuf, size, &iov, &msg.msg_iter);
        if (unlikely(err))
                return err;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
@@ -2417,7 +2434,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
        if (err)
                return err;
 
-       err = import_iovec(save_addr ? READ : WRITE,
+       err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE,
                            msg.msg_iov, msg.msg_iovlen,
                            UIO_FASTIOV, iov, &kmsg->msg_iter);
        return err < 0 ? err : 0;
@@ -2479,7 +2496,7 @@ static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
                err = sock_sendmsg_nosec(sock, msg_sys);
                goto out_freectl;
        }
-       err = sock_sendmsg(sock, msg_sys);
+       err = __sock_sendmsg(sock, msg_sys);
        /*
         * If this is sendmmsg() and sending to current destination address was
         * successful, remember it.
@@ -2890,7 +2907,7 @@ static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
                 * error to return on the next call or if the
                 * app asks about it using getsockopt(SO_ERROR).
                 */
-               sock->sk->sk_err = -err;
+               WRITE_ONCE(sock->sk->sk_err, -err);
        }
 out_put:
        fput_light(sock->file, fput_needed);
@@ -3437,7 +3454,11 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd,
 
 int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
 {
-       return sock->ops->bind(sock, addr, addrlen);
+       struct sockaddr_storage address;
+
+       memcpy(&address, addr, addrlen);
+
+       return sock->ops->bind(sock, (struct sockaddr *)&address, addrlen);
 }
 EXPORT_SYMBOL(kernel_bind);
 
@@ -3507,7 +3528,11 @@ EXPORT_SYMBOL(kernel_accept);
 int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
                   int flags)
 {
-       return sock->ops->connect(sock, addr, addrlen, flags);
+       struct sockaddr_storage address;
+
+       memcpy(&address, addr, addrlen);
+
+       return sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, flags);
 }
 EXPORT_SYMBOL(kernel_connect);