Probes fixes for v6.9-rc3:

- kprobes: Fix possible use-after-free issue on kprobe registration. Since
   check_kprobe_address_safe() uses `is_module_text_address()` and
   `__module_text_address()` separately, if the probe address is on an
   unloading module, the first `is_module_text_address()` return true but
   the second `__module_text_address()` returns NULL (module is unloaded
   between them). Thus it expects the probe is on the kernel text, and
   skips to get the module reference. In this case, when it arms a breakpoint
   on the probe address, it may cause a use-after-free problem.
   To fix this issue, we only use `__module_text_address()` once and tries
   to get reference of the module, if it fails, reject the probe.
 -----BEGIN PGP SIGNATURE-----
 
 iQFPBAABCgA5FiEEh7BulGwFlgAOi5DV2/sHvwUrPxsFAmYWrOEbHG1hc2FtaS5o
 aXJhbWF0c3VAZ21haWwuY29tAAoJENv7B78FKz8b9ugIAKBeaLfuhoa45V/XZ+If
 GyIvXnmldj8e0U6fCQL58rFdzHfjUMt2X7r8sQrMgjVhRHbtE1SnKqOOi/NNMb6Z
 2KOESX73xj94ohG0ydSEYP/W1QVyDByMxAIRGpmKAmAnt+7GA76iCQrcgwYirTFV
 okgnldJvH0RNm4xIuD4YAQMJnYXg9WJFxaA127uI/JGCzw7R4OBQ9i2PaSS4oXYr
 ZZhH2x+D6fcwFY5Sr5ApAcIQfvfk6IG5xLHu981r93Y/BncorIi8I4MtaZFvoWwQ
 SdCi85KPG1R99rok/54Lm4tfPPQa8oNMBiImIcF5iCzC/CUh6GEn5tCifefV/UmW
 7i0=
 =PVv1
 -----END PGP SIGNATURE-----

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:
Linus Torvalds 2024-04-10 19:48:05 -07:00
commit e8c39d0f57

View File

@ -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