History

Merge tag 'probes-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull kprobes updates from Masami Hiramatsu: - Skip negative return code check for snprintf in eprobe - Add recursive call test cases for kprobe unit test - Add 'char' type to probe events to show it as the character instead of value - Update kselftest kprobe-event testcase to ignore '__pfx_' symbols - Fix kselftest to check filter on eprobe event correctly - Add filter on eprobe to the README file in tracefs - Fix optprobes to check whether there is 'under unoptimizing' optprobe when optimizing another kprobe correctly - Fix optprobe to check whether there is 'under unoptimizing' optprobe when fetching the original instruction correctly - Fix optprobe to free 'forcibly unoptimized' optprobe correctly * tag 'probes-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing/eprobe: no need to check for negative ret value for snprintf test_kprobes: Add recursed kprobe test case tracing/probe: add a char type to show the character value of traced arguments selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols selftests/ftrace: Fix eprobe syntax test case to check filter support tracing/eprobe: Fix to add filter on eprobe description in README file x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe range x86/kprobes: Fix __recover_optprobed_insn check optimizing logic kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list

Linus Torvalds committed 3 years ago

Commit 2b79eb72 parents 0df8218 c96abae12 files · +117 −33Browse files

Unified · Split

12 files
  1. Documentation/trace/kprobetrace.rst +3 −1
  2. arch/x86/kernel/kprobes/opt.c +3 −3
  3. include/linux/kprobes.h +2 −0
  4. kernel/kprobes.c +12 −15
  5. kernel/trace/trace.c +2 −2
  6. kernel/trace/trace_eprobe.c +4 −8
  7. kernel/trace/trace_probe.c +2 −0
  8. kernel/trace/trace_probe.h +1 −0
  9. lib/test_kprobes.c +37 −2
  10. tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc +3 −1
  11. tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc +47 −0
  12. tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc +1 −1
Documentation/trace/kprobetrace.rst+3−1
@@ -58,7 +58,7 @@ Synopsis of kprobe_events · 57 unmodified lines
5858 NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
5959 FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
6060 (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
61− (x8/x16/x32/x64), "string", "ustring", "symbol", "symstr"
61+ (x8/x16/x32/x64), "char", "string", "ustring", "symbol", "symstr"
6262 and bitfield are supported.
6363
6464 (\*1) only for the probe on function entry (offs == 0).
@@ -82,6 +82,8 @@ Note that the array can be applied to memory type fetchargs, you can not · 17 unmodified lines
8282 apply it to registers/stack-entries etc. (for example, '$stack1:x8[8]' is
8383 wrong, but '+8($stack):x8[8]' is OK.)
8484
85+Char type can be used to show the character value of traced arguments.
86+
8587 String type is a special type, which fetches a "null-terminated" string from
8688 kernel space. This means it will fail and store NULL if the string container
8789 has been paged out. "ustring" type is an alternative of string for user-space.
arch/x86/kernel/kprobes/opt.c+3−3
@@ -46,8 +46,8 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr) · 45 unmodified lines
4646 /* This function only handles jump-optimized kprobe */
4747 if (kp && kprobe_optimized(kp)) {
4848 op = container_of(kp, struct optimized_kprobe, kp);
49− /* If op->list is not empty, op is under optimizing */
50− if (list_empty(&op->list))
49+ /* If op is optimized or under unoptimizing */
50+ if (list_empty(&op->list) || optprobe_queued_unopt(op))
5151 goto found;
5252 }
5353 }
@@ -353,7 +353,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op) · 299 unmodified lines
353353
354354 for (i = 1; i < op->optinsn.size; i++) {
355355 p = get_kprobe(op->kp.addr + i);
356− if (p && !kprobe_disabled(p))
356+ if (p && !kprobe_disarmed(p))
357357 return -EEXIST;
358358 }
359359
include/linux/kprobes.h+2−0
@@ -378,6 +378,8 @@ extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs); · 377 unmodified lines
378378 DEFINE_INSN_CACHE_OPS(optinsn);
379379
380380 extern void wait_for_kprobe_optimizer(void);
381+bool optprobe_queued_unopt(struct optimized_kprobe *op);
382+bool kprobe_disarmed(struct kprobe *p);
381383 #else /* !CONFIG_OPTPROBES */
382384 static inline void wait_for_kprobe_optimizer(void) { }
383385 #endif /* CONFIG_OPTPROBES */
kernel/kprobes.c+12−15
@@ -458,7 +458,7 @@ static inline int kprobe_optready(struct kprobe *p) · 457 unmodified lines
458458 }
459459
460460 /* Return true if the kprobe is disarmed. Note: p must be on hash list */
461−static inline bool kprobe_disarmed(struct kprobe *p)
461+bool kprobe_disarmed(struct kprobe *p)
462462 {
463463 struct optimized_kprobe *op;
464464
@@ -555,17 +555,15 @@ static void do_unoptimize_kprobes(void) · 90 unmodified lines
555555 /* See comment in do_optimize_kprobes() */
556556 lockdep_assert_cpus_held();
557557
558− /* Unoptimization must be done anytime */
559− if (list_empty(&unoptimizing_list))
560− return;
558+ if (!list_empty(&unoptimizing_list))
559+ arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
561560
562− arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
563− /* Loop on 'freeing_list' for disarming */
561+ /* Loop on 'freeing_list' for disarming and removing from kprobe hash list */
564562 list_for_each_entry_safe(op, tmp, &freeing_list, list) {
565563 /* Switching from detour code to origin */
566564 op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
567− /* Disarm probes if marked disabled */
568− if (kprobe_disabled(&op->kp))
565+ /* Disarm probes if marked disabled and not gone */
566+ if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp))
569567 arch_disarm_kprobe(&op->kp);
570568 if (kprobe_unused(&op->kp)) {
571569 /*
@@ -662,7 +660,7 @@ void wait_for_kprobe_optimizer(void) · 90 unmodified lines
662660 mutex_unlock(&kprobe_mutex);
663661 }
664662
665−static bool optprobe_queued_unopt(struct optimized_kprobe *op)
663+bool optprobe_queued_unopt(struct optimized_kprobe *op)
666664 {
667665 struct optimized_kprobe *_op;
668666
@@ -797,14 +795,13 @@ static void kill_optimized_kprobe(struct kprobe *p) · 128 unmodified lines
797795 op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
798796
799797 if (kprobe_unused(p)) {
800− /* Enqueue if it is unused */
801− list_add(&op->list, &freeing_list);
802798 /*
803− * Remove unused probes from the hash list. After waiting
804− * for synchronization, this probe is reclaimed.
805− * (reclaiming is done by do_free_cleaned_kprobes().)
799+ * Unused kprobe is on unoptimizing or freeing list. We move it
800+ * to freeing_list and let the kprobe_optimizer() remove it from
801+ * the kprobe hash list and free it.
806802 */
807− hlist_del_rcu(&op->kp.hlist);
803+ if (optprobe_queued_unopt(op))
804+ list_move(&op->list, &freeing_list);
808805 }
809806
810807 /* Don't touch the code, because it is already freed. */
kernel/trace/trace.c+2−2
@@ -5646,7 +5646,7 @@ static const char readme_msg[] = · 5645 unmodified lines
56465646 #ifdef CONFIG_HIST_TRIGGERS
56475647 "\t s:[synthetic/]<event> <field> [<field>]\n"
56485648 #endif
5649− "\t e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]\n"
5649+ "\t e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>] [if <filter>]\n"
56505650 "\t -:[<group>/][<event>]\n"
56515651 #ifdef CONFIG_KPROBE_EVENTS
56525652 "\t place: [<module>:]<symbol>[+<offset>]|<memaddr>\n"
@@ -5663,7 +5663,7 @@ static const char readme_msg[] = · 10 unmodified lines
56635663 "\t $stack<index>, $stack, $retval, $comm,\n"
56645664 #endif
56655665 "\t +|-[u]<offset>(<fetcharg>), \\imm-value, \\\"imm-string\"\n"
5666− "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n"
5666+ "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, char, string, symbol,\n"
56675667 "\t b<bit-width>@<bit-offset>/<container-size>, ustring,\n"
56685668 "\t symstr, <type>\\[<array-size>\\]\n"
56695669 #ifdef CONFIG_HIST_TRIGGERS
kernel/trace/trace_eprobe.c+4−8
@@ -923,17 +923,13 @@ static int trace_eprobe_parse_filter(struct trace_eprobe *ep, int argc, const ch · 922 unmodified lines
923923
924924 p = ep->filter_str;
925925 for (i = 0; i < argc; i++) {
926− ret = snprintf(p, len, "%s ", argv[i]);
927− if (ret < 0)
928− goto error;
929− if (ret > len) {
930− ret = -E2BIG;
931− goto error;
932− }
926+ if (i)
927+ ret = snprintf(p, len, " %s", argv[i]);
928+ else
929+ ret = snprintf(p, len, "%s", argv[i]);
933930 p += ret;
934931 len -= ret;
935932 }
936− p[-1] = '\0';
937933
938934 /*
939935 * Ensure the filter string can be parsed correctly. Note, this
kernel/trace/trace_probe.c+2−0
@@ -50,6 +50,7 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x8, u8, "0x%x") · 49 unmodified lines
5050 DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x")
5151 DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x")
5252 DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx")
53+DEFINE_BASIC_PRINT_TYPE_FUNC(char, u8, "'%c'")
5354
5455 int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent)
5556 {
@@ -95,6 +96,7 @@ static const struct fetch_type probe_fetch_types[] = { · 39 unmodified lines
9596 ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
9697 ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
9798 ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
99+ ASSIGN_FETCH_TYPE_ALIAS(char, u8, u8, 0),
98100 ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0),
99101
100102 ASSIGN_FETCH_TYPE_END
kernel/trace/trace_probe.h+1−0
@@ -166,6 +166,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(x16); · 165 unmodified lines
166166 DECLARE_BASIC_PRINT_TYPE_FUNC(x32);
167167 DECLARE_BASIC_PRINT_TYPE_FUNC(x64);
168168
169+DECLARE_BASIC_PRINT_TYPE_FUNC(char);
169170 DECLARE_BASIC_PRINT_TYPE_FUNC(string);
170171 DECLARE_BASIC_PRINT_TYPE_FUNC(symbol);
171172
lib/test_kprobes.c+37−2
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414
1515 static u32 rand1, preh_val, posth_val;
1616 static u32 (*target)(u32 value);
17+static u32 (*recursed_target)(u32 value);
1718 static u32 (*target2)(u32 value);
1819 static struct kunit *current_test;
1920
@@ -27,18 +28,27 @@ static noinline u32 kprobe_target(u32 value) · 7 unmodified lines
2728 return (value / div_factor);
2829 }
2930
31+static noinline u32 kprobe_recursed_target(u32 value)
32+{
33+ return (value / div_factor);
34+}
35+
3036 static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
3137 {
3238 KUNIT_EXPECT_FALSE(current_test, preemptible());
33− preh_val = (rand1 / div_factor);
39+
40+ preh_val = recursed_target(rand1);
3441 return 0;
3542 }
3643
3744 static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
3845 unsigned long flags)
3946 {
47+ u32 expval = recursed_target(rand1);
48+
4049 KUNIT_EXPECT_FALSE(current_test, preemptible());
41− KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor));
50+ KUNIT_EXPECT_EQ(current_test, preh_val, expval);
51+
4252 posth_val = preh_val + div_factor;
4353 }
4454
@@ -136,6 +146,29 @@ static void test_kprobes(struct kunit *test) · 91 unmodified lines
136146 unregister_kprobes(kps, 2);
137147 }
138148
149+static struct kprobe kp_missed = {
150+ .symbol_name = "kprobe_recursed_target",
151+ .pre_handler = kp_pre_handler,
152+ .post_handler = kp_post_handler,
153+};
154+
155+static void test_kprobe_missed(struct kunit *test)
156+{
157+ current_test = test;
158+ preh_val = 0;
159+ posth_val = 0;
160+
161+ KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp_missed));
162+
163+ recursed_target(rand1);
164+
165+ KUNIT_EXPECT_EQ(test, 2, kp_missed.nmissed);
166+ KUNIT_EXPECT_NE(test, 0, preh_val);
167+ KUNIT_EXPECT_NE(test, 0, posth_val);
168+
169+ unregister_kprobe(&kp_missed);
170+}
171+
139172 #ifdef CONFIG_KRETPROBES
140173 static u32 krph_val;
141174
@@ -336,6 +369,7 @@ static int kprobes_test_init(struct kunit *test) · 194 unmodified lines
336369 {
337370 target = kprobe_target;
338371 target2 = kprobe_target2;
372+ recursed_target = kprobe_recursed_target;
339373 stacktrace_target = kprobe_stacktrace_target;
340374 internal_target = kprobe_stacktrace_internal_target;
341375 stacktrace_driver = kprobe_stacktrace_driver;
@@ -346,6 +380,7 @@ static int kprobes_test_init(struct kunit *test) · 4 unmodified lines
346380 static struct kunit_case kprobes_testcases[] = {
347381 KUNIT_CASE(test_kprobe),
348382 KUNIT_CASE(test_kprobes),
383+ KUNIT_CASE(test_kprobe_missed),
349384 #ifdef CONFIG_KRETPROBES
350385 KUNIT_CASE(test_kretprobe),
351386 KUNIT_CASE(test_kretprobes),
tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc+3−1
@@ -22,6 +22,8 @@ check_error 'e:foo/^bar.1 syscalls/sys_enter_openat' # BAD_EVENT_NAME · 21 unmodified lines
2222 check_error 'e:foo/bar syscalls/sys_enter_openat arg=^dfd' # BAD_FETCH_ARG
2323 check_error 'e:foo/bar syscalls/sys_enter_openat ^arg=$foo' # BAD_ATTACH_ARG
2424
25−check_error 'e:foo/bar syscalls/sys_enter_openat if ^' # NO_EP_FILTER
25+if grep -q '<attached-group>\.<attached-event>.*\[if <filter>\]' README; then
26+ check_error 'e:foo/bar syscalls/sys_enter_openat if ^' # NO_EP_FILTER
27+fi
2628
2729 exit 0
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc+47−0
@@ -0,0 +1,47 @@
1+#!/bin/sh
2+# SPDX-License-Identifier: GPL-2.0
3+# description: Kprobe event char type argument
4+# requires: kprobe_events
5+
6+case `uname -m` in
7+x86_64)
8+ ARG1=%di
9+;;
10+i[3456]86)
11+ ARG1=%ax
12+;;
13+aarch64)
14+ ARG1=%x0
15+;;
16+arm*)
17+ ARG1=%r0
18+;;
19+ppc64*)
20+ ARG1=%r3
21+;;
22+ppc*)
23+ ARG1=%r3
24+;;
25+s390*)
26+ ARG1=%r2
27+;;
28+mips*)
29+ ARG1=%r4
30+;;
31+*)
32+ echo "Please implement other architecture here"
33+ exit_untested
34+esac
35+
36+: "Test get argument (1)"
37+echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):char" > kprobe_events
38+echo 1 > events/kprobes/testprobe/enable
39+echo "p:test $FUNCTION_FORK" >> kprobe_events
40+grep -qe "testprobe.* arg1='t'" trace
41+
42+echo 0 > events/kprobes/testprobe/enable
43+: "Test get argument (2)"
44+echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):char arg2=+0(${ARG1}):char[4]" > kprobe_events
45+echo 1 > events/kprobes/testprobe/enable
46+echo "p:test $FUNCTION_FORK" >> kprobe_events
47+grep -qe "testprobe.* arg1='t' arg2={'t','e','s','t'}" trace
tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc+1−1
@@ -21,7 +21,7 @@ set_offs() { # prev target next · 20 unmodified lines
2121
2222 # We have to decode symbol addresses to get correct offsets.
2323 # If the offset is not an instruction boundary, it cause -EILSEQ.
24−set_offs `grep -A1 -B1 ${TARGET_FUNC} /proc/kallsyms | cut -f 1 -d " " | xargs`
24+set_offs `grep -v __pfx_ /proc/kallsyms | grep -A1 -B1 ${TARGET_FUNC} | cut -f 1 -d " " | xargs`
2525
2626 UINT_TEST=no
2727 # printf "%x" -1 returns (unsigned long)-1.