Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp1324107rwb; Tue, 27 Sep 2022 11:20:17 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6wyhREy9FRxWEiosmNjCt3RYJiwsb2BzumpPHnfHKPvfYkqlsK4TA8d22tbc+Xp3P7Zw/x X-Received: by 2002:a05:6a00:170e:b0:550:dc52:4647 with SMTP id h14-20020a056a00170e00b00550dc524647mr30204107pfc.19.1664302816731; Tue, 27 Sep 2022 11:20:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664302816; cv=none; d=google.com; s=arc-20160816; b=nP6MXEHbI07zCbAUOAM8HRSP5y1wsWNqbwERWEQagOeLMfewdp+HkfY41NtQULOiQB 9YnAU+jeE/qsu9dG9bmqOv3AVIFcaVG+cc0ZGn+DifBX6gF3K+gOEQObrvw1gp852HS3 kPT3tqQIUBFeOJlqawaZEw38j+OYC4yrBdK06yIxiFPJde0VzDfpf5wund1kc0sOQHt0 GJeMXDQrKI1uKxdqtsU7lDH0CvrAUCkuUzGdPlpeJx5l71p6hZJ0uR66DMyzuQnxhRxy H3sYzBL1NnwmfeVNITmjU8t2NTUtbJVc7DOBUDf73rjRxdJvCBbuNsRUsLQp1zUevQ1p ONjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:mime-version:date :dkim-signature; bh=xrimbA31oh12GrLjVo2B/hMpsltLczwvj4VfTLXOv0M=; b=OfsZuYUiUp5ld1iBKPIqQuT1PavF/4O77rTJvkz4PqIjnRis9P1MAs7HqPkgpxMuYr 6Uubs0t2oceD5ad3352VjuxJuuTHPgGVM74nEz1Ys7Ff+OImuHrAXo5HMo/aYlt378fv PPje3VvpmjwkC0goCI/mocXV726Mca2rk3iHpNVGeANH164YfX3LHXs0+3rGG8Un6g9A HQIBaKSRHiaVLY3FHOEOw68HK/418IWm8XsVSsgyHVuj6tXTjr6Bgszz6VC3quL4/f04 Uc/mpgIIxgM2exE0Mt3eocGHuA0bVmQ8HNXfuwjOk0y0ykrsv9mz7/seLczoNCMSnaRX FkrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=OMULmYEI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z18-20020aa79492000000b0052d5f874fa8si78945pfk.164.2022.09.27.11.20.04; Tue, 27 Sep 2022 11:20:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=OMULmYEI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231448AbiI0RUx (ORCPT + 99 others); Tue, 27 Sep 2022 13:20:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230326AbiI0RUv (ORCPT ); Tue, 27 Sep 2022 13:20:51 -0400 Received: from mail-ed1-x54a.google.com (mail-ed1-x54a.google.com [IPv6:2a00:1450:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7555AEEE86 for ; Tue, 27 Sep 2022 10:20:49 -0700 (PDT) Received: by mail-ed1-x54a.google.com with SMTP id z2-20020a056402274200b004516734e755so8265965edd.3 for ; Tue, 27 Sep 2022 10:20:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date; bh=xrimbA31oh12GrLjVo2B/hMpsltLczwvj4VfTLXOv0M=; b=OMULmYEIDkxRB7ENeb/uPGSUQ/EgKtqJfimZkvES7SP7Ltpiyr6iMf2rYJ/dQhl9he coiTT+OW7F8lFzNCnGgdwu5UwagfywnIiEyVoRcGQWlgoiTWZ4vO1fO049HmAt3CZrDy 2DJsHAEhaWJXPTKd85/2FpQtiXDEOB1fRgMLGpV7NiSw0acPbNGYRZnzuQbb7X1sPj56 rRsrbWFHxStB08zMuxe95EAr3Ym7aZ9iE4Y5l6UKgqKfWp1hXqGHVVJKHZB5mzhosmoP t2TbThc4MsAN5J73pZjoiCIbEFQRn867vj92luYVJYzkyuaMR/+gKSFWJfgmr0ZQK/7l PhHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date; bh=xrimbA31oh12GrLjVo2B/hMpsltLczwvj4VfTLXOv0M=; b=GMGBIOLT8JITdUTHBeI+X+T6USonl3Ffmm35iPolchQErxZ+pDwy9qZNgcDRxgfnih ViCwd8dcEI6y38tNVmqPC4RdmEzan4F5M4jS96zRogFCpKHnYObex5BgNib9ROX5hU6k GihHeJfjapt5BwLf8JONwhtMkbmB6f4oadZfbE+7SAXFb8EhrLk8dHxev4pvgRq06ROC uGRI8mOIYw9zqO+AwytVReazChZZMMO8Ourzsuc9VIaJE+4uO3L/5Gt3hYPmbi3L0npI AugaEI6JP320ayP5eWY1avzbwYG5I05heFK+taUfLtVXgMNUf4xEXIjqogtYJuusMb9Z 8Pvg== X-Gm-Message-State: ACrzQf02dRAhiGlruprYJzKxbMOFkpFSRm4ukoGVdqhgyfk7Kc5w8yBX 1+q5YB2dOZnwI6JaiIzRh6zpxkNTww== X-Received: from elver.muc.corp.google.com ([2a00:79e0:9c:201:693c:15a1:a531:bb4e]) (user=elver job=sendgmr) by 2002:a05:6402:d5a:b0:457:b705:3280 with SMTP id ec26-20020a0564020d5a00b00457b7053280mr3560695edb.201.1664299247897; Tue, 27 Sep 2022 10:20:47 -0700 (PDT) Date: Tue, 27 Sep 2022 19:20:25 +0200 Mime-Version: 1.0 X-Mailer: git-send-email 2.37.3.998.g577e59143f-goog Message-ID: <20220927172025.1636995-1-elver@google.com> Subject: [PATCH -tip] perf, hw_breakpoint: Fix use-after-free if perf_event_open() fails From: Marco Elver To: elver@google.com, Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Dmitry Vyukov , kasan-dev@googlegroups.com, syzkaller Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Local testing revealed that we can trigger a use-after-free during rhashtable lookup as follows: | BUG: KASAN: use-after-free in memcmp lib/string.c:757 | Read of size 8 at addr ffff888107544dc0 by task perf-rhltable-n/1293 | | CPU: 0 PID: 1293 Comm: perf-rhltable-n Not tainted 6.0.0-rc3-00014-g85260862789c #46 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-debian-1.16.0-4 04/01/2014 | Call Trace: | | memcmp lib/string.c:757 | rhashtable_compare include/linux/rhashtable.h:577 [inline] | __rhashtable_lookup include/linux/rhashtable.h:602 [inline] | rhltable_lookup include/linux/rhashtable.h:688 [inline] | task_bp_pinned kernel/events/hw_breakpoint.c:324 | toggle_bp_slot kernel/events/hw_breakpoint.c:462 | __release_bp_slot kernel/events/hw_breakpoint.c:631 [inline] | release_bp_slot kernel/events/hw_breakpoint.c:639 | register_perf_hw_breakpoint kernel/events/hw_breakpoint.c:742 | hw_breakpoint_event_init kernel/events/hw_breakpoint.c:976 | perf_try_init_event kernel/events/core.c:11261 | perf_init_event kernel/events/core.c:11325 [inline] | perf_event_alloc kernel/events/core.c:11619 | __do_sys_perf_event_open kernel/events/core.c:12157 | do_syscall_x64 arch/x86/entry/common.c:50 [inline] | do_syscall_64 arch/x86/entry/common.c:80 | entry_SYSCALL_64_after_hwframe | | | Allocated by task 1292: | perf_event_alloc kernel/events/core.c:11505 | __do_sys_perf_event_open kernel/events/core.c:12157 | do_syscall_x64 arch/x86/entry/common.c:50 [inline] | do_syscall_64 arch/x86/entry/common.c:80 | entry_SYSCALL_64_after_hwframe | | Freed by task 1292: | perf_event_alloc kernel/events/core.c:11716 | __do_sys_perf_event_open kernel/events/core.c:12157 | do_syscall_x64 arch/x86/entry/common.c:50 [inline] | do_syscall_64 arch/x86/entry/common.c:80 | entry_SYSCALL_64_after_hwframe | | The buggy address belongs to the object at ffff888107544c00 | which belongs to the cache perf_event of size 1352 | The buggy address is located 448 bytes inside of | 1352-byte region [ffff888107544c00, ffff888107545148) This happens because the first perf_event_open() managed to reserve a HW breakpoint slot, however, later fails for other reasons and returns. The second perf_event_open() runs concurrently, and during rhltable_lookup() looks up an entry which is being freed: since rhltable_lookup() may run concurrently (under the RCU read lock) with rhltable_remove(), we may end up with a stale entry, for which memory may also have already been freed when being accessed. To fix, only free the failed perf_event after an RCU grace period. This allows subsystems that store references to an event to always access it concurrently under the RCU read lock, even if initialization will fail. Given failure is unlikely and a slow-path, turning the immediate free into a call_rcu()-wrapped free does not affect performance elsewhere. Fixes: 0370dc314df3 ("perf/hw_breakpoint: Optimize list of per-task breakpoints") Reported-by: syzkaller Signed-off-by: Marco Elver --- kernel/events/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index df90777262bf..007a87c1599c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11776,11 +11776,9 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->destroy(event); module_put(pmu->module); err_ns: - if (event->ns) - put_pid_ns(event->ns); if (event->hw.target) put_task_struct(event->hw.target); - kmem_cache_free(perf_event_cache, event); + call_rcu(&event->rcu_head, free_event_rcu); return ERR_PTR(err); } -- 2.37.3.998.g577e59143f-goog