From nobody Tue Jun 30 20:10:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92D15C433F5 for ; Sun, 9 Jan 2022 23:45:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234254AbiAIXpC (ORCPT ); Sun, 9 Jan 2022 18:45:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232177AbiAIXpB (ORCPT ); Sun, 9 Jan 2022 18:45:01 -0500 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE22CC06173F; Sun, 9 Jan 2022 15:45:00 -0800 (PST) Received: by mail-ed1-x52e.google.com with SMTP id w16so46725200edc.11; Sun, 09 Jan 2022 15:45:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KMVKzWzTDkR0qm3suHIJabcOLRjs4Osz10LuFhuiBqQ=; b=qF2H6YQCKG5mK6HEF6v1TEfhR5giSM4UdtU5JQ+Wai88ek6ir4iysxX/o10d/v/PCa z0QWciGSY0zbmWfbrt74Pao6mVGeNPNXvQZQo+lmY5+68Ss8liZ6S07P3zlyf6V/i8WB +B8GMfLUlRr9H777q1RwWXtA+/uWvNrtyGK96FeiOGdov1Kh9FW61FqMdOhaAQ6ka4am Axyq4xec0qBcjUPVUlmwdqZv+TiQbZWrVlFZzyGTEPbJl3IeCOVlnqJKA/LuFRpHm8wX 9oYOtS1A5luxTphAqWZ4b175Kkr+ohBQ+xoztyg1HmeY8AKseWZvgn49TCa7e97rfLko dDDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KMVKzWzTDkR0qm3suHIJabcOLRjs4Osz10LuFhuiBqQ=; b=HYhljqUpLDiSwG9ukmI+oZCSMxBgsgs0LS4WMLl7rsKcKKUwZhUI8WTPEfD8fsdk/Q SVp4INl2R88rd2hiWoK5Y07cXLVooBkGxorJO14C8ogsCYFEksq0ju7FP2MeRs358pyE 9HliYbjrLu2gOoNInjF4BqbR2mtFCjnShhJVjAXGfKNYTwXWFvPziiGPUPjpGhO//BYh dBCrXNPLQWNuEFAlvyPuAc+olSOAalyEr3QZJkFG6RiSXc6eaXySG3OjYRkqhMoelPwz aZuSVIeinC9v1olfgEVY2zIhOKYuO05vGfVcvU/a1357wkLwwv2bGCdjrOXJ4yzygQ8N sxRw== X-Gm-Message-State: AOAM532OBIuG1YeaXPa2zBGe6mzSxmuJjg4KcL1U10vIt1+dBmioZOmB JhWMn/F41z/geRjVGrc+tZy8hVKdxWq3CQ== X-Google-Smtp-Source: ABdhPJzOTbCQjm+GkHz+iDH9OwEiyI+CzOOSB6eqLvqd8dIFttdcgGTi873z0pS3ZB48GBdoRGdTXw== X-Received: by 2002:a17:906:d554:: with SMTP id cr20mr55865493ejc.356.1641771898951; Sun, 09 Jan 2022 15:44:58 -0800 (PST) Received: from localhost.localdomain (host-79-18-211-221.retail.telecomitalia.it. [79.18.211.221]) by smtp.gmail.com with ESMTPSA id kx21sm1783493ejc.155.2022.01.09.15.44.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Jan 2022 15:44:58 -0800 (PST) From: Dario Petrillo To: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo Cc: Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Dario Petrillo Subject: [PATCH] perf tui: avoid crash when annotating recursive functions Date: Mon, 10 Jan 2022 00:44:41 +0100 Message-Id: <20220109234441.325106-1-dario.pk1@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In perf report, entering a recursive function from inside of itself (either directly of indirectly through some other function) results in calling symbol__annotate2 multiple times, and freeing the whole disassembly when exiting from the innermost instance. The first issue causes the function's disassembly to be duplicated, and the latter a heap use-after-free (and crash) when trying to access the disassembly again. I reproduced the bug on perf 5.11.22 (Ubuntu 20.04.3 LTS) and 5.16.rc8 with the following testcase (compile with gcc recursive.c -o recursive). To reproduce: - perf record ./recursive - perf report - enter fibonacci and annotate it - move the cursor on one of the "callq fibonacci" instructions and press en= ter - at this point there will be two copies of the function in the disassemb= ly - go back by pressing q, and perf will crash #include int fibonacci(int n) { if(n <=3D 2) return 1; return fibonacci(n-1) + fibonacci(n-2); } int main() { printf("%d\n", fibonacci(40)); } This patch addresses the issue by annotating a function and freeing the associated memory on exit only if no annotation is already present, so that a recursive function is only annotated on entry. Signed-off-by: Dario Petrillo --- tools/perf/ui/browsers/annotate.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index e81c2493efdf..44ba900828f6 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -966,6 +966,7 @@ int symbol__tui_annotate(struct map_symbol *ms, struct = evsel *evsel, .opts =3D opts, }; int ret =3D -1, err; + int not_annotated =3D list_empty(¬es->src->source); =20 if (sym =3D=3D NULL) return -1; @@ -973,13 +974,15 @@ int symbol__tui_annotate(struct map_symbol *ms, struc= t evsel *evsel, if (ms->map->dso->annotate_warned) return -1; =20 - err =3D symbol__annotate2(ms, evsel, opts, &browser.arch); - if (err) { - char msg[BUFSIZ]; - ms->map->dso->annotate_warned =3D true; - symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); - ui__error("Couldn't annotate %s:\n%s", sym->name, msg); - goto out_free_offsets; + if (not_annotated) { + err =3D symbol__annotate2(ms, evsel, opts, &browser.arch); + if (err) { + char msg[BUFSIZ]; + ms->map->dso->annotate_warned =3D true; + symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); + ui__error("Couldn't annotate %s:\n%s", sym->name, msg); + goto out_free_offsets; + } } =20 ui_helpline__push("Press ESC to exit"); @@ -994,9 +997,11 @@ int symbol__tui_annotate(struct map_symbol *ms, struct= evsel *evsel, =20 ret =3D annotate_browser__run(&browser, evsel, hbt); =20 - annotated_source__purge(notes->src); + if(not_annotated) + annotated_source__purge(notes->src); =20 out_free_offsets: - zfree(¬es->offsets); + if(not_annotated) + zfree(¬es->offsets); return ret; } --=20 2.25.1