Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp5227390ybl; Tue, 27 Aug 2019 01:08:30 -0700 (PDT) X-Google-Smtp-Source: APXvYqzmpl8M7LW9oNIQB+PYlAlTNJQ9Jw3WcjSHddoX7ol073HUELLz9E7ti0fEMhPul9jQZ4hb X-Received: by 2002:a63:1f1b:: with SMTP id f27mr19869679pgf.233.1566893310631; Tue, 27 Aug 2019 01:08:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566893310; cv=none; d=google.com; s=arc-20160816; b=WP+vZ2GmG8q/8OVJ6WnUZVKXjpSDTZBQPzpqPTRY38VHq982bfNZTuMtZoz+AqUWvr 1RvJE1G8eSclSDIY7Jzj1NL5Db8CvdFLllleS4u55ZRpvHQ5p0lN/xm3hfwptgILv3dF NeQHukec5d+8iPrGD2SY5a+W0PzziVSIM0RJKPoZtFa2akNM1LT2cEaTBIC3D4CJkOSe i7wnWZlcaZrxRDTEE8lvb29LA85ugGR8AZ9rk4REdUDXHJbgetItKNjiA+peoqAwwft1 W3Fv7Vze4WK78xakKa7gS3NMohpFWdYUcO56eXb7w07AXZzlcbstCWarIYAfEwEoQf4l lVQA== 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=ZFTHcFW9a00a3b295ggFTWMgDCkn6IOufPEmN9289l0=; b=sh5xBrjGIAzD+iAS7SJg9k8Gfibpv6GSmjHgtqOKVojXV7u5iibi4drgBbXtCJoASh ruFqLaeNVXN1pLajgG3i010JHhtw7w62hjDuGQ3XUnTFOcQ/wEFE3hEbVgbDmyLF77Wx G/s2B3LufO62eM/d3RMrnYuFeXikyGwXnHjb3gw6u3hpibc1oGMR5Rjcz298M+ZKYsQt xWAD6RXNLs6hbivD7zts2sv4MafGZNrTwmpzfQwqrXM3zZO8y3Su8HKjc59Q7VTIwjzW 6u9jevv8M4D5QZlkaOoozmebPtC6zcd+ojeQjTsQRDx3IRkdZ1LfZgB6bGIBKMv/9Crd gXbg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=SM5xjzHW; 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 t34si12171386plb.29.2019.08.27.01.08.15; Tue, 27 Aug 2019 01:08:30 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b=SM5xjzHW; 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 S1732509AbfH0IHD (ORCPT + 99 others); Tue, 27 Aug 2019 04:07:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:37004 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732787AbfH0IG7 (ORCPT ); Tue, 27 Aug 2019 04:06:59 -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 DA8522173E; Tue, 27 Aug 2019 08:06:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1566893218; bh=pBHbVVwBvslJflaoPCCes5yvLgDQdAX5KjPTw5dVcfs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SM5xjzHW7YsGv+Qk+HqjmpYuWBcAiFmfb1TB4cT6+FcBa5DmP0KAg4fsVpjZ7iCl8 8MDoDhN9CzxOI5W13xoaThn0ApGGKCRlis2JTe9VawZm1ifeFU3av3spd46guVRj57 A/s+Ex01sTbZxIKLfJ47/6taXVOg+0lsADAbBYCU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+78e71c5bab4f76a6a719@syzkaller.appspotmail.com, David Howells Subject: [PATCH 5.2 162/162] rxrpc: Fix read-after-free in rxrpc_queue_local() Date: Tue, 27 Aug 2019 09:51:30 +0200 Message-Id: <20190827072744.493410292@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190827072738.093683223@linuxfoundation.org> References: <20190827072738.093683223@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 commit 06d9532fa6b34f12a6d75711162d47c17c1add72 upstream. rxrpc_queue_local() attempts to queue the local endpoint it is given and then, if successful, prints a trace line. The trace line includes the current usage count - but we're not allowed to look at the local endpoint at this point as we passed our ref on it to the workqueue. Fix this by reading the usage count before queuing the work item. Also fix the reading of local->debug_id for trace lines, which must be done with the same consideration as reading the usage count. Fixes: 09d2bf595db4 ("rxrpc: Add a tracepoint to track rxrpc_local refcounting") Reported-by: syzbot+78e71c5bab4f76a6a719@syzkaller.appspotmail.com Signed-off-by: David Howells Signed-off-by: Greg Kroah-Hartman --- include/trace/events/rxrpc.h | 6 +++--- net/rxrpc/local_object.c | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -498,10 +498,10 @@ rxrpc_tx_points; #define E_(a, b) { a, b } TRACE_EVENT(rxrpc_local, - TP_PROTO(struct rxrpc_local *local, enum rxrpc_local_trace op, + TP_PROTO(unsigned int local_debug_id, enum rxrpc_local_trace op, int usage, const void *where), - TP_ARGS(local, op, usage, where), + TP_ARGS(local_debug_id, op, usage, where), TP_STRUCT__entry( __field(unsigned int, local ) @@ -511,7 +511,7 @@ TRACE_EVENT(rxrpc_local, ), TP_fast_assign( - __entry->local = local->debug_id; + __entry->local = local_debug_id; __entry->op = op; __entry->usage = usage; __entry->where = where; --- a/net/rxrpc/local_object.c +++ b/net/rxrpc/local_object.c @@ -93,7 +93,7 @@ static struct rxrpc_local *rxrpc_alloc_l local->debug_id = atomic_inc_return(&rxrpc_debug_id); memcpy(&local->srx, srx, sizeof(*srx)); local->srx.srx_service = 0; - trace_rxrpc_local(local, rxrpc_local_new, 1, NULL); + trace_rxrpc_local(local->debug_id, rxrpc_local_new, 1, NULL); } _leave(" = %p", local); @@ -321,7 +321,7 @@ struct rxrpc_local *rxrpc_get_local(stru int n; n = atomic_inc_return(&local->usage); - trace_rxrpc_local(local, rxrpc_local_got, n, here); + trace_rxrpc_local(local->debug_id, rxrpc_local_got, n, here); return local; } @@ -335,7 +335,8 @@ struct rxrpc_local *rxrpc_get_local_mayb if (local) { int n = atomic_fetch_add_unless(&local->usage, 1, 0); if (n > 0) - trace_rxrpc_local(local, rxrpc_local_got, n + 1, here); + trace_rxrpc_local(local->debug_id, rxrpc_local_got, + n + 1, here); else local = NULL; } @@ -343,16 +344,16 @@ struct rxrpc_local *rxrpc_get_local_mayb } /* - * Queue a local endpoint unless it has become unreferenced and pass the - * caller's reference to the work item. + * Queue a local endpoint and pass the caller's reference to the work item. */ void rxrpc_queue_local(struct rxrpc_local *local) { const void *here = __builtin_return_address(0); + unsigned int debug_id = local->debug_id; + int n = atomic_read(&local->usage); if (rxrpc_queue_work(&local->processor)) - trace_rxrpc_local(local, rxrpc_local_queued, - atomic_read(&local->usage), here); + trace_rxrpc_local(debug_id, rxrpc_local_queued, n, here); else rxrpc_put_local(local); } @@ -367,7 +368,7 @@ void rxrpc_put_local(struct rxrpc_local if (local) { n = atomic_dec_return(&local->usage); - trace_rxrpc_local(local, rxrpc_local_put, n, here); + trace_rxrpc_local(local->debug_id, rxrpc_local_put, n, here); if (n == 0) call_rcu(&local->rcu, rxrpc_local_rcu); @@ -454,7 +455,7 @@ static void rxrpc_local_processor(struct container_of(work, struct rxrpc_local, processor); bool again; - trace_rxrpc_local(local, rxrpc_local_processing, + trace_rxrpc_local(local->debug_id, rxrpc_local_processing, atomic_read(&local->usage), NULL); do {