From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@kernel.org>,
Menglong Dong <menglong8.dong@gmail.com>
Cc: jolsa@kernel.org, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, kees@kernel.org, samitolvanen@google.com,
rppt@kernel.org, luto@kernel.org, mhiramat@kernel.org,
ast@kernel.org, andrii@kernel.org, linux-kernel@vger.kernel.org,
bpf@vger.kernel.org
Subject: [PATCH v2 2/2] lib/test_fprobe: Add recursion check test cases
Date: Mon, 22 Sep 2025 15:35:33 +0900 [thread overview]
Message-ID: <175852293339.307379.8831172703363408291.stgit@devnote2> (raw)
In-Reply-To: <175852291163.307379.14414635977719513326.stgit@devnote2>
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Add test cases for checking recursion level must be less than 2.
This ensures that fprobe can prevent infinite recursive call by
itself.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
lib/tests/test_fprobe.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 90 insertions(+), 2 deletions(-)
diff --git a/lib/tests/test_fprobe.c b/lib/tests/test_fprobe.c
index cf92111b5c79..0022da242a83 100644
--- a/lib/tests/test_fprobe.c
+++ b/lib/tests/test_fprobe.c
@@ -17,8 +17,10 @@ static u32 rand1, entry_val, exit_val;
/* Use indirect calls to avoid inlining the target functions */
static u32 (*target)(u32 value);
static u32 (*target2)(u32 value);
+static u32 (*target3)(u32 value);
static unsigned long target_ip;
static unsigned long target2_ip;
+static unsigned long target3_ip;
static int entry_return_value;
static noinline u32 fprobe_selftest_target(u32 value)
@@ -31,13 +33,18 @@ static noinline u32 fprobe_selftest_target2(u32 value)
return (value / div_factor) + 1;
}
+static noinline u32 fprobe_selftest_target3(u32 value)
+{
+ return (value / div_factor) + 2;
+}
+
static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
unsigned long ret_ip,
struct ftrace_regs *fregs, void *data)
{
KUNIT_EXPECT_FALSE(current_test, preemptible());
/* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */
- if (ip != target_ip)
+ if (ip != target_ip && ip != target3_ip)
KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
entry_val = (rand1 / div_factor);
if (fp->entry_data_size) {
@@ -190,6 +197,84 @@ static void test_fprobe_skip(struct kunit *test)
KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
}
+static int recur_count;
+static int recur_high;
+
+static notrace int fp_recur_entry_handler(struct fprobe *fp, unsigned long ip,
+ unsigned long ret_ip,
+ struct ftrace_regs *fregs, void *data)
+{
+ /* fgraph/fprobe allows one-level nesting. */
+ if (recur_count > 1)
+ return 0;
+
+ recur_count++;
+ if (recur_count > recur_high)
+ recur_high = recur_count;
+ target3(rand1);
+ recur_count--;
+
+ return 0;
+}
+
+static notrace void fp_recur_exit_handler(struct fprobe *fp, unsigned long ip,
+ unsigned long ret_ip,
+ struct ftrace_regs *fregs, void *data)
+{
+ /* fgraph/fprobe allows one-level nesting. */
+ if (recur_count > 1)
+ return;
+
+ recur_count++;
+ if (recur_count > recur_high)
+ recur_high = recur_count;
+ target3(rand1);
+ recur_count--;
+}
+
+static void test_fprobe_recursion_entry(struct kunit *test)
+{
+ struct fprobe fp = {
+ .entry_handler = fp_recur_entry_handler,
+ };
+ struct fprobe fp3 = {
+ .entry_handler = fp_recur_entry_handler,
+ };
+
+ current_test = test;
+ recur_count = 0;
+ recur_high = 0;
+ KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
+ KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp3, "fprobe_selftest_target3", NULL));
+
+ target(rand1);
+
+ KUNIT_EXPECT_LE(test, recur_high, 2);
+ KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp3));
+ KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+static void test_fprobe_recursion_exit(struct kunit *test)
+{
+ struct fprobe fp = {
+ .exit_handler = fp_recur_exit_handler,
+ };
+ struct fprobe fp3 = {
+ .exit_handler = fp_recur_exit_handler,
+ };
+
+ current_test = test;
+ recur_count = 0;
+ KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
+ KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp3, "fprobe_selftest_target3", NULL));
+
+ target(rand1);
+
+ KUNIT_EXPECT_LE(test, recur_high, 2);
+ KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp3));
+ KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
static unsigned long get_ftrace_location(void *func)
{
unsigned long size, addr = (unsigned long)func;
@@ -205,8 +290,10 @@ static int fprobe_test_init(struct kunit *test)
rand1 = get_random_u32_above(div_factor);
target = fprobe_selftest_target;
target2 = fprobe_selftest_target2;
+ target3 = fprobe_selftest_target3;
target_ip = get_ftrace_location(target);
target2_ip = get_ftrace_location(target2);
+ target3_ip = get_ftrace_location(target3);
return 0;
}
@@ -217,6 +304,8 @@ static struct kunit_case fprobe_testcases[] = {
KUNIT_CASE(test_fprobe_syms),
KUNIT_CASE(test_fprobe_data),
KUNIT_CASE(test_fprobe_skip),
+ KUNIT_CASE(test_fprobe_recursion_entry),
+ KUNIT_CASE(test_fprobe_recursion_exit),
{}
};
@@ -227,4 +316,3 @@ static struct kunit_suite fprobe_test_suite = {
};
kunit_test_suites(&fprobe_test_suite);
-
prev parent reply other threads:[~2025-09-22 6:35 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-22 6:35 [PATCH v2 0/2] tracing: fprobe: Protect return handler from recursion loop Masami Hiramatsu (Google)
2025-09-22 6:35 ` [PATCH v2 1/2] tracing: fgraph: " Masami Hiramatsu (Google)
2025-09-22 8:01 ` menglong.dong
2025-09-24 15:34 ` Masami Hiramatsu
2025-09-25 7:26 ` Steven Rostedt
2025-09-27 12:57 ` Steven Rostedt
2025-09-28 12:56 ` Steven Rostedt
2025-09-29 0:02 ` Masami Hiramatsu
2025-09-22 6:35 ` Masami Hiramatsu (Google) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=175852293339.307379.8831172703363408291.stgit@devnote2 \
--to=mhiramat@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jolsa@kernel.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=menglong8.dong@gmail.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@kernel.org \
--cc=rppt@kernel.org \
--cc=samitolvanen@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.