Received: by 10.223.176.5 with SMTP id f5csp3352906wra; Mon, 29 Jan 2018 12:06:04 -0800 (PST) X-Google-Smtp-Source: AH8x2274eyMt03u4DI5HeZyIMuz76y7hNiirfllOAnu7G+IKH4gzdzddx22jd9/xzxJd0fgavKO9 X-Received: by 10.99.125.74 with SMTP id m10mr22825799pgn.354.1517256363890; Mon, 29 Jan 2018 12:06:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517256363; cv=none; d=google.com; s=arc-20160816; b=ZjkwbckcVlBADUov1Auqk+LYbK6jlc3l737yJPsU4FEVf9kUVbwQyq1KFIY1WfeNg3 dB4EV9SU+yWMOjlDBPZPP15Hg4cKnxm9/JKQXUryooXxS+KgcAY4LtoXAFpml+bsVsIN PuxPnWBkoYcpDeq2St1DSk1mHtJ4uUaWzid5ShIuOj1t7xaNH1T9xCG6OShkwBzGYBii rNqZ7y1SFGZpU4jcEXuENLV2N73d0q0lT8O4DMyMrjfGK/MPbTex7bYf9OWGJJO3zHoV fk+YLxqIOnpNxH6Rk/BhIMsljh6Lo5wrlQa3xljQQqeUVcXv6B2fjGBBWlkQHD+8KdKt cu5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=BJ0UKAT6G00464kgYxEztcvJWp2KnxbQoUDYbzc4+Xo=; b=MAqzX8amjA6vHVfkKRcTJsyvHtvvmn1Nqb0eVVhw5yZNLVAzR1IUFcGXW5b1LnEhEO 2ztm6j4nHq47BmXxLx1iFMsLJeyvMHMXNV7Cwz3YhVzBNfGrtqDgW7jZ9/1CyZvdsyEv F2YIlUndmVVmncnyNNqnFqqfwoLMgcXh0Bpq00pyDdpqKwwQTKbNYDNn8n/iWn8FZ0Z9 xLrOm/axDu4NFGHp4WL/6yAjL6v7KiOy07RH79c4wfFfBYp6xIdJmYoRsSjdonQvjfob IOo8PSh9dPuExlrvL9fkHwNprVcx4XU21MvZS58KTULLw5VAxYMBnXSt/I/b5cP11k9g d86g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i137si7900004pgc.258.2018.01.29.12.05.49; Mon, 29 Jan 2018 12:06:03 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752203AbeA2UES (ORCPT + 99 others); Mon, 29 Jan 2018 15:04:18 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:41934 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752158AbeA2UEQ (ORCPT ); Mon, 29 Jan 2018 15:04:16 -0500 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 2B5F82F9A; Mon, 29 Jan 2018 13:06:03 +0000 (UTC) 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 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. */