From patchwork Mon Dec 19 18:31:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 34691 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp2561422wrn; Mon, 19 Dec 2022 10:58:09 -0800 (PST) X-Google-Smtp-Source: AMrXdXtvYdAb9+RbtsaoRUqrPQL9SJJgOh2lRP1KmHklEICQfwPA8WW5cWE/+QDpu39Uq8k5GHnC X-Received: by 2002:a17:906:943:b0:818:3ef8:f2fc with SMTP id j3-20020a170906094300b008183ef8f2fcmr5725992ejd.5.1671476289501; Mon, 19 Dec 2022 10:58:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671476289; cv=none; d=google.com; s=arc-20160816; b=otI3UGdb4f6xS27yjKAiWtW//1ZomZcYsgU3+Lb8luSXSf/23u6B9e67xWBqA3pJ3p ZVHHqGQ74uiTzmZCaBNu/5W5ys/0mFlno7htH2CA0hLfDePbUko2NtAnhJdZ4d9dcNKX nSK3o4Omgk0LtiMgBhqYFLBhwiguYOwgXei3cSfqzXpzK3B2tJUMHYk2jYXBeOpALFvk XFYi5DfhoS2VIZK6Tifwa7W9rKe9wSITph6ucnZNGT2C7aQsNYLKoNayPsn4JYhaUNeJ POyuRqbwy1nBTm6Ji+qqvqozLxpL2xbPp18zO9QBJ4WI4+IWrs8k39OhF4rog+7e60+z 4rBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:subject:cc:to:from:date :user-agent:message-id; bh=CfyEE4rnASVltVJAD/Hr6918HuCgME1WrqPkWyT/iHo=; b=c2RTPC/+1RGiCB5GWG4xMtIUTToqsTw9Wnu39fDVZJJ0xu2Lz1aENrpOGl2JX/G3Uq d8eshZ4WX52sFDLSlfTNJXdRCMjakMOz/9LB0CdcnBZBmf/xumeAcjERoW4aQqSJMr6Q XBiCYzOLfTudYn0oIk6CKaHfFFVB1eOs70DzJdCZv01PxLjBLF+4fy3EB4JHFNd30Jmo 3RYAAa4FNJH6BtOC+sa7xJKCc/67D9dysAbRfP06Km8ii+yebOfBqu3VCMhJvKnIbo5P 0TbvckLneJwpkjh3ZCgIRaDDB7hSzW0rCno4HOuGGhkREBFXFnAuqmwHiMhIqLJZsOPR Ilkw== ARC-Authentication-Results: i=1; mx.google.com; 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 Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ga27-20020a1709070c1b00b007c0abf0760fsi10485041ejc.54.2022.12.19.10.57.46; Mon, 19 Dec 2022 10:58:09 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232678AbiLSSfQ (ORCPT + 99 others); Mon, 19 Dec 2022 13:35:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232288AbiLSSe3 (ORCPT ); Mon, 19 Dec 2022 13:34:29 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A363E13F91; Mon, 19 Dec 2022 10:32:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5A346B80D84; Mon, 19 Dec 2022 18:32:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 15D3DC433F1; Mon, 19 Dec 2022 18:32:15 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1p7Kvu-0005T5-0B; Mon, 19 Dec 2022 13:32:14 -0500 Message-ID: <20221219183213.916833763@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 19 Dec 2022 13:31:07 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler , Tom Zanussi , Zheng Yejian Subject: [PATCH 1/2] tracing: Add a way to filter function addresses to function names References: <20221219183106.518341498@goodmis.org> MIME-Version: 1.0 X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752213220634337125?= X-GMAIL-MSGID: =?utf-8?q?1752669921650310135?= From: "Steven Rostedt (Google)" There's been several times where an event records a function address in its field and I needed to filter on that address for a specific function name. It required looking up the function in kallsyms, finding its size, and doing a compare of "field >= function_start && field < function_end". But this would change from boot to boot and is unreliable in scripts. Also, it is useful to have this at boot up, where the addresses will not be known. For example, on the boot command line: trace_trigger="initcall_finish.traceoff if func.function == acpi_init" To implement this, add a ".function" prefix, that will check that the field is of size long, and the only operations allowed (so far) are "==" and "!=". Signed-off-by: Steven Rostedt (Google) Reviewed-by: Ross Zwisler --- Documentation/trace/events.rst | 12 ++++ kernel/trace/trace_events.c | 2 +- kernel/trace/trace_events_filter.c | 93 +++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/Documentation/trace/events.rst b/Documentation/trace/events.rst index c47f381d0c00..d0fd5c7220b7 100644 --- a/Documentation/trace/events.rst +++ b/Documentation/trace/events.rst @@ -207,6 +207,18 @@ field name:: As the kernel will have to know how to retrieve the memory that the pointer is at from user space. +You can convert any long type to a function address and search by function name:: + + call_site.function == security_prepare_creds + +The above will filter when the field "call_site" falls on the address within +"security_prepare_creds". That is, it will compare the value of "call_site" and +the filter will return true if it is greater than or equal to the start of +the function "security_prepare_creds" and less than the end of that function. + +The ".function" postfix can only be attached to values of size long, and can only +be compared with "==" or "!=". + 5.2 Setting filters ------------------- diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 33e0b4f8ebe6..b07931ad97de 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2822,7 +2822,7 @@ static __init int setup_trace_triggers(char *str) if (!trigger) break; bootup_triggers[i].event = strsep(&trigger, "."); - bootup_triggers[i].trigger = strsep(&trigger, "."); + bootup_triggers[i].trigger = trigger; if (!bootup_triggers[i].trigger) break; } diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 96acc2b71ac7..996b3c458c1a 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -64,6 +64,7 @@ enum filter_pred_fn { FILTER_PRED_FN_PCHAR_USER, FILTER_PRED_FN_PCHAR, FILTER_PRED_FN_CPU, + FILTER_PRED_FN_FUNCTION, FILTER_PRED_FN_, FILTER_PRED_TEST_VISITED, }; @@ -71,6 +72,7 @@ enum filter_pred_fn { struct filter_pred { enum filter_pred_fn fn_num; u64 val; + u64 val2; struct regex regex; unsigned short *ops; struct ftrace_event_field *field; @@ -103,6 +105,7 @@ struct filter_pred { C(INVALID_FILTER, "Meaningless filter expression"), \ C(IP_FIELD_ONLY, "Only 'ip' field is supported for function trace"), \ C(INVALID_VALUE, "Invalid value (did you forget quotes)?"), \ + C(NO_FUNCTION, "Function not found"), \ C(ERRNO, "Error"), \ C(NO_FILTER, "No filter found") @@ -876,6 +879,17 @@ static int filter_pred_comm(struct filter_pred *pred, void *event) return cmp ^ pred->not; } +/* Filter predicate for functions. */ +static int filter_pred_function(struct filter_pred *pred, void *event) +{ + unsigned long *addr = (unsigned long *)(event + pred->offset); + unsigned long start = (unsigned long)pred->val; + unsigned long end = (unsigned long)pred->val2; + int ret = *addr >= start && *addr < end; + + return pred->op == OP_EQ ? ret : !ret; +} + /* * regex_match_foo - Basic regex callbacks * @@ -1335,6 +1349,8 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event) return filter_pred_pchar(pred, event); case FILTER_PRED_FN_CPU: return filter_pred_cpu(pred, event); + case FILTER_PRED_FN_FUNCTION: + return filter_pred_function(pred, event); case FILTER_PRED_TEST_VISITED: return test_pred_visited_fn(pred, event); default: @@ -1350,8 +1366,13 @@ static int parse_pred(const char *str, void *data, struct trace_event_call *call = data; struct ftrace_event_field *field; struct filter_pred *pred = NULL; + unsigned long offset; + unsigned long size; + unsigned long ip; char num_buf[24]; /* Big enough to hold an address */ char *field_name; + char *name; + bool function = false; bool ustring = false; char q; u64 val; @@ -1393,6 +1414,12 @@ static int parse_pred(const char *str, void *data, i += len; } + /* See if the field is a kernel function name */ + if ((len = str_has_prefix(str + i, ".function"))) { + function = true; + i += len; + } + while (isspace(str[i])) i++; @@ -1423,7 +1450,71 @@ static int parse_pred(const char *str, void *data, pred->offset = field->offset; pred->op = op; - if (ftrace_event_is_function(call)) { + if (function) { + /* The field must be the same size as long */ + if (field->size != sizeof(long)) { + parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i); + goto err_free; + } + + /* Function only works with '==' or '!=' and an unquoted string */ + switch (op) { + case OP_NE: + case OP_EQ: + break; + default: + parse_error(pe, FILT_ERR_INVALID_OP, pos + i); + goto err_free; + } + + if (isdigit(str[i])) { + /* We allow 0xDEADBEEF */ + while (isalnum(str[i])) + i++; + + len = i - s; + /* 0xfeedfacedeadbeef is 18 chars max */ + if (len >= sizeof(num_buf)) { + parse_error(pe, FILT_ERR_OPERAND_TOO_LONG, pos + i); + goto err_free; + } + + strncpy(num_buf, str + s, len); + num_buf[len] = 0; + + ret = kstrtoul(num_buf, 0, &ip); + if (ret) { + parse_error(pe, FILT_ERR_INVALID_VALUE, pos + i); + goto err_free; + } + } else { + s = i; + for (; str[i] && !isspace(str[i]); i++) + ; + + len = i - s; + name = kmemdup_nul(str + s, len, GFP_KERNEL); + if (!name) + goto err_mem; + ip = kallsyms_lookup_name(name); + kfree(name); + if (!ip) { + parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i); + goto err_free; + } + } + + /* Now find the function start and end address */ + if (!kallsyms_lookup_size_offset(ip, &size, &offset)) { + parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i); + goto err_free; + } + + pred->fn_num = FILTER_PRED_FN_FUNCTION; + pred->val = ip - offset; + pred->val2 = pred->val + size; + + } else if (ftrace_event_is_function(call)) { /* * Perf does things different with function events. * It only allows an "ip" field, and expects a string. From patchwork Mon Dec 19 18:31:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 34690 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp2554419wrn; Mon, 19 Dec 2022 10:42:10 -0800 (PST) X-Google-Smtp-Source: AMrXdXvAwGnj/g4v79VQ3mdoR0NoGCs7TJawY3ybZIrG+RdBr4EFG6rpvCbSc9SFPcWmf1HokwOd X-Received: by 2002:aa7:d7d4:0:b0:46c:9a5d:239e with SMTP id e20-20020aa7d7d4000000b0046c9a5d239emr19513758eds.13.1671475329868; Mon, 19 Dec 2022 10:42:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671475329; cv=none; d=google.com; s=arc-20160816; b=m0zhHxErzSA9Ry5dqELXGRLHffoHOvkGjoLr+/2+xXgakyyZBK+dsqvcVQX0wKPiaR jMmx3rTwNqQ9cvsJn1MMiWDsfu9pRxTjG3eOnIiSM/0Yd0dUSSUh7zT7EpaselnrYa9R XSge8Jdwa/nYoyOO9AWnhzaKlQRaSWPWp+Bq+nXaOYiP4APfZ87ZylhcykVD5FuJsuQp NpLoU8iNE/fQjZF9y52wgIGOgQOW8vU79C3nEUcOf+wdYPXp+qIGTkJLxrWqYaDxa2cL UrEKlm3aW/3CXnm4oH1LljLjRCi1ec7edpP1HvT5vTwNGxYMPvMMSAn8L6HkK+E10a+1 43wA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:subject:cc:to:from:date :user-agent:message-id; bh=Sn/OcFpxGNDXNl/pKTYnahkoq6uTxg/iAJOQaDNJ5jo=; b=c1pQMcnw4E3Z2OlIeRgmsUhZejx8V6Tr+83theBpIMADMQAcBAn6g/Hz6ojX3W5zIK KZlqIrWtezofDmPxjvUW0xgsAHvZcIt85JrkO1XU4z/Mvt9zoUinwSpdwZCpRWGqNP2b R2xfwt3OJnH5rtaMsIrnDB91e4CeSbY95guMdVDnoSZGwpaC0tOwjoWLLBbXJqZZ4OA7 Vcv1bFLt2CW5PqOYJ/QJCs8QEtdLY0hakDspSaxWQXuqtGSE7FkIjbNb6Num3hpYjaE9 2vd3qgBGVfIjRtb09Cm5UXQhPG8g8LWydw2AaxBZbKZKa44J9AD+v+3tkqeyo8Sy3jkn 7OaQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cy24-20020a0564021c9800b0046eff871046si8310243edb.367.2022.12.19.10.41.45; Mon, 19 Dec 2022 10:42:09 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232348AbiLSSfU (ORCPT + 99 others); Mon, 19 Dec 2022 13:35:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232655AbiLSSe3 (ORCPT ); Mon, 19 Dec 2022 13:34:29 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A565213FAB; Mon, 19 Dec 2022 10:32:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 60C1FB80F6F; Mon, 19 Dec 2022 18:32:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CF6BC4339B; Mon, 19 Dec 2022 18:32:15 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1p7Kvu-0005TZ-0g; Mon, 19 Dec 2022 13:32:14 -0500 Message-ID: <20221219183214.075559302@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 19 Dec 2022 13:31:08 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler , Tom Zanussi , Zheng Yejian , Shuah Khan , Shuah Khan , linux-kselftest@vger.kernel.org Subject: [PATCH 2/2] tracing/selftests: Add test for event filtering on function name References: <20221219183106.518341498@goodmis.org> MIME-Version: 1.0 X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752668915644634219?= X-GMAIL-MSGID: =?utf-8?q?1752668915644634219?= From: "Steven Rostedt (Google)" With the new filter logic of passing in the name of a function to match an instruction pointer (or the address of the function), add a test to make sure that it is functional. This is also the first test to test plain filtering. The filtering has been tested via the trigger logic, which uses the same code, but there was nothing to test just the event filter, so this test is the first to add such a case. Cc: Shuah Khan Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Suggested-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Reviewed-by: Ross Zwisler Acked-by: Shuah Khan --- .../test.d/filter/event-filter-function.tc | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc diff --git a/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc new file mode 100644 index 000000000000..e2ff3bf4df80 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc @@ -0,0 +1,58 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: event filter function - test event filtering on functions +# requires: set_event events/kmem/kmem_cache_free/filter +# flags: instance + +fail() { #msg + echo $1 + exit_fail +} + +echo "Test event filter function name" +echo 0 > tracing_on +echo 0 > events/enable +echo > trace +echo 'call_site.function == exit_mmap' > events/kmem/kmem_cache_free/filter +echo 1 > events/kmem/kmem_cache_free/enable +echo 1 > tracing_on +ls > /dev/null +echo 0 > events/kmem/kmem_cache_free/enable + +hitcnt=`grep kmem_cache_free trace| grep exit_mmap | wc -l` +misscnt=`grep kmem_cache_free trace| grep -v exit_mmap | wc -l` + +if [ $hitcnt -eq 0 ]; then + exit_fail +fi + +if [ $misscnt -gt 0 ]; then + exit_fail +fi + +address=`grep ' exit_mmap$' /proc/kallsyms | cut -d' ' -f1` + +echo "Test event filter function address" +echo 0 > tracing_on +echo 0 > events/enable +echo > trace +echo "call_site.function == 0x$address" > events/kmem/kmem_cache_free/filter +echo 1 > events/kmem/kmem_cache_free/enable +echo 1 > tracing_on +sleep 1 +echo 0 > events/kmem/kmem_cache_free/enable + +hitcnt=`grep kmem_cache_free trace| grep exit_mmap | wc -l` +misscnt=`grep kmem_cache_free trace| grep -v exit_mmap | wc -l` + +if [ $hitcnt -eq 0 ]; then + exit_fail +fi + +if [ $misscnt -gt 0 ]; then + exit_fail +fi + +reset_events_filter + +exit 0