mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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/20230517034510.15639-4-zegao@tencent.com/
Fixes: 5b0ab78998
("fprobe: Add exit_handler support")
Signed-off-by: Ze Gao <zegao@tencent.com>
Cc: stable@vger.kernel.org
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
This commit is contained in:
parent
3cc4e2c5fb
commit
2752741080
@ -17,6 +17,7 @@
|
||||
struct fprobe_rethook_node {
|
||||
struct rethook_node node;
|
||||
unsigned long entry_ip;
|
||||
unsigned long entry_parent_ip;
|
||||
char data[];
|
||||
};
|
||||
|
||||
@ -39,6 +40,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip,
|
||||
}
|
||||
fpr = container_of(rh, struct fprobe_rethook_node, node);
|
||||
fpr->entry_ip = ip;
|
||||
fpr->entry_parent_ip = parent_ip;
|
||||
if (fp->entry_data_size)
|
||||
entry_data = fpr->data;
|
||||
}
|
||||
@ -114,14 +116,26 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data,
|
||||
{
|
||||
struct fprobe *fp = (struct fprobe *)data;
|
||||
struct fprobe_rethook_node *fpr;
|
||||
int bit;
|
||||
|
||||
if (!fp || fprobe_disabled(fp))
|
||||
return;
|
||||
|
||||
fpr = container_of(rh, struct fprobe_rethook_node, node);
|
||||
|
||||
/*
|
||||
* we need to assure no calls to traceable functions in-between the
|
||||
* end of fprobe_handler and the beginning of fprobe_exit_handler.
|
||||
*/
|
||||
bit = ftrace_test_recursion_trylock(fpr->entry_ip, fpr->entry_parent_ip);
|
||||
if (bit < 0) {
|
||||
fp->nmissed++;
|
||||
return;
|
||||
}
|
||||
|
||||
fp->exit_handler(fp, fpr->entry_ip, regs,
|
||||
fp->entry_data_size ? (void *)fpr->data : NULL);
|
||||
ftrace_test_recursion_unlock(bit);
|
||||
}
|
||||
NOKPROBE_SYMBOL(fprobe_exit_handler);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user