diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-19 13:10:20 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-19 13:10:20 +0200 |
commit | a2b4426c1bb1b80fb0b97b47e32b993bbbb47fe8 (patch) | |
tree | c782709c81b0a6d01d76317136ef18d1f848d79a | |
parent | ac400d38bcc8201524b344e5b0322f7be3165402 (diff) | |
download | stable-queue-a2b4426c1bb1b80fb0b97b47e32b993bbbb47fe8.tar.gz |
5.10-stable patches
added patches:
kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch
-rw-r--r-- | queue-5.10/kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch | 77 | ||||
-rw-r--r-- | queue-5.10/series | 1 |
2 files changed, 78 insertions, 0 deletions
diff --git a/queue-5.10/kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch b/queue-5.10/kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch new file mode 100644 index 0000000000..054c4059c0 --- /dev/null +++ b/queue-5.10/kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch @@ -0,0 +1,77 @@ +From 325f3fb551f8cd672dbbfc4cf58b14f9ee3fc9e8 Mon Sep 17 00:00:00 2001 +From: Zheng Yejian <zhengyejian1@huawei.com> +Date: Wed, 10 Apr 2024 09:58:02 +0800 +Subject: kprobes: Fix possible use-after-free issue on kprobe registration + +From: Zheng Yejian <zhengyejian1@huawei.com> + +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@huawei.com/ + +Fixes: 28f6c37a2910 ("kprobes: Forbid probing on trampoline and BPF code areas") +Cc: stable@vger.kernel.org +Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com> +Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> +[Fix conflict due to lack dependency +commit 223a76b268c9 ("kprobes: Fix coding style issues")] +Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + kernel/kprobes.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1647,10 +1647,17 @@ static int check_kprobe_address_safe(str + 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(str + 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 diff --git a/queue-5.10/series b/queue-5.10/series index 451079d919..8fead0b133 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -32,3 +32,4 @@ riscv-enable-per-task-stack-canaries.patch riscv-process-fix-kernel-gp-leakage.patch ring-buffer-only-update-pages_touched-when-a-new-pag.patch selftests-ftrace-limit-length-in-subsystem-enable-tests.patch +kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch |