Received: by 10.192.165.156 with SMTP id m28csp888880imm; Tue, 17 Apr 2018 23:30:56 -0700 (PDT) X-Google-Smtp-Source: AIpwx48UQD5gqUhXMpl5tQYrAoBMVtsT+1t/fK1+oq25ie7PAqnKMiH+QEYP9zgYgOFx8FuDSNJF X-Received: by 10.98.36.76 with SMTP id r73mr852063pfj.108.1524033056699; Tue, 17 Apr 2018 23:30:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524033056; cv=none; d=google.com; s=arc-20160816; b=AA8r4U/tw/n8dzXlOdEhTvkDAWL0q1IBJI3TIoShFAlNMYW79YnTfKj++TR/4iRb5A 9KyT4XpgeIx81gH+yZC9wx2zRSur6S5xQrkF00vWzAPxq9FMTAYTGMeOAy3/Y2XhhofM N6hikp1J8aQf8nDCZ65bLrV4ifmDVCeaGf+HUrIm1lP++LlvoaKw3U/VWy+NktheQC2R CJJzM0aCJjoKPIRsz52EU+QVyQ1Ob/mqysIy4flMAQ+RtlL8/3vi/7KqL12SoNnMfelv 1fLqtPPhHUr9ZMDXUaURXTjURlwc13jLuC4lr8pJ2tSVzW3UejSFopeusAT7nWfPCcTU NqQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:smtp-origin-cluster:cc:to :smtp-origin-hostname:from:smtp-origin-hostprefix:dkim-signature :arc-authentication-results; bh=+6LjDfRj9G0JRmWoaT2pgjybMXvnOx5XAndG2Pv36UY=; b=ITVLug3UnLaEq8kVWxRFOKHRa8zt75WypPKK2YzCA9vGPvp70SKTG1rNiTEoZlmpCq g0Ezw1+SHvlQUA92R4ILa+/5rDvqEZi694QuwFVyBweNXd+QHvlmVdUIK37CwewTU4Wj thVuxrZBy71YnJM0juXac/HlRoogFbkJExwz1bDtLB1mK/T3lbhynQx9u0JLmtbCk13U 96Lygtbc415whXdLcvuuH+Mm0wEacT5HQ5Lc6Lg1/9V1KdPAgcmpAbx4WFfE/Bu1YzM1 arwBiOmeOnKaSMK7mLHnvK+GrMkTamtuXhRbgz3M88OC7C/nLo+WaXZRyN7/YaO8PWSk 2gRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@fb.com header.s=facebook header.b=dhDnrGAI; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=fb.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i192si537081pgc.380.2018.04.17.23.30.42; Tue, 17 Apr 2018 23:30:56 -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=@fb.com header.s=facebook header.b=dhDnrGAI; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=fb.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752665AbeDRG3i (ORCPT + 99 others); Wed, 18 Apr 2018 02:29:38 -0400 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:34504 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752357AbeDRG3g (ORCPT ); Wed, 18 Apr 2018 02:29:36 -0400 Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w3I6P2m3005130 for ; Tue, 17 Apr 2018 23:29:35 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=facebook; bh=+6LjDfRj9G0JRmWoaT2pgjybMXvnOx5XAndG2Pv36UY=; b=dhDnrGAIMMCVkC+DenJLeaHKRmO4aM/AJCa+MThK9//rnGkhHDD4jnIrn2n9HXvM/UAp SXf7To4SmEMwy2/9whQ0Pr6hVZnRyxF+Tg98lApKzd6lJ7raNOp9vHr4N0DgquFobDsy 7CxrpAKVTPm5gTDEf5d7K6JFgse9ng9juoM= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 2he0qcr090-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Tue, 17 Apr 2018 23:29:35 -0700 Received: from mx-out.facebook.com (192.168.52.123) by PRN-CHUB13.TheFacebook.com (192.168.16.23) with Microsoft SMTP Server id 14.3.361.1; Tue, 17 Apr 2018 23:29:34 -0700 Received: by devbig102.frc2.facebook.com (Postfix, from userid 4523) id 6D1EB4282898; Tue, 17 Apr 2018 23:29:34 -0700 (PDT) Smtp-Origin-Hostprefix: devbig From: Song Liu Smtp-Origin-Hostname: devbig102.frc2.facebook.com To: CC: , Song Liu , Alexander Shishkin , Ingo Molnar , Peter Zijlstra Smtp-Origin-Cluster: frc2c02 Subject: [PATCH 2/2] perf/core: fix bad use of igrab in kernel/event/core.c Date: Tue, 17 Apr 2018 23:29:07 -0700 Message-ID: <20180418062907.3210386-2-songliubraving@fb.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180418062907.3210386-1-songliubraving@fb.com> References: <20180418062907.3210386-1-songliubraving@fb.com> X-FB-Internal: Safe MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-04-18_02:,, signatures=0 X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org As Miklos reported and suggested: This pattern repeats two times in trace_uprobe.c and in kernel/events/core.c as well: ret = kern_path(filename, LOOKUP_FOLLOW, &path); if (ret) goto fail_address_parse; inode = igrab(d_inode(path.dentry)); path_put(&path); And it's wrong. You can only hold a reference to the inode if you have an active ref to the superblock as well (which is normally through path.mnt) or holding s_umount. This way unmounting the containing filesystem while the tracepoint is active will give you the "VFS: Busy inodes after unmount..." message and a crash when the inode is finally put. Solution: store path instead of inode. This patch fixes the issue in kernel/event/core.c. NOTE: Based on my understanding, perf_addr_filter only supports intel_pt. However, my test system doesn't support address filtering (or I made a mistake?). Therefore, I have NOT tested this patch. Could someone please help test it? Fixes: 375637bc5249 ("perf/core: Introduce address range filtering") Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Peter Zijlstra (Intel) Reported-by: Miklos Szeredi Signed-off-by: Song Liu --- arch/x86/events/intel/pt.c | 4 ++-- include/linux/perf_event.h | 2 +- kernel/events/core.c | 21 +++++++++------------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 3b99394..8d016ce 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -1194,7 +1194,7 @@ static int pt_event_addr_filters_validate(struct list_head *filters) filter->action == PERF_ADDR_FILTER_ACTION_START) return -EOPNOTSUPP; - if (!filter->inode) { + if (!filter->path.dentry) { if (!valid_kernel_ip(filter->offset)) return -EINVAL; @@ -1221,7 +1221,7 @@ static void pt_event_addr_filters_sync(struct perf_event *event) return; list_for_each_entry(filter, &head->list, entry) { - if (filter->inode && !offs[range]) { + if (filter->path.dentry && !offs[range]) { msr_a = msr_b = 0; } else { /* apply the offset */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index e71e99e..88922d8 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -467,7 +467,7 @@ enum perf_addr_filter_action_t { */ struct perf_addr_filter { struct list_head entry; - struct inode *inode; + struct path path; unsigned long offset; unsigned long size; enum perf_addr_filter_action_t action; diff --git a/kernel/events/core.c b/kernel/events/core.c index d7af828..7d711ed 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6668,7 +6668,7 @@ static void perf_event_addr_filters_exec(struct perf_event *event, void *data) raw_spin_lock_irqsave(&ifh->lock, flags); list_for_each_entry(filter, &ifh->list, entry) { - if (filter->inode) { + if (filter->path.dentry) { event->addr_filters_offs[count] = 0; restart++; } @@ -7333,7 +7333,7 @@ static bool perf_addr_filter_match(struct perf_addr_filter *filter, struct file *file, unsigned long offset, unsigned long size) { - if (filter->inode != file_inode(file)) + if (d_inode(filter->path.dentry) != file_inode(file)) return false; if (filter->offset > offset + size) @@ -8674,8 +8674,7 @@ static void free_filters_list(struct list_head *filters) struct perf_addr_filter *filter, *iter; list_for_each_entry_safe(filter, iter, filters, entry) { - if (filter->inode) - iput(filter->inode); + path_put(&filter->path); list_del(&filter->entry); kfree(filter); } @@ -8772,7 +8771,7 @@ static void perf_event_addr_filters_apply(struct perf_event *event) * Adjust base offset if the filter is associated to a binary * that needs to be mapped: */ - if (filter->inode) + if (filter->path.dentry) event->addr_filters_offs[count] = perf_addr_filter_apply(filter, mm); @@ -8846,7 +8845,6 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr, { struct perf_addr_filter *filter = NULL; char *start, *orig, *filename = NULL; - struct path path; substring_t args[MAX_OPT_ARGS]; int state = IF_STATE_ACTION, token; unsigned int kernel = 0; @@ -8959,19 +8957,18 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr, goto fail_free_name; /* look up the path and grab its inode */ - ret = kern_path(filename, LOOKUP_FOLLOW, &path); + ret = kern_path(filename, LOOKUP_FOLLOW, + &filter->path); if (ret) goto fail_free_name; - filter->inode = igrab(d_inode(path.dentry)); - path_put(&path); kfree(filename); filename = NULL; ret = -EINVAL; - if (!filter->inode || - !S_ISREG(filter->inode->i_mode)) - /* free_filters_list() will iput() */ + if (!filter->path.dentry || + !S_ISREG(d_inode(filter->path.dentry) + ->i_mode)) goto fail; event->addr_filters.nr_file_filters++; -- 2.9.5