Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp5135451yba; Wed, 8 May 2019 08:24:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqzdJBxoJ9mlG6Voyj9ajJ6XeB06QKwc43q+D6z8eq/OsYxo6Wfu1f+Z7Crp3j2xJFYN6knq X-Received: by 2002:a17:902:e48d:: with SMTP id cj13mr5661130plb.156.1557329083163; Wed, 08 May 2019 08:24:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557329083; cv=none; d=google.com; s=arc-20160816; b=fqXLO5OrBl9tjZ19xjTiJ/bTKRBd7YUrnZY4lFVhaalhcJ6aPIz2aX/j9ANpDt5DSK 7A1YuqbDXIF6BR/gu2o/cFCDLkljCpk5Crgc2EzugarWxzQo2lVN4m42RjQaoxV7KHbI epAOQo1sV/fbta9FrpHgveAJZZ2ZpXgmjZ+tNHhQz2BBH89Ic6xd5h6KJiXHzvJFJ71B rDQsT/bjmR7c0pWVvjkFdJK6IapyaO1aiIp6IQEWfuHz+rRtAbXf/wFpkuoMrm2634W0 QBqyZLfcjtC2IMocnReGWSdrHMkBok8/nfknOMKWkXHjLlT4+g2fn0ExK/oFcp316H6k oD9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from; bh=X35ZJIl/QVdOAWBmSwu6qIHziUbIFcSAnkoZbz/DWhs=; b=TYYKMJOmQw1YWt2ZXN6FlpeCoZfGv2TvF4VIMiGq5+BU/T8+8WRj5Auqsku+/aB7Ry HPddfSrLkY+poZPEgpw5nmOls/goe6HkJF6lWFgRaGyp6yqUh5t3mYFpkpExA40162PS 5FN7496rAblkY6ACNlfeA933m9NAUsQ79JIZCXdeMmmcTxLefGpopKTb83NBgoIGpNDO LSrlaEYwLSYaLLjAbp7KEyXjJz9aK2dBYhFSkweB4q0yGuIebITNAzyUlDDoYU0TNGDT 0J26pQGyaLf/P3YMSEZgCO6UZYyOXwj1or+Hb88LeLcf0A3jLByp9utuxp1OUlZnfWPH xoBw== ARC-Authentication-Results: i=1; mx.google.com; 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 71si15482867pga.319.2019.05.08.08.24.27; Wed, 08 May 2019 08:24:43 -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; 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 S1727029AbfEHO2i (ORCPT + 99 others); Wed, 8 May 2019 10:28:38 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:52442 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726783AbfEHO2h (ORCPT ); Wed, 8 May 2019 10:28:37 -0400 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 252892C6F3213E655003; Wed, 8 May 2019 22:28:35 +0800 (CST) Received: from euler.huawei.com (10.175.104.193) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.439.0; Wed, 8 May 2019 22:28:27 +0800 From: Wei Li To: , , , , , CC: , Subject: [PATCH v2] fix use-after-free in perf_sched__lat Date: Wed, 8 May 2019 22:36:48 +0800 Message-ID: <20190508143648.8153-1-liwei391@huawei.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.104.193] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After thread is added to machine->threads[i].dead in __machine__remove_thread, the machine->threads[i].dead is freed when calling free(session) in perf_session__delete(). So it get a Segmentation fault when accessing it in thread__put(). In this patch, we delay the perf_session__delete until all threads have been deleted. This can be reproduced by following steps: ulimit -c unlimited export MALLOC_MMAP_THRESHOLD_=0 perf sched record sleep 10 perf sched latency --sort max Segmentation fault (core dumped) Signed-off-by: Zhipeng Xie Signed-off-by: Wei Li --- tools/perf/builtin-sched.c | 63 ++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 275f2d92a7bf..8a4841fa124c 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1774,7 +1774,8 @@ static int perf_sched__process_comm(struct perf_tool *tool __maybe_unused, return 0; } -static int perf_sched__read_events(struct perf_sched *sched) +static int __perf_sched__read_events(struct perf_sched *sched, + struct perf_session *session) { const struct perf_evsel_str_handler handlers[] = { { "sched:sched_switch", process_sched_switch_event, }, @@ -1783,30 +1784,17 @@ static int perf_sched__read_events(struct perf_sched *sched) { "sched:sched_wakeup_new", process_sched_wakeup_event, }, { "sched:sched_migrate_task", process_sched_migrate_task_event, }, }; - struct perf_session *session; - struct perf_data data = { - .path = input_name, - .mode = PERF_DATA_MODE_READ, - .force = sched->force, - }; - int rc = -1; - - session = perf_session__new(&data, false, &sched->tool); - if (session == NULL) { - pr_debug("No Memory for session\n"); - return -1; - } symbol__init(&session->header.env); if (perf_session__set_tracepoints_handlers(session, handlers)) - goto out_delete; + return -1; if (perf_session__has_traces(session, "record -R")) { int err = perf_session__process_events(session); if (err) { pr_err("Failed to process events, error %d", err); - goto out_delete; + return -1; } sched->nr_events = session->evlist->stats.nr_events[0]; @@ -1814,9 +1802,28 @@ static int perf_sched__read_events(struct perf_sched *sched) sched->nr_lost_chunks = session->evlist->stats.nr_events[PERF_RECORD_LOST]; } - rc = 0; -out_delete: + return 0; +} + +static int perf_sched__read_events(struct perf_sched *sched) +{ + struct perf_session *session; + struct perf_data data = { + .path = input_name, + .mode = PERF_DATA_MODE_READ, + .force = sched->force, + }; + int rc; + + session = perf_session__new(&data, false, &sched->tool); + if (session == NULL) { + pr_debug("No Memory for session\n"); + return -1; + } + + rc = __perf_sched__read_events(sched, session); perf_session__delete(session); + return rc; } @@ -3130,12 +3137,25 @@ static void perf_sched__merge_lat(struct perf_sched *sched) static int perf_sched__lat(struct perf_sched *sched) { + struct perf_session *session; + struct perf_data data = { + .path = input_name, + .mode = PERF_DATA_MODE_READ, + .force = sched->force, + }; struct rb_node *next; + int rc = -1; setup_pager(); - if (perf_sched__read_events(sched)) + session = perf_session__new(&data, false, &sched->tool); + if (session == NULL) { + pr_debug("No Memory for session\n"); return -1; + } + + if (__perf_sched__read_events(sched, session)) + goto out_delete; perf_sched__merge_lat(sched); perf_sched__sort_lat(sched); @@ -3164,7 +3184,10 @@ static int perf_sched__lat(struct perf_sched *sched) print_bad_events(sched); printf("\n"); - return 0; + rc = 0; +out_delete: + perf_session__delete(session); + return rc; } static int setup_map_cpus(struct perf_sched *sched) -- 2.17.1