diff --git a/net/socket.c b/net/socket.c index c05d86e63abf..4cb8662869f0 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1851,10 +1851,7 @@ int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; - /* - * reserve descriptors and make sure we won't fail - * to return them to userland. - */ + /* Reserve both descriptors before creating the sockets. */ fd1 = get_unused_fd_flags(flags); if (unlikely(fd1 < 0)) return fd1; @@ -1865,14 +1862,6 @@ int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) return fd2; } - err = put_user(fd1, &usockvec[0]); - if (err) - goto out; - - err = put_user(fd2, &usockvec[1]); - if (err) - goto out; - /* * Obtain the first socket and check if the underlying protocol * supports the socketpair call. @@ -1916,6 +1905,16 @@ int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) goto out; } + /* Publish the descriptors now that it shouldn't fail. */ + err = put_user(fd1, &usockvec[0]); + if (!err) + err = put_user(fd2, &usockvec[1]); + if (err) { + fput(newfile2); + fput(newfile1); + goto out; + } + audit_fd_pair(fd1, fd2); fd_install(fd1, newfile1);