From patchwork Wed Oct 26 15:48:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 11317 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp350457wru; Wed, 26 Oct 2022 09:00:39 -0700 (PDT) X-Google-Smtp-Source: AMsMyM77Oy+JOgzrHRsgfGb5AeQ6h/4rSHPYMQP7oqHScuMSy8Q7O7MxZvaqp0/1yEqjSgorg8Lf X-Received: by 2002:a17:907:2be9:b0:7a1:11a9:1334 with SMTP id gv41-20020a1709072be900b007a111a91334mr10040088ejc.131.1666800039188; Wed, 26 Oct 2022 09:00:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666800039; cv=none; d=google.com; s=arc-20160816; b=07VBmKow78kzOfmCKDty5c9aEHy4RJ81h+lL9FQD4kJycoLyLKwt7r1UxZgz2C0Q49 qnc+JaYR00Qv/Q52aUYP4aabOv7dnw13a4BXvGet85xN8a5eityxNfF/L9cPZUxO+Lu+ dNGephCsXdTpa7tabv/Zfz8lwYb4ALBFtGQaZgfBfTksHWv3Q5fxcPnDeRDINRibIYfw Nyy/Yq0ECd/9R+ZkP+d1NwymqMuv+ZQ8caRFClF/rNPMLGBat2ysOiQ1iBAY8FIZ2Zd3 GKwm4zJz+FqUMH34fsGJ0e1NDzMEzhScJkhzlUCl5fN34Suz/9DUMQM62KXbonDRgyb+ jKNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=GkOc9gqTFdoE2t/iHpiQYf9Y9SRI2DfVU36CkoAmL7k=; b=MJaHxTt9r7OnhuZsDHtpm7XPPX9/Yq+4fRCqge5Dd+f4q0kUqc/pQ5ouvIS0vL5yCO D9UWmbQC008Fv8EeBzSAJZL1v1l4FgL7j2bOjpvxX0GzxZf5vN2XFV1HIss2+/nxaNJ9 DRV56JMt4CmdbeVCjTmTATWBi9YJI/hN6IodWU0CI1Q5InQLjyaCkxEVjZ6hoA9W35s5 jpmAHkz5o6OuEbxneYrO/0DLAOSGYBhO7opod9n0MKnnT5iI4jiRdSDU7c+rKqLzPbru rnZjg7w/wInMi0VpVs1HonpNbw40vT0lUX3X00zyHbS0KDtuds4N9hLbtFliIaOEvf71 PkhA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=O53RH0Aj; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id dz21-20020a0564021d5500b0045902845795si7600152edb.557.2022.10.26.09.00.13; Wed, 26 Oct 2022 09:00:39 -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=@kernel.org header.s=k20201202 header.b=O53RH0Aj; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233856AbiJZPsj (ORCPT + 99 others); Wed, 26 Oct 2022 11:48:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233745AbiJZPsg (ORCPT ); Wed, 26 Oct 2022 11:48:36 -0400 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3D62B56D8; Wed, 26 Oct 2022 08:48:34 -0700 (PDT) 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 sin.source.kernel.org (Postfix) with ESMTPS id 65A51CE231C; Wed, 26 Oct 2022 15:48:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6A217C433C1; Wed, 26 Oct 2022 15:48:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666799311; bh=XOrn7EyGRuSgSXcm6qYGnOr4PubedOVQu+6MpHzXgFs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O53RH0AjGrzKZF4s+foUOhUGu78JPNKuX/Z0XzptPMOTFPW88zU0A3ztjnemePJhX Ph/tE198xk8FdclBBNsVEFwxyuSft17syrkroUAVFT32N3vBiP7NHp9yRnIELhvimB 3OfhnIGtV3IJIi3oxMdlt0PS3u8XtYXgQ6+yAvY1JOtJ+Py1d9jZT+hhcnwJxDC4gL g+PSs2v7ZNmcjrhw6ksRU/EHyaZWxsOv44JjvRlCCeFHulQzENxH9YxPttS4nuVNhR xglbqHWvAs+yISRy8yUpexA+RLBsVJuDrfYh0iutfSyXqppZsCA4EA0CkZVdU6hMdK yYUYpwEes2L3w== From: "Masami Hiramatsu (Google)" To: LKML Cc: Steven Rostedt , Linux Trace Kernel , Masami Hiramatsu , Primiano Tucci Subject: [PATCH v2 1/2] tracing/probes: Add symstr type for dynamic events Date: Thu, 27 Oct 2022 00:48:28 +0900 Message-Id: <166679930847.1528100.4124308529180235965.stgit@devnote3> X-Mailer: git-send-email 2.38.0.135.g90850a2211-goog In-Reply-To: <166679929981.1528100.11309260111368557859.stgit@devnote3> References: <166679929981.1528100.11309260111368557859.stgit@devnote3> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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?1747766517924051095?= X-GMAIL-MSGID: =?utf-8?q?1747766517924051095?= From: Masami Hiramatsu (Google) Add 'symstr' type for storing the kernel symbol as a string data instead of the symbol address. This allows us to filter the events by wildcard symbol name. e.g. # echo 'e:wqfunc workqueue.workqueue_execute_start symname=$function:symstr' >> dynamic_events # cat events/eprobes/wqfunc/format name: wqfunc ID: 2110 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:__data_loc char[] symname; offset:8; size:4; signed:1; print fmt: " symname=\"%s\"", __get_str(symname) Note that there is already 'symbol' type which just change the print format (so it still stores the symbol address in the tracing ring buffer.) On the other hand, 'symstr' type stores the actual "symbol+offset/size" data as a string. Signed-off-by: Masami Hiramatsu (Google) --- Changes in v2: - Remove redundant strlen(). --- Documentation/trace/kprobetrace.rst | 8 ++++-- kernel/trace/trace.c | 2 + kernel/trace/trace_probe.c | 44 ++++++++++++++++++++++----------- kernel/trace/trace_probe.h | 16 ++++++++---- kernel/trace/trace_probe_tmpl.h | 47 +++++++++++++++++++++++++++++++++-- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst index 4274cc6a2f94..08a2a6a3782f 100644 --- a/Documentation/trace/kprobetrace.rst +++ b/Documentation/trace/kprobetrace.rst @@ -58,8 +58,8 @@ Synopsis of kprobe_events NAME=FETCHARG : Set NAME as the argument name of FETCHARG. FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types - (x8/x16/x32/x64), "string", "ustring" and bitfield - are supported. + (x8/x16/x32/x64), "string", "ustring", "symbol", "symstr" + and bitfield are supported. (\*1) only for the probe on function entry (offs == 0). (\*2) only for return probe. @@ -96,6 +96,10 @@ offset, and container-size (usually 32). The syntax is:: Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG) which shows given pointer in "symbol+offset" style. +On the other hand, symbol-string type ('symstr') converts the given address to +"symbol+offset/symbolsize" style and stores it as a null-terminated string. +With 'symstr' type, you can filter the event with wildcard pattern of the +symbols, and you don't need to solve symbol name by yourself. For $comm, the default type is "string"; any other type is invalid. .. _user_mem_access: diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 47a44b055a1d..80aae336cc19 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5608,7 +5608,7 @@ static const char readme_msg[] = "\t +|-[u](), \\imm-value, \\\"imm-string\"\n" "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t b@/, ustring,\n" - "\t \\[\\]\n" + "\t symstr, \\[\\]\n" #ifdef CONFIG_HIST_TRIGGERS "\t field: ;\n" "\t stype: u8/u16/u32/u64, s8/s16/s32/s64, pid_t,\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 36dff277de46..dfec4af857b4 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -76,9 +76,11 @@ const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; /* Fetch type information table */ static const struct fetch_type probe_fetch_types[] = { /* Special types */ - __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, + __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, 1, "__data_loc char[]"), - __ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1, + __ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1, 1, + "__data_loc char[]"), + __ASSIGN_FETCH_TYPE("symstr", string, string, sizeof(u32), 1, 1, "__data_loc char[]"), /* Basic types */ ASSIGN_FETCH_TYPE(u8, u8, 0), @@ -662,16 +664,26 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, ret = -EINVAL; /* Store operation */ - if (!strcmp(parg->type->name, "string") || - !strcmp(parg->type->name, "ustring")) { - if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF && - code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM && - code->op != FETCH_OP_DATA && code->op != FETCH_OP_TP_ARG) { - trace_probe_log_err(offset + (t ? (t - arg) : 0), - BAD_STRING); - goto fail; + if (parg->type->is_string) { + if (!strcmp(parg->type->name, "symstr")) { + if (code->op != FETCH_OP_REG && code->op != FETCH_OP_STACK && + code->op != FETCH_OP_RETVAL && code->op != FETCH_OP_ARG && + code->op != FETCH_OP_DEREF && code->op != FETCH_OP_TP_ARG) { + trace_probe_log_err(offset + (t ? (t - arg) : 0), + BAD_SYMSTRING); + goto fail; + } + } else { + if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF && + code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM && + code->op != FETCH_OP_DATA && code->op != FETCH_OP_TP_ARG) { + trace_probe_log_err(offset + (t ? (t - arg) : 0), + BAD_STRING); + goto fail; + } } - if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM || + if (!strcmp(parg->type->name, "symstr") || + (code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM || code->op == FETCH_OP_DATA) || code->op == FETCH_OP_TP_ARG || parg->count) { /* @@ -679,6 +691,8 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, * must be kept, and if parg->count != 0, this is an * array of string pointers instead of string address * itself. + * For the symstr, it doesn't need to dereference, thus + * it just get the value. */ code++; if (code->op != FETCH_OP_NOP) { @@ -690,6 +704,8 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, if (!strcmp(parg->type->name, "ustring") || code->op == FETCH_OP_UDEREF) code->op = FETCH_OP_ST_USTRING; + else if (!strcmp(parg->type->name, "symstr")) + code->op = FETCH_OP_ST_SYMSTR; else code->op = FETCH_OP_ST_STRING; code->size = parg->type->size; @@ -919,8 +935,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, for (i = 0; i < tp->nr_args; i++) { parg = tp->args + i; if (parg->count) { - if ((strcmp(parg->type->name, "string") == 0) || - (strcmp(parg->type->name, "ustring") == 0)) + if (parg->type->is_string) fmt = ", __get_str(%s[%d])"; else fmt = ", REC->%s[%d]"; @@ -928,8 +943,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, pos += snprintf(buf + pos, LEN_OR_ZERO, fmt, parg->name, j); } else { - if ((strcmp(parg->type->name, "string") == 0) || - (strcmp(parg->type->name, "ustring") == 0)) + if (parg->type->is_string) fmt = ", __get_str(%s)"; else fmt = ", REC->%s"; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index de38f1c03776..0838b74f403b 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -98,6 +98,7 @@ enum fetch_op { FETCH_OP_ST_UMEM, /* Mem: .offset, .size */ FETCH_OP_ST_STRING, /* String: .offset, .size */ FETCH_OP_ST_USTRING, /* User String: .offset, .size */ + FETCH_OP_ST_SYMSTR, /* Kernel Symbol String: .offset, .size */ // Stage 4 (modify) op FETCH_OP_MOD_BF, /* Bitfield: .basesize, .lshift, .rshift */ // Stage 5 (loop) op @@ -133,7 +134,8 @@ struct fetch_insn { struct fetch_type { const char *name; /* Name of type */ size_t size; /* Byte size of type */ - int is_signed; /* Signed flag */ + bool is_signed; /* Signed flag */ + bool is_string; /* String flag */ print_type_func_t print; /* Print functions */ const char *fmt; /* Format string */ const char *fmttype; /* Name in format file */ @@ -177,16 +179,19 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(symbol); #define _ADDR_FETCH_TYPE(t) __ADDR_FETCH_TYPE(t) #define ADDR_FETCH_TYPE _ADDR_FETCH_TYPE(BITS_PER_LONG) -#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ - {.name = _name, \ +#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, str, _fmttype) \ + {.name = _name, \ .size = _size, \ - .is_signed = sign, \ + .is_signed = (bool)sign, \ + .is_string = (bool)str, \ .print = PRINT_TYPE_FUNC_NAME(ptype), \ .fmt = PRINT_TYPE_FMT_NAME(ptype), \ .fmttype = _fmttype, \ } + +/* Non string types can use these macros */ #define _ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ - __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, #_fmttype) + __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, 0, #_fmttype) #define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \ _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, ptype) @@ -431,6 +436,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, C(ARRAY_TOO_BIG, "Array number is too big"), \ C(BAD_TYPE, "Unknown type is specified"), \ C(BAD_STRING, "String accepts only memory argument"), \ + C(BAD_SYMSTRING, "Symbol String doesn't accept data/userdata"), \ C(BAD_BITFIELD, "Invalid bitfield"), \ C(ARG_NAME_TOO_LONG, "Argument name is too long"), \ C(NO_ARG_NAME, "Argument name is not specified"), \ diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h index b3bdb8ddb862..5cea672243f6 100644 --- a/kernel/trace/trace_probe_tmpl.h +++ b/kernel/trace/trace_probe_tmpl.h @@ -67,6 +67,37 @@ probe_mem_read(void *dest, void *src, size_t size); static nokprobe_inline int probe_mem_read_user(void *dest, void *src, size_t size); +static nokprobe_inline int +fetch_store_symstrlen(unsigned long addr) +{ + char namebuf[KSYM_SYMBOL_LEN]; + int ret; + + ret = sprint_symbol(namebuf, addr); + if (ret < 0) + return 0; + + return ret + 1; +} + +/* + * Fetch a null-terminated symbol string + offset. Caller MUST set *(u32 *)buf + * with max length and relative data location. + */ +static nokprobe_inline int +fetch_store_symstring(unsigned long addr, void *dest, void *base) +{ + int maxlen = get_loc_len(*(u32 *)dest); + void *__dest; + + if (unlikely(!maxlen)) + return -ENOMEM; + + __dest = get_loc_data(dest, base); + + return sprint_symbol(__dest, addr); +} + /* From the 2nd stage, routine is same */ static nokprobe_inline int process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, @@ -99,16 +130,22 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, stage3: /* 3rd stage: store value to buffer */ if (unlikely(!dest)) { - if (code->op == FETCH_OP_ST_STRING) { + switch (code->op) { + case FETCH_OP_ST_STRING: ret = fetch_store_strlen(val + code->offset); code++; goto array; - } else if (code->op == FETCH_OP_ST_USTRING) { + case FETCH_OP_ST_USTRING: ret += fetch_store_strlen_user(val + code->offset); code++; goto array; - } else + case FETCH_OP_ST_SYMSTR: + ret += fetch_store_symstrlen(val + code->offset); + code++; + goto array; + default: return -EILSEQ; + } } switch (code->op) { @@ -129,6 +166,10 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, loc = *(u32 *)dest; ret = fetch_store_string_user(val + code->offset, dest, base); break; + case FETCH_OP_ST_SYMSTR: + loc = *(u32 *)dest; + ret = fetch_store_symstring(val + code->offset, dest, base); + break; default: return -EILSEQ; } From patchwork Wed Oct 26 15:48:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 11316 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp349481wru; Wed, 26 Oct 2022 08:58:36 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5BX6tRR3M0A5/JQHLUo7Dt4oXzaVSBdgr+e/iKffnsIPHMuaLdRkqJCQ8s5kduuBVR2tzW X-Received: by 2002:a05:6a00:c89:b0:56c:3772:5f83 with SMTP id a9-20020a056a000c8900b0056c37725f83mr7156198pfv.74.1666799915885; Wed, 26 Oct 2022 08:58:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666799915; cv=none; d=google.com; s=arc-20160816; b=zsH3PJFKImeSSvInN74PXUhhSGhEhY8Wp0OXkr20A9O2MfauLYRaaEgSihbAoPWQr8 yF6p80uQoYJEdBr5YoVw6ok6EvdJ0mKR8f3C6q0OvrbHnFd3WjD+EevgMtHlR5aybJ5J SxsHwSVPSvRHsTk8rFvNnHN4PH3S2Rp5ACih7NdIPyy2WsW6udaiScCTohL5GbM6rHyn 9oFdO7MHKZApjDZydlch76H6iAXCu1tINhMhz79dJM20VEtBBx0aiPCFxPsGUExcZ4H1 NMvlQ3PWWNCbXICTrMzrM5hADXBvq61tLzwbZ8ahB1eL80JU9ZrRobbhiUFMT7vIstt3 xTLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4p5yi8UyW9vOsOGW2+NDbbbMXd4BZ2xc9KEpNX8dmwk=; b=EngHlT3qnZkD1VI963eUsVpO0ey3cAEHQGNB1qE7FYmCj3pDfRJ42zZf61ixgMFF09 +ABh83eqt5uuYSKlBVZnhXqXLl5CQKECo2mZiat8tMCeqMxpjEmtYPbwhc9LQzM/1lzf N5rKPinr98A2A7QLbUrsb0on1wlfwyLJ7UCZTO0U6z0vSrX9sNp7XelQw6MPb3W6xeCm dgEXRGhPeuMOi4pqF2m8tHet4nltMom69X3VG92Ba20ewJnadJDaQJJm6p4ICV8vi/vb VdUpm0UxxYsHUzbD7ghubap9xMuNsakfJ7u6mEzCztN/mXmQ+cjmXmE2Zusaq9j/hcR9 04+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QbkHDSCw; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x14-20020a63310e000000b0045075b52a0fsi7649484pgx.534.2022.10.26.08.58.21; Wed, 26 Oct 2022 08:58:35 -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=@kernel.org header.s=k20201202 header.b=QbkHDSCw; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233318AbiJZPst (ORCPT + 99 others); Wed, 26 Oct 2022 11:48:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233663AbiJZPsn (ORCPT ); Wed, 26 Oct 2022 11:48:43 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40713B488F; Wed, 26 Oct 2022 08:48:42 -0700 (PDT) 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 E72B9B82344; Wed, 26 Oct 2022 15:48:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F189C43470; Wed, 26 Oct 2022 15:48:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666799319; bh=sX2VmN8QIAfNUi3ehGzCa1UcNn8eoXtW++VSPOl7vVk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QbkHDSCwnYyR/TgpFq+jGc2Y6i3FFrkj4mMkK5eytAslQwuAXdJVjh2cAc6LaVrCs yVbewnkkEflINbWrv1btIkUqOnFJ5cUymjuOqfC7BHdhZxyvWgYI9QPv3Fgm+0ATdO 0ekjuIAe99BVxfkfziBzawSLqPeZYREaEVxFnMxbPGSrEg/8RJoOBHt77w1So14Tna 2YPNYb0l7MIReOi2oOc4u7iUtn8LFqa++0vZK3aOUfQXVl17Xh+jGkPyvmc6pyZIsl 5jucngEwhSgHOKRcMGArtObJvOT7R/qUKv7uhuTKTLe+Pigxymf3VsMf5qB8mLNmiY STZqgKjeMNHWA== From: "Masami Hiramatsu (Google)" To: LKML Cc: Steven Rostedt , Linux Trace Kernel , Masami Hiramatsu , Primiano Tucci Subject: [PATCH v2 2/2] tracing/probes: Reject symbol/symstr type for uprobe Date: Thu, 27 Oct 2022 00:48:36 +0900 Message-Id: <166679931679.1528100.15540755370726009882.stgit@devnote3> X-Mailer: git-send-email 2.38.0.135.g90850a2211-goog In-Reply-To: <166679929981.1528100.11309260111368557859.stgit@devnote3> References: <166679929981.1528100.11309260111368557859.stgit@devnote3> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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?1747766388692574982?= X-GMAIL-MSGID: =?utf-8?q?1747766388692574982?= From: Masami Hiramatsu (Google) Since uprobe's argument must contain the user-space data, that should not be converted to kernel symbols. Reject if user specifies these types on uprobe events. e.g. /sys/kernel/debug/tracing # echo 'p /bin/sh:10 %ax:symbol' >> uprobe_events sh: write error: Invalid argument /sys/kernel/debug/tracing # echo 'p /bin/sh:10 %ax:symstr' >> uprobe_events sh: write error: Invalid argument /sys/kernel/debug/tracing # cat error_log [ 1783.134883] trace_uprobe: error: Unknown type is specified Command: p /bin/sh:10 %ax:symbol ^ [ 1792.201120] trace_uprobe: error: Unknown type is specified Command: p /bin/sh:10 %ax:symstr ^ Signed-off-by: Masami Hiramatsu (Google) --- Changes in v2: - Fixes indentation. --- kernel/trace/trace_probe.c | 21 ++++++++++++-------- kernel/trace/trace_probe.h | 3 ++- kernel/trace/trace_uprobe.c | 3 ++- .../ftrace/test.d/kprobe/uprobe_syntax_errors.tc | 5 +++++ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index dfec4af857b4..960bb7693a84 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -100,10 +100,15 @@ static const struct fetch_type probe_fetch_types[] = { ASSIGN_FETCH_TYPE_END }; -static const struct fetch_type *find_fetch_type(const char *type) +static const struct fetch_type *find_fetch_type(const char *type, unsigned long flags) { int i; + /* Reject the symbol/symstr for uprobes */ + if (type && (flags & TPARG_FL_USER) && + (!strcmp(type, "symbol") || !strcmp(type, "symstr"))) + return NULL; + if (!type) type = DEFAULT_FETCH_TYPE_STR; @@ -121,13 +126,13 @@ static const struct fetch_type *find_fetch_type(const char *type) switch (bs) { case 8: - return find_fetch_type("u8"); + return find_fetch_type("u8", flags); case 16: - return find_fetch_type("u16"); + return find_fetch_type("u16", flags); case 32: - return find_fetch_type("u32"); + return find_fetch_type("u32", flags); case 64: - return find_fetch_type("u64"); + return find_fetch_type("u64", flags); default: goto fail; } @@ -480,7 +485,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, DEREF_OPEN_BRACE); return -EINVAL; } else { - const struct fetch_type *t2 = find_fetch_type(NULL); + const struct fetch_type *t2 = find_fetch_type(NULL, flags); *tmp = '\0'; ret = parse_probe_arg(arg, t2, &code, end, flags, offs); @@ -632,9 +637,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, /* The type of $comm must be "string", and not an array. */ if (parg->count || (t && strcmp(t, "string"))) goto out; - parg->type = find_fetch_type("string"); + parg->type = find_fetch_type("string", flags); } else - parg->type = find_fetch_type(t); + parg->type = find_fetch_type(t, flags); if (!parg->type) { trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE); goto out; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 0838b74f403b..23acfd1c3812 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -358,7 +358,8 @@ int trace_probe_create(const char *raw_command, int (*createfn)(int, const char #define TPARG_FL_KERNEL BIT(1) #define TPARG_FL_FENTRY BIT(2) #define TPARG_FL_TPOINT BIT(3) -#define TPARG_FL_MASK GENMASK(3, 0) +#define TPARG_FL_USER BIT(4) +#define TPARG_FL_MASK GENMASK(4, 0) extern int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, const char *argv, unsigned int flags); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index fb58e86dd117..8d64b6553aed 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -691,7 +691,8 @@ static int __trace_uprobe_create(int argc, const char **argv) for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { trace_probe_log_set_index(i + 2); ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], - is_return ? TPARG_FL_RETURN : 0); + (is_return ? TPARG_FL_RETURN : 0) | + TPARG_FL_USER); if (ret) goto error; } diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc index f5e3f9e4a01f..c817158b99db 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc @@ -23,4 +23,9 @@ check_error 'p /bin/sh:10^%hoge' # BAD_ADDR_SUFFIX check_error 'p /bin/sh:10(10)^%return' # BAD_REFCNT_SUFFIX fi +# symstr is not supported by uprobe +if grep -q ".*symstr.*" README; then +check_error 'p /bin/sh:10 $stack0:^symstr' # BAD_TYPE +fi + exit 0