From patchwork Sun Aug 28 02:02:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krister Johansen X-Patchwork-Id: 1671316 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=templeofstupid.com header.i=@templeofstupid.com header.a=rsa-sha256 header.s=dreamhost header.b=K7sGDKh1; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MGLbJ67KNz1ygm for ; Mon, 29 Aug 2022 16:47:24 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1oSYYD-00015p-Pz; Mon, 29 Aug 2022 06:47:13 +0000 Received: from quail.birch.relay.mailchannels.net ([23.83.209.151]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1oS7dd-0000uU-8e for kernel-team@lists.ubuntu.com; Sun, 28 Aug 2022 02:03:01 +0000 X-Sender-Id: dreamhost|x-authsender|kjlx@templeofstupid.com Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 8C8E912292B for ; Sun, 28 Aug 2022 02:02:59 +0000 (UTC) Received: from pdx1-sub0-mail-a304 (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 2A808121F25 for ; Sun, 28 Aug 2022 02:02:59 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1661652179; a=rsa-sha256; cv=none; b=q1R+FExLpTPvu0eROOaGKc2nvsV66bE4ImogegXBW3me6v97q2Gaezsbkl9nqVCx1NXE+f 8SHzJwfY3ATxSBnR6sU7p9+aS3Xf/XemJY2zpPT2AUN3jrHQyQ50f5jt3LBwExv0XRZ40q f8Dt3lDCdKK8E0LiFmdZop7e42i0PwKst4ADilIKEQVvXLN6DfOVTl+Da9GE607c4CplZq wPu3oxM7FxXoRjuWn9GRQ7hijoG9pBHUny4GQOf02bJFl7nlwQ2geTwthrClJKW9bbk9sT bLP5FI/4SCUptTk9V4LDbJigkc5xJJ4fE2L17EhdIq79QeVvAqScIe2KzjM7xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1661652179; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ddhx+iD0oqW79e/Y8yj3vFrQzMktqsD80fVf+3gN0VE=; b=ls5hZhyPchBLKlGpcWBAy9yFJXVvizMDA7LhbZDlAXseLF/HqsmTtK25HTVb6Yd4bpod/M e4H/vpRF8UgQUH9uq4a/RCbL7qAc3wyFOqVqR547M3pGO3EfUsJAzvDXkMtbaiAeSadlAB i2ndancsQFWxGXY8GivcCCHmXHkt9hqfuOqFsVIFKKBROF/STYeABg+vpepLaxJz5/RwDl tb+uqjXsaGp29nw0Xmvi82UM2e1FWqXT8mTiII2lTN5XRtvlMIhNW4cBdo4M96G+1lDreH HKd9gvItE19tUijsjvic/rUcIO0T+0ktpqWuKnMY86v9AXsSaZlO1gKhD0n5xg== ARC-Authentication-Results: i=1; rspamd-64cc6f7466-v6ln5; auth=pass smtp.auth=dreamhost smtp.mailfrom=kjlx@templeofstupid.com X-Sender-Id: dreamhost|x-authsender|kjlx@templeofstupid.com X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|kjlx@templeofstupid.com X-MailChannels-Auth-Id: dreamhost X-Cellar-Broad: 37cffd4e0e0f362a_1661652179420_685425468 X-MC-Loop-Signature: 1661652179420:2324456387 X-MC-Ingress-Time: 1661652179420 Received: from pdx1-sub0-mail-a304 (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.121.210.155 (trex/6.7.1); Sun, 28 Aug 2022 02:02:59 +0000 Received: from kmjvbox (unknown [98.42.138.125]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kjlx@templeofstupid.com) by pdx1-sub0-mail-a304 (Postfix) with ESMTPSA id 4MFcKZ6Vjcz33 for ; Sat, 27 Aug 2022 19:02:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=templeofstupid.com; s=dreamhost; t=1661652179; bh=ddhx+iD0oqW79e/Y8yj3vFrQzMktqsD80fVf+3gN0VE=; h=Date:From:To:Cc:Subject:Content-Type; b=K7sGDKh1KG2aMxD3pWa+rOZIjb60wvT3xTOSRTLwC88SMxC8sNzYuRhamsv42ZNQc QDRLffDwf0sAv6PTJkcT6d5qmQ6FCRRkZbG8GptQlQ0PCreJxQCTvBooDAYJeSWeLY x7aEtGnA+wrye6Bd5lGn7Cru+gUIWJPvT2Us1pBk= Received: from johansen (uid 1000) (envelope-from kjlx@templeofstupid.com) id e0007 by kmjvbox (DragonFly Mail Agent v0.12); Sat, 27 Aug 2022 19:02:57 -0700 Date: Sat, 27 Aug 2022 19:02:57 -0700 From: Krister Johansen To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/1][linux-5.15] tracing/perf: Fix double put of trace event when init fails Message-ID: <0d7970e8702b7d15293a844cb59ddd352c298f26.1661651934.git.kjlx@templeofstupid.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Mailman-Approved-At: Mon, 29 Aug 2022 06:47:13 +0000 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Reaver Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" commit 7249921d94ff64f67b733eca0b68853a62032b3d upstream. If in perf_trace_event_init(), the perf_trace_event_open() fails, then it will call perf_trace_event_unreg() which will not only unregister the perf trace event, but will also call the put() function of the tp_event. The problem here is that the trace_event_try_get_ref() is called by the caller of perf_trace_event_init() and if perf_trace_event_init() returns a failure, it will then call trace_event_put(). But since the perf_trace_event_unreg() already called the trace_event_put() function, it triggers a WARN_ON(). WARNING: CPU: 1 PID: 30309 at kernel/trace/trace_dynevent.c:46 trace_event_dyn_put_ref+0x15/0x20 If perf_trace_event_reg() does not call the trace_event_try_get_ref() then the perf_trace_event_unreg() should not be calling trace_event_put(). This breaks symmetry and causes bugs like these. Pull out the trace_event_put() from perf_trace_event_unreg() and call it in the locations that perf_trace_event_unreg() is called. This not only fixes this bug, but also brings back the proper symmetry of the reg/unreg vs get/put logic. Link: https://lore.kernel.org/all/cover.1660347763.git.kjlx@templeofstupid.com/ Link: https://lkml.kernel.org/r/20220816192817.43d5e17f@gandalf.local.home Cc: stable@vger.kernel.org Fixes: 1d18538e6a092 ("tracing: Have dynamic events have a ref counter") Reported-by: Krister Johansen Reviewed-by: Krister Johansen Tested-by: Krister Johansen Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman Signed-off-by: Krister Johansen Acked-by: Stefan Bader --- kernel/trace/trace_event_perf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index fba8cb77a73a..083f648e3265 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -157,7 +157,7 @@ static void perf_trace_event_unreg(struct perf_event *p_event) int i; if (--tp_event->perf_refcount > 0) - goto out; + return; tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER, NULL); @@ -176,8 +176,6 @@ static void perf_trace_event_unreg(struct perf_event *p_event) perf_trace_buf[i] = NULL; } } -out: - trace_event_put_ref(tp_event); } static int perf_trace_event_open(struct perf_event *p_event) @@ -241,6 +239,7 @@ void perf_trace_destroy(struct perf_event *p_event) mutex_lock(&event_mutex); perf_trace_event_close(p_event); perf_trace_event_unreg(p_event); + trace_event_put_ref(p_event->tp_event); mutex_unlock(&event_mutex); } @@ -292,6 +291,7 @@ void perf_kprobe_destroy(struct perf_event *p_event) mutex_lock(&event_mutex); perf_trace_event_close(p_event); perf_trace_event_unreg(p_event); + trace_event_put_ref(p_event->tp_event); mutex_unlock(&event_mutex); destroy_local_trace_kprobe(p_event->tp_event); @@ -347,6 +347,7 @@ void perf_uprobe_destroy(struct perf_event *p_event) mutex_lock(&event_mutex); perf_trace_event_close(p_event); perf_trace_event_unreg(p_event); + trace_event_put_ref(p_event->tp_event); mutex_unlock(&event_mutex); destroy_local_trace_uprobe(p_event->tp_event); }