Merge tag 'selinux-pr-20210830' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / net / socket.c
index 0b2dad3..532fff5 100644 (file)
@@ -1722,32 +1722,22 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
        return __sys_listen(fd, backlog);
 }
 
-int __sys_accept4_file(struct file *file, unsigned file_flags,
+struct file *do_accept(struct file *file, unsigned file_flags,
                       struct sockaddr __user *upeer_sockaddr,
-                      int __user *upeer_addrlen, int flags,
-                      unsigned long nofile)
+                      int __user *upeer_addrlen, int flags)
 {
        struct socket *sock, *newsock;
        struct file *newfile;
-       int err, len, newfd;
+       int err, len;
        struct sockaddr_storage address;
 
-       if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
-               return -EINVAL;
-
-       if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
-               flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
-
        sock = sock_from_file(file);
-       if (!sock) {
-               err = -ENOTSOCK;
-               goto out;
-       }
+       if (!sock)
+               return ERR_PTR(-ENOTSOCK);
 
-       err = -ENFILE;
        newsock = sock_alloc();
        if (!newsock)
-               goto out;
+               return ERR_PTR(-ENFILE);
 
        newsock->type = sock->type;
        newsock->ops = sock->ops;
@@ -1758,18 +1748,9 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,
         */
        __module_get(newsock->ops->owner);
 
-       newfd = __get_unused_fd_flags(flags, nofile);
-       if (unlikely(newfd < 0)) {
-               err = newfd;
-               sock_release(newsock);
-               goto out;
-       }
        newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
-       if (IS_ERR(newfile)) {
-               err = PTR_ERR(newfile);
-               put_unused_fd(newfd);
-               goto out;
-       }
+       if (IS_ERR(newfile))
+               return newfile;
 
        err = security_socket_accept(sock, newsock);
        if (err)
@@ -1794,16 +1775,38 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,
        }
 
        /* File flags are not inherited via accept() unlike another OSes. */
-
-       fd_install(newfd, newfile);
-       err = newfd;
-out:
-       return err;
+       return newfile;
 out_fd:
        fput(newfile);
-       put_unused_fd(newfd);
-       goto out;
+       return ERR_PTR(err);
+}
+
+int __sys_accept4_file(struct file *file, unsigned file_flags,
+                      struct sockaddr __user *upeer_sockaddr,
+                      int __user *upeer_addrlen, int flags,
+                      unsigned long nofile)
+{
+       struct file *newfile;
+       int newfd;
 
+       if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
+               return -EINVAL;
+
+       if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
+               flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
+
+       newfd = __get_unused_fd_flags(flags, nofile);
+       if (unlikely(newfd < 0))
+               return newfd;
+
+       newfile = do_accept(file, file_flags, upeer_sockaddr, upeer_addrlen,
+                           flags);
+       if (IS_ERR(newfile)) {
+               put_unused_fd(newfd);
+               return PTR_ERR(newfile);
+       }
+       fd_install(newfd, newfile);
+       return newfd;
 }
 
 /*