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
This commit is contained in:
+12
-6
@@ -1567,10 +1567,17 @@ static int check_kprobe_address_safe(struct kprobe *p,
|
||||
jump_label_lock();
|
||||
preempt_disable();
|
||||
|
||||
/* Ensure it is not in reserved area nor out of text */
|
||||
if (!(core_kernel_text((unsigned long) p->addr) ||
|
||||
is_module_text_address((unsigned long) p->addr)) ||
|
||||
in_gate_area_no_mm((unsigned long) p->addr) ||
|
||||
/* Ensure the address is in a text area, and find a module if exists. */
|
||||
*probed_mod = NULL;
|
||||
if (!core_kernel_text((unsigned long) p->addr)) {
|
||||
*probed_mod = __module_text_address((unsigned long) p->addr);
|
||||
if (!(*probed_mod)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Ensure it is not in reserved area. */
|
||||
if (in_gate_area_no_mm((unsigned long) p->addr) ||
|
||||
within_kprobe_blacklist((unsigned long) p->addr) ||
|
||||
jump_label_text_reserved(p->addr, p->addr) ||
|
||||
static_call_text_reserved(p->addr, p->addr) ||
|
||||
@@ -1580,8 +1587,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check if 'p' is probing a module. */
|
||||
*probed_mod = __module_text_address((unsigned long) p->addr);
|
||||
/* Get module refcount and reject __init functions for loaded modules. */
|
||||
if (*probed_mod) {
|
||||
/*
|
||||
* We must hold a refcount of the probed module while updating
|
||||
|
||||
Reference in New Issue
Block a user