Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1129521ybt; Tue, 7 Jul 2020 08:24:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxXR82qTNGWB2pgfy+ac0RMdFXwaeQSJC/dNjmhNAhdQqBFWWwfG0/A+hEZ4dnc/Ez33Zca X-Received: by 2002:a17:906:33c5:: with SMTP id w5mr47519970eja.275.1594135496603; Tue, 07 Jul 2020 08:24:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594135496; cv=none; d=google.com; s=arc-20160816; b=XeKp0lye/gHcsDZm9tCfs5TMkH3JHra0rEc3SWjGJgDNntOLgLgUkEoZ3s6BR7S7s8 +wOYYA+rOgf/uVbqMwlZKXnpE5vlrHyTSrDFBEHhT9KcA3DdBM2aKnrFo5reN0VxE85A XoedRokOdW6TFwXg0XSwfXHSFnQjX+nFdFGOl1HSHAOq3q0yhEjeK3JSGVN3RXEtg3wj BpnmcUrRG6FwGZSIdhnc4czuZpTG8bnK5BidcAOfCkM0u1wYd8d8+SmQ4iPUHS1iTKis ncjLrJksEYP49GFtwphEUsO3CMjn8yJSed5jau5QukjRhtz/UoUnl7Y4c0r4yuR7C/8l xpmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=x7e3d8zbRzTzkZkDbcHMPHUN8sL5lqWyaM3OLBHkpxs=; b=PXZj08ml7I1d3LkjN/5CF2mKh70EZkmigxHmxLLR9H8txjbpZqYcQ/i1kFeks0HP0W 2+6wC4UpDTLeSLsp2/29imEcjwBJbMMlyfU9FPn6al42uBNjMW/0T0j8p2uax4U4oDFg 0MHu+5yCAccPdHJ0LbZQp3t2nvDlDliPlRBiFgrs1OmxwoXRjDoY1BSWcFbD2akyxeqI ke2e2TkgxL9AtEMU9TrOXXTupMNlShmFnbDcoCn8IQSayd+J/+gecr0npZyeEhGUiDe3 zgnGviHCIP/VdLnQhOC5C/G6+L55Bd17DhIS/gWdO+xhL/U+minTBg9BaGSJ8Abzx9xO K6Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Kiq2fqcx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f12si14975401ejw.135.2020.07.07.08.24.33; Tue, 07 Jul 2020 08:24:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Kiq2fqcx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729644AbgGGPVG (ORCPT + 99 others); Tue, 7 Jul 2020 11:21:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:33068 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729616AbgGGPVB (ORCPT ); Tue, 7 Jul 2020 11:21:01 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4C273206E2; Tue, 7 Jul 2020 15:21:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1594135260; bh=hTbUvOF/JFnFT0p2wG5DgDAwt3T4hRgBb5o3JsrfnL8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kiq2fqcxaXJfQ/LwZBmU0/u+bKueKZ/mNy//tZgIiUC5P8QqCyH5NbRKO/d5/62w9 LkoQpUxICSAZEwo1FiRzpKDB63dHv7nl/JSHSqMw/z4xyucMM+/WrLYHq7I0+jK07r IDxQR06oDsCiDENgEpiw6K+8WBSJ6AstATCnXTtU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, David Howells , "David S. Miller" , Sasha Levin Subject: [PATCH 5.4 08/65] rxrpc: Fix race between incoming ACK parser and retransmitter Date: Tue, 7 Jul 2020 17:16:47 +0200 Message-Id: <20200707145752.841736013@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200707145752.417212219@linuxfoundation.org> References: <20200707145752.417212219@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: David Howells [ Upstream commit 2ad6691d988c0c611362ddc2aad89e0fb50e3261 ] There's a race between the retransmission code and the received ACK parser. The problem is that the retransmission loop has to drop the lock under which it is iterating through the transmission buffer in order to transmit a packet, but whilst the lock is dropped, the ACK parser can crank the Tx window round and discard the packets from the buffer. The retransmission code then updated the annotations for the wrong packet and a later retransmission thought it had to retransmit a packet that wasn't there, leading to a NULL pointer dereference. Fix this by: (1) Moving the annotation change to before we drop the lock prior to transmission. This means we can't vary the annotation depending on the outcome of the transmission, but that's fine - we'll retransmit again later if it failed now. (2) Skipping the packet if the skb pointer is NULL. The following oops was seen: BUG: kernel NULL pointer dereference, address: 000000000000002d Workqueue: krxrpcd rxrpc_process_call RIP: 0010:rxrpc_get_skb+0x14/0x8a ... Call Trace: rxrpc_resend+0x331/0x41e ? get_vtime_delta+0x13/0x20 rxrpc_process_call+0x3c0/0x4ac process_one_work+0x18f/0x27f worker_thread+0x1a3/0x247 ? create_worker+0x17d/0x17d kthread+0xe6/0xeb ? kthread_delayed_work_timer_fn+0x83/0x83 ret_from_fork+0x1f/0x30 Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code") Signed-off-by: David Howells Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/rxrpc/call_event.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index 2a65ac41055f5..985fb89202d0c 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c @@ -248,7 +248,18 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) if (anno_type != RXRPC_TX_ANNO_RETRANS) continue; + /* We need to reset the retransmission state, but we need to do + * so before we drop the lock as a new ACK/NAK may come in and + * confuse things + */ + annotation &= ~RXRPC_TX_ANNO_MASK; + annotation |= RXRPC_TX_ANNO_RESENT; + call->rxtx_annotations[ix] = annotation; + skb = call->rxtx_buffer[ix]; + if (!skb) + continue; + rxrpc_get_skb(skb, rxrpc_skb_got); spin_unlock_bh(&call->lock); @@ -262,24 +273,6 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) rxrpc_free_skb(skb, rxrpc_skb_freed); spin_lock_bh(&call->lock); - - /* We need to clear the retransmit state, but there are two - * things we need to be aware of: A new ACK/NAK might have been - * received and the packet might have been hard-ACK'd (in which - * case it will no longer be in the buffer). - */ - if (after(seq, call->tx_hard_ack)) { - annotation = call->rxtx_annotations[ix]; - anno_type = annotation & RXRPC_TX_ANNO_MASK; - if (anno_type == RXRPC_TX_ANNO_RETRANS || - anno_type == RXRPC_TX_ANNO_NAK) { - annotation &= ~RXRPC_TX_ANNO_MASK; - annotation |= RXRPC_TX_ANNO_UNACK; - } - annotation |= RXRPC_TX_ANNO_RESENT; - call->rxtx_annotations[ix] = annotation; - } - if (after(call->tx_hard_ack, seq)) seq = call->tx_hard_ack; } -- 2.25.1