Received: by 10.223.185.116 with SMTP id b49csp6340421wrg; Wed, 28 Feb 2018 07:51:34 -0800 (PST) X-Google-Smtp-Source: AG47ELsCXSQl86ihiCnKU5L9sQ2hOftG6Helbo8id+szHVJatlGC3XWT+wL1XtukwbEJyYWQgi7n X-Received: by 2002:a17:902:7a2:: with SMTP id 31-v6mr7502191plj.313.1519833094272; Wed, 28 Feb 2018 07:51:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519833094; cv=none; d=google.com; s=arc-20160816; b=gkZHlmQuz+2+KsLMXmI7uKE5ue8HHLwJ0oxoEGSYLoZjdiKP2lT+VTKuyRTfUZJBuZ 6jgx8wLJSzHCq3Fcr4ragKbK1i5k5CJZacKAspFkLcJUdNJ8ihNpMJlGTuo/VSLuyJ7N gF/T1HVsYFwQurSJMWmH/z353q+4TnCUAOf/H0qeqPcRT0ml/CfMdXB1Y1WYpM4PYvxp 0/FE3aFTPhhgOPVougASlkQRApCJn9o41sUAj+19qgR/n7I0j5IiHkwwrl9YSKcRK5bL MjbT/ENlNRfM20a5Cju0D5gZhfcIB9xRws5zo+SraFCiHFJwQlZbOh3Zp+Wh+3ZR6H2F kUsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=0Xu/0JAuEF2jrR7XNmTTbe8QxYXQuicId2r7QFErKaI=; b=o1WMGDM4H2sMKspAveOHtbRh8osfXHGo7JxDSMSAGGcBWUobApCvu0OJL4zb1mQHfe qcDY/aexs3pcJnEpTAqqo8zXqn2/6z40KosHiPL9ILBkPQDg9+KuLpxQVZbF7r2Q99LI u2l3ktqgEQciI44Jjh6/TNilXVRQzIdGHUtmumR08WfSByWaQLr8CgYDEIhVB1d1DTJn hHiKlQdZd6duHXahH9FUYlvXQx/r5C4S46nZ8uCIR7G2Re9I504vg1UQIgP5wKLRn96a gOCmXOLDORAmat9rVcFHvrwOIFIddTb+Lzjt53E1/CS83L39Jkk7LQrGWV+nPRepBA3b dV4Q== 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 68si1370271pff.141.2018.02.28.07.51.19; Wed, 28 Feb 2018 07:51:34 -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 S1752934AbeB1Pu2 (ORCPT + 99 others); Wed, 28 Feb 2018 10:50:28 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:34323 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933668AbeB1PuY (ORCPT ); Wed, 28 Feb 2018 10:50:24 -0500 Received: from [2a02:8011:400e:2:6f00:88c8:c921:d332] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1er3Yp-0006Xi-HY; Wed, 28 Feb 2018 15:22:27 +0000 Received: from ben by deadeye with local (Exim 4.90_1) (envelope-from ) id 1er3Yk-0000Gj-0m; Wed, 28 Feb 2018 15:22:22 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "David S. Miller" , "Neil Horman" , syzbot+ac6ea7baa4432811eb50@syzkaller.appspotmail.com, "Xin Long" Date: Wed, 28 Feb 2018 15:20:18 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 210/254] sctp: return error if the asoc has been peeled off in sctp_wait_for_sndbuf In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.55-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Xin Long commit a0ff660058b88d12625a783ce9e5c1371c87951f upstream. 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 [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings --- 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); @@ -1906,7 +1906,7 @@ static int sctp_sendmsg(struct kiocb *io 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) goto out_free; } @@ -6732,12 +6732,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); @@ -6765,17 +6765,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. */