Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753786AbcKYIi2 (ORCPT ); Fri, 25 Nov 2016 03:38:28 -0500 Received: from mx2.suse.de ([195.135.220.15]:45310 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753339AbcKYIcx (ORCPT ); Fri, 25 Nov 2016 03:32:53 -0500 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" From: Jiri Slaby To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Marcelo Ricardo Leitner , "David S . Miller" , Jiri Slaby Subject: [PATCH 3.12 106/127] sctp: assign assoc_id earlier in __sctp_connect Date: Fri, 25 Nov 2016 09:30:19 +0100 Message-Id: X-Mailer: git-send-email 2.10.2 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2138 Lines: 59 From: Marcelo Ricardo Leitner 3.12-stable review patch. If anyone has any objections, please let me know. =============== [ Upstream commit 7233bc84a3aeda835d334499dc00448373caf5c0 ] sctp_wait_for_connect() currently already holds the asoc to keep it alive during the sleep, in case another thread release it. But Andrey Konovalov and Dmitry Vyukov reported an use-after-free in such situation. Problem is that __sctp_connect() doesn't get a ref on the asoc and will do a read on the asoc after calling sctp_wait_for_connect(), but by then another thread may have closed it and the _put on sctp_wait_for_connect will actually release it, causing the use-after-free. Fix is, instead of doing the read after waiting for the connect, do it before so, and avoid this issue as the socket is still locked by then. There should be no issue on returning the asoc id in case of failure as the application shouldn't trust on that number in such situations anyway. This issue doesn't exist in sctp_sendmsg() path. Reported-by: Dmitry Vyukov Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov Signed-off-by: Marcelo Ricardo Leitner Reviewed-by: Xin Long Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Jiri Slaby --- net/sctp/socket.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 98cd6606f4a4..2c5cb6d2787d 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1217,9 +1217,12 @@ static int __sctp_connect(struct sock* sk, timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); - err = sctp_wait_for_connect(asoc, &timeo); - if ((err == 0 || err == -EINPROGRESS) && assoc_id) + if (assoc_id) *assoc_id = asoc->assoc_id; + err = sctp_wait_for_connect(asoc, &timeo); + /* Note: the asoc may be freed after the return of + * sctp_wait_for_connect. + */ /* Don't free association on exit. */ asoc = NULL; -- 2.10.2