summaryrefslogtreecommitdiff
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/net/socket.c b/net/socket.c
index 8246cdf18437..2e3b5737c481 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -800,7 +800,10 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
int ret = INDIRECT_CALL_INET(READ_ONCE(sock->ops)->sendmsg, inet6_sendmsg,
inet_sendmsg, sock, msg,
msg_data_left(msg));
- BUG_ON(ret == -EIOCBQUEUED);
+ if (unlikely(ret == -EIOCBQUEUED)) {
+ DEBUG_NET_WARN_ON_ONCE(1);
+ ret = -EIO;
+ }
if (trace_sock_send_length_enabled())
call_trace_sock_send_length(sock->sk, ret, 0);
@@ -1851,10 +1854,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 +1865,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 +1908,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);
@@ -2437,8 +2439,8 @@ INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
* It is important to remember that both iov points to the same data, but,
* .iter_in is read-only and .iter_out is write-only by the protocol callbacks
*/
-static int sockptr_to_sockopt(sockopt_t *opt, sockptr_t optval,
- sockptr_t optlen, struct kvec *kvec)
+int sockptr_to_sockopt(sockopt_t *opt, sockptr_t optval,
+ sockptr_t optlen, struct kvec *kvec)
{
int koptlen;