Skip to content

Commit e8c39d0

Browse files
committed
Merge tag 'probes-fixes-v6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull probes fixes from Masami Hiramatsu: "Fix possible use-after-free issue on kprobe registration. check_kprobe_address_safe() uses `is_module_text_address()` and `__module_text_address()` separately. As a result, if the probed address is in a module that is being unloaded, the first `is_module_text_address()` might return true but then the `__module_text_address()` call might return NULL if the module has been unloaded between the two. The result is that kprobe believes the probe is on the kernel text, and skips getting a module reference. In this case, when it arms a breakpoint on the probe address, it may cause a use-after-free. To fix this issue, only use `__module_text_address()` once and get a reference to the module then. If it fails, reject the probe" * tag 'probes-fixes-v6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: kprobes: Fix possible use-after-free issue on kprobe registration
2 parents 03a55b6 + 325f3fb commit e8c39d0

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

kernel/kprobes.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,10 +1567,17 @@ static int check_kprobe_address_safe(struct kprobe *p,
15671567
jump_label_lock();
15681568
preempt_disable();
15691569

1570-
/* Ensure it is not in reserved area nor out of text */
1571-
if (!(core_kernel_text((unsigned long) p->addr) ||
1572-
is_module_text_address((unsigned long) p->addr)) ||
1573-
in_gate_area_no_mm((unsigned long) p->addr) ||
1570+
/* Ensure the address is in a text area, and find a module if exists. */
1571+
*probed_mod = NULL;
1572+
if (!core_kernel_text((unsigned long) p->addr)) {
1573+
*probed_mod = __module_text_address((unsigned long) p->addr);
1574+
if (!(*probed_mod)) {
1575+
ret = -EINVAL;
1576+
goto out;
1577+
}
1578+
}
1579+
/* Ensure it is not in reserved area. */
1580+
if (in_gate_area_no_mm((unsigned long) p->addr) ||
15741581
within_kprobe_blacklist((unsigned long) p->addr) ||
15751582
jump_label_text_reserved(p->addr, p->addr) ||
15761583
static_call_text_reserved(p->addr, p->addr) ||
@@ -1580,8 +1587,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
15801587
goto out;
15811588
}
15821589

1583-
/* Check if 'p' is probing a module. */
1584-
*probed_mod = __module_text_address((unsigned long) p->addr);
1590+
/* Get module refcount and reject __init functions for loaded modules. */
15851591
if (*probed_mod) {
15861592
/*
15871593
* We must hold a refcount of the probed module while updating

0 commit comments

Comments
 (0)