Skip to content

Commit 2752741

Browse files
zegao96mhiramat
authored andcommitted
fprobe: add recursion detection in fprobe_exit_handler
fprobe_hander and fprobe_kprobe_handler has guarded ftrace recursion detection but fprobe_exit_handler has not, which possibly introduce recursive calls if the fprobe exit callback calls any traceable functions. Checking in fprobe_hander or fprobe_kprobe_handler is not enough and misses this case. So add recursion free guard the same way as fprobe_hander. Since ftrace recursion check does not employ ip(s), so here use entry_ip and entry_parent_ip the same as fprobe_handler. Link: https://lore.kernel.org/all/[email protected]/ Fixes: 5b0ab78 ("fprobe: Add exit_handler support") Signed-off-by: Ze Gao <[email protected]> Cc: [email protected] Acked-by: Masami Hiramatsu (Google) <[email protected]> Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
1 parent 3cc4e2c commit 2752741

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

kernel/trace/fprobe.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
struct fprobe_rethook_node {
1818
struct rethook_node node;
1919
unsigned long entry_ip;
20+
unsigned long entry_parent_ip;
2021
char data[];
2122
};
2223

@@ -39,6 +40,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip,
3940
}
4041
fpr = container_of(rh, struct fprobe_rethook_node, node);
4142
fpr->entry_ip = ip;
43+
fpr->entry_parent_ip = parent_ip;
4244
if (fp->entry_data_size)
4345
entry_data = fpr->data;
4446
}
@@ -114,14 +116,26 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data,
114116
{
115117
struct fprobe *fp = (struct fprobe *)data;
116118
struct fprobe_rethook_node *fpr;
119+
int bit;
117120

118121
if (!fp || fprobe_disabled(fp))
119122
return;
120123

121124
fpr = container_of(rh, struct fprobe_rethook_node, node);
122125

126+
/*
127+
* we need to assure no calls to traceable functions in-between the
128+
* end of fprobe_handler and the beginning of fprobe_exit_handler.
129+
*/
130+
bit = ftrace_test_recursion_trylock(fpr->entry_ip, fpr->entry_parent_ip);
131+
if (bit < 0) {
132+
fp->nmissed++;
133+
return;
134+
}
135+
123136
fp->exit_handler(fp, fpr->entry_ip, regs,
124137
fp->entry_data_size ? (void *)fpr->data : NULL);
138+
ftrace_test_recursion_unlock(bit);
125139
}
126140
NOKPROBE_SYMBOL(fprobe_exit_handler);
127141

0 commit comments

Comments
 (0)