From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AH8x227FVAHuFfQunAh9bONKLvLKrs+ltn/DuJhDoVEAcNXO7wMvmWsbqAMRcAZ+QAfGWmv4v2dr ARC-Seal: i=1; a=rsa-sha256; t=1517256257; cv=none; d=google.com; s=arc-20160816; b=T6xdYUECSVrsok/MolPNmaBD/AAEanlB+kMq+g5KwLdlp1KKloaRx8LIvtZbLU1seV AsCLMVEJwbYFfi7mbMPKrfOiSntZrc7h6dlyuph/WZqkPqjHCCqGRPbih+PpaAyujl29 oKgml6JjiGq1J19U8NxP2PO79ISwsFbXAJaKYB/5MN4kdlLa86kxJ9aUJbVr6biRlfgq 3nn2qBcOAMCMJ6e+em/WqYX/orb9KSGnJt1NNiLtxHPQeMQWtCE6DyI48U5t7oUMTFcM jAb88tn3wXSCD8rjkN0lA3h/VjWI095CBRs1jPDekqDhuRFB81cnYPjRrboDa7A7eVS4 V4kA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=BJ0UKAT6G00464kgYxEztcvJWp2KnxbQoUDYbzc4+Xo=; b=b9PHnxzePjTpbFD7pJIG8WXRPFo8WKxTdk86inpK93SL923b1xDcQqJC9buWQVjIgR mI3rhxJGh+TPpNaT4MnJhEUsKYIirGKvTe9LHg6FCZ4hKOfXodqiklzTzFcv7Lcum5ds abIz0S3o6BUCJmQzVRnTHD1Pxs5ZjSDgLAWrca6uQ0nYmYHTvev4qmGizmRrMoMo+FlR AGFgjXMtnQEeQRJ+LBJQf8K/tGtdv9xlgv00iEpQogCPqMMTDSVo3U5qus7jNp8Fu7CK RX2+Ce8OLQleMGizf8412I890T1abBEbm6zEk53Iz9dW/fK3hVfEnptS2uaiWf8qDme2 KFEA== ARC-Authentication-Results: i=1; mx.google.com; spf=softfail (google.com: domain of transitioning gregkh@linuxfoundation.org does not designate 90.92.71.90 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning gregkh@linuxfoundation.org does not designate 90.92.71.90 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+ac6ea7baa4432811eb50@syzkaller.appspotmail.com, Xin Long , Neil Horman , "David S. Miller" Subject: [PATCH 4.9 44/66] sctp: return error if the asoc has been peeled off in sctp_wait_for_sndbuf Date: Mon, 29 Jan 2018 13:57:08 +0100 Message-Id: <20180129123842.216806771@linuxfoundation.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180129123839.842860149@linuxfoundation.org> References: <20180129123839.842860149@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-LABELS: =?utf-8?b?IlxcU2VudCI=?= X-GMAIL-THRID: =?utf-8?q?1590958497909596692?= X-GMAIL-MSGID: =?utf-8?q?1590958497909596692?= X-Mailing-List: linux-kernel@vger.kernel.org List-ID: 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Xin Long [ Upstream commit a0ff660058b88d12625a783ce9e5c1371c87951f ] After commit cea0cc80a677 ("sctp: use the right sk after waking up from wait_buf sleep"), it may change to lock another sk if the asoc has been peeled off in sctp_wait_for_sndbuf. However, the asoc's new sk could be already closed elsewhere, as it's in the sendmsg context of the old sk that can't avoid the new sk's closing. If the sk's last one refcnt is held by this asoc, later on after putting this asoc, the new sk will be freed, while under it's own lock. This patch is to revert that commit, but fix the old issue by returning error under the old sk's lock. Fixes: cea0cc80a677 ("sctp: use the right sk after waking up from wait_buf sleep") Reported-by: syzbot+ac6ea7baa4432811eb50@syzkaller.appspotmail.com Signed-off-by: Xin Long Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sctp/socket.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -83,7 +83,7 @@ static int sctp_writeable(struct sock *sk); static void sctp_wfree(struct sk_buff *skb); static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, - size_t msg_len, struct sock **orig_sk); + size_t msg_len); static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p); static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p); static int sctp_wait_for_accept(struct sock *sk, long timeo); @@ -1956,7 +1956,7 @@ static int sctp_sendmsg(struct sock *sk, timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); if (!sctp_wspace(asoc)) { /* sk can be changed by peel off when waiting for buf. */ - err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len, &sk); + err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len); if (err) { if (err == -ESRCH) { /* asoc is already dead. */ @@ -7439,12 +7439,12 @@ void sctp_sock_rfree(struct sk_buff *skb /* Helper function to wait for space in the sndbuf. */ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, - size_t msg_len, struct sock **orig_sk) + size_t msg_len) { struct sock *sk = asoc->base.sk; - int err = 0; long current_timeo = *timeo_p; DEFINE_WAIT(wait); + int err = 0; pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, *timeo_p, msg_len); @@ -7473,17 +7473,13 @@ static int sctp_wait_for_sndbuf(struct s release_sock(sk); current_timeo = schedule_timeout(current_timeo); lock_sock(sk); - if (sk != asoc->base.sk) { - release_sock(sk); - sk = asoc->base.sk; - lock_sock(sk); - } + if (sk != asoc->base.sk) + goto do_error; *timeo_p = current_timeo; } out: - *orig_sk = sk; finish_wait(&asoc->wait, &wait); /* Release the association's refcnt. */