Commit d460b04b authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Paolo Abeni
Browse files

af_unix: Clean up error paths in unix_stream_sendmsg().



If we move send_sig() to the SEND_SHUTDOWN check before
the while loop, then we can reuse the same kfree_skb()
after the pipe_err_free label.

Let's gather the scattered kfree_skb()s in error paths.

While at it, some style issues are fixed, and the pipe_err_free
label is renamed to out_pipe to match other label names.

Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6c444255
Loading
Loading
Loading
Loading
+20 −19
Original line number Diff line number Diff line
@@ -2275,8 +2275,13 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
		}
	}

	if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
		goto pipe_err;
	if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) {
		if (!(msg->msg_flags & MSG_NOSIGNAL))
			send_sig(SIGPIPE, current, 0);

		err = -EPIPE;
		goto out_err;
	}

	while (sent < len) {
		size = len - sent;
@@ -2305,20 +2310,18 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,

		/* Only send the fds in the first buffer */
		err = unix_scm_to_skb(&scm, skb, !fds_sent);
		if (err < 0) {
			kfree_skb(skb);
			goto out_err;
		}
		if (err < 0)
			goto out_free;

		fds_sent = true;

		if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) {
			skb->ip_summed = CHECKSUM_UNNECESSARY;
			err = skb_splice_from_iter(skb, &msg->msg_iter, size,
						   sk->sk_allocation);
			if (err < 0) {
				kfree_skb(skb);
				goto out_err;
			}
			if (err < 0)
				goto out_free;

			size = err;
			refcount_add(size, &sk->sk_wmem_alloc);
		} else {
@@ -2326,17 +2329,15 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
			skb->data_len = data_len;
			skb->len = size;
			err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
			if (err) {
				kfree_skb(skb);
				goto out_err;
			}
			if (err)
				goto out_free;
		}

		unix_state_lock(other);

		if (sock_flag(other, SOCK_DEAD) ||
		    (other->sk_shutdown & RCV_SHUTDOWN))
			goto pipe_err_free;
			goto out_pipe;

		maybe_add_creds(skb, sock, other);
		scm_stat_add(other, skb);
@@ -2359,13 +2360,13 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,

	return sent;

pipe_err_free:
out_pipe:
	unix_state_unlock(other);
	kfree_skb(skb);
pipe_err:
	if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
	if (!sent && !(msg->msg_flags & MSG_NOSIGNAL))
		send_sig(SIGPIPE, current, 0);
	err = -EPIPE;
out_free:
	kfree_skb(skb);
out_err:
	scm_destroy(&scm);
	return sent ? : err;