Skip to content

Commit 868a6fc

Browse files
Yang Jihongmhiramat
authored andcommitted
x86/kprobes: Fix __recover_optprobed_insn check optimizing logic
Since the following commit: commit f66c044 ("kprobes: Set unoptimized flag after unoptimizing code") modified the update timing of the KPROBE_FLAG_OPTIMIZED, a optimized_kprobe may be in the optimizing or unoptimizing state when op.kp->flags has KPROBE_FLAG_OPTIMIZED and op->list is not empty. The __recover_optprobed_insn check logic is incorrect, a kprobe in the unoptimizing state may be incorrectly determined as unoptimizing. As a result, incorrect instructions are copied. The optprobe_queued_unopt function needs to be exported for invoking in arch directory. Link: https://lore.kernel.org/all/[email protected]/ Fixes: f66c044 ("kprobes: Set unoptimized flag after unoptimizing code") Cc: [email protected] Signed-off-by: Yang Jihong <[email protected]> Acked-by: Masami Hiramatsu (Google) <[email protected]> Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
1 parent 4fbd2f8 commit 868a6fc

File tree

3 files changed

+4
-3
lines changed

3 files changed

+4
-3
lines changed

arch/x86/kernel/kprobes/opt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr)
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
}

include/linux/kprobes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs);
378378
DEFINE_INSN_CACHE_OPS(optinsn);
379379

380380
extern void wait_for_kprobe_optimizer(void);
381+
bool optprobe_queued_unopt(struct optimized_kprobe *op);
381382
#else /* !CONFIG_OPTPROBES */
382383
static inline void wait_for_kprobe_optimizer(void) { }
383384
#endif /* CONFIG_OPTPROBES */

kernel/kprobes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ void wait_for_kprobe_optimizer(void)
660660
mutex_unlock(&kprobe_mutex);
661661
}
662662

663-
static bool optprobe_queued_unopt(struct optimized_kprobe *op)
663+
bool optprobe_queued_unopt(struct optimized_kprobe *op)
664664
{
665665
struct optimized_kprobe *_op;
666666

0 commit comments

Comments
 (0)