Patch "kprobes: Fix possible use-after-free issue on kprobe registration" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    kprobes: Fix possible use-after-free issue on kprobe registration

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     kprobes-fix-possible-use-after-free-issue-on-kprobe-.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit eafe098bc555680560db39b534bec118e2a005c6
Author: Zheng Yejian <zhengyejian1@xxxxxxxxxx>
Date:   Wed Apr 10 09:58:02 2024 +0800

    kprobes: Fix possible use-after-free issue on kprobe registration
    
    commit 325f3fb551f8cd672dbbfc4cf58b14f9ee3fc9e8 upstream.
    
    When unloading a module, its state is changing MODULE_STATE_LIVE ->
     MODULE_STATE_GOING -> MODULE_STATE_UNFORMED. Each change will take
    a time. `is_module_text_address()` and `__module_text_address()`
    works with MODULE_STATE_LIVE and MODULE_STATE_GOING.
    If we use `is_module_text_address()` and `__module_text_address()`
    separately, there is a chance that the first one is succeeded but the
    next one is failed because module->state becomes MODULE_STATE_UNFORMED
    between those operations.
    
    In `check_kprobe_address_safe()`, if the second `__module_text_address()`
    is failed, that is ignored because it expected a kernel_text address.
    But it may have failed simply because module->state has been changed
    to MODULE_STATE_UNFORMED. In this case, arm_kprobe() will try to modify
    non-exist module text address (use-after-free).
    
    To fix this problem, we should not use separated `is_module_text_address()`
    and `__module_text_address()`, but use only `__module_text_address()`
    once and do `try_module_get(module)` which is only available with
    MODULE_STATE_LIVE.
    
    Link: https://lore.kernel.org/all/20240410015802.265220-1-zhengyejian1@xxxxxxxxxx/
    
    Fixes: 28f6c37a2910 ("kprobes: Forbid probing on trampoline and BPF code areas")
    Cc: stable@xxxxxxxxxxxxxxx
    Signed-off-by: Zheng Yejian <zhengyejian1@xxxxxxxxxx>
    Signed-off-by: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>
    [Fix conflict due to lack dependency
    commit 223a76b268c9 ("kprobes: Fix coding style issues")]
    Signed-off-by: Zheng Yejian <zhengyejian1@xxxxxxxxxx>
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 05d3e156a7d63..dba6541c0fc3c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1647,10 +1647,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) ||
@@ -1660,8 +1667,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
 		goto out;
 	}
 
-	/* Check if are we 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




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux