mbox series

[SRU,F,0/3] CVE-2024-38588

Message ID 20241025133110.2839066-1-koichiro.den@canonical.com
Headers show
Series CVE-2024-38588 | expand

Message

Koichiro Den Oct. 25, 2024, 1:31 p.m. UTC
[Impact]

ftrace: Fix possible use-after-free issue in ftrace_location()
KASAN reports a bug:

  BUG: KASAN: use-after-free in ftrace_location+0x90/0x120
  Read of size 8 at addr ffff888141d40010 by task insmod/424
  CPU: 8 PID: 424 Comm: insmod Tainted: G        W          6.9.0-rc2+
  [...]
  Call Trace:
   <TASK>
   dump_stack_lvl+0x68/0xa0
   print_report+0xcf/0x610
   kasan_report+0xb5/0xe0
   ftrace_location+0x90/0x120
   register_kprobe+0x14b/0xa40
   kprobe_init+0x2d/0xff0 [kprobe_example]
   do_one_initcall+0x8f/0x2d0
   do_init_module+0x13a/0x3c0
   load_module+0x3082/0x33d0
   init_module_from_file+0xd2/0x130
   __x64_sys_finit_module+0x306/0x440
   do_syscall_64+0x68/0x140
   entry_SYSCALL_64_after_hwframe+0x71/0x79

The root cause is that, in lookup_rec(), ftrace record of some address
is being searched in ftrace pages of some module, but those ftrace pages
at the same time is being freed in ftrace_release_mod() as the
corresponding module is being deleted:

           CPU1                       |      CPU2
  register_kprobes() {                | delete_module() {
    check_kprobe_address_safe() {     |
      arch_check_ftrace_location() {  |
        ftrace_location() {           |
          lookup_rec() // USE!        |   ftrace_release_mod() // Free!

To fix this issue:
  1. Hold rcu lock as accessing ftrace pages in ftrace_location_range();
  2. Use ftrace_location_range() instead of lookup_rec() in
     ftrace_location();
  3. Call synchronize_rcu() before freeing any ftrace pages both in
     ftrace_process_locs()/ftrace_release_mod()/ftrace_free_mem().

[Fix]

Noble:  fixed via stable
Jammy:  fixed via stable
Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
Bionic: fix sent to esm ML
Xenial: fix sent to esm ML
Trusty: won't fix

[Test Case]

Compile and boot tested

[Where problems could occur]

The primary fix affects those who use kprobes, especially when creating an
event which leads to ftrace based optimization. Even though the fix
itself is unlikely to introduce any regression as it's confined to the sync
issue, the multiple prerequisite commits for the fix touch ftrace
infrastructures, thus an issue with those would be visible to the user
via unpredicted system behavior or a system crash when directly using
any ftrace features.


Artem Savkov (1):
  ftrace: Return the first found result in lookup_rec()

Steven Rostedt (VMware) (1):
  ftrace: Separate out functionality from ftrace_location_range()

Zheng Yejian (1):
  ftrace: Fix possible use-after-free issue in ftrace_location()

 kernel/trace/ftrace.c | 64 ++++++++++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 22 deletions(-)

Comments

Koichiro Den Oct. 25, 2024, 1:41 p.m. UTC | #1
I mistakenly sent an old cover letter. Let me send v2.

On Fri, Oct 25, 2024 at 10:31:03PM +0900, Koichiro Den wrote:
> [Impact]
> 
> ftrace: Fix possible use-after-free issue in ftrace_location()
> KASAN reports a bug:
> 
>   BUG: KASAN: use-after-free in ftrace_location+0x90/0x120
>   Read of size 8 at addr ffff888141d40010 by task insmod/424
>   CPU: 8 PID: 424 Comm: insmod Tainted: G        W          6.9.0-rc2+
>   [...]
>   Call Trace:
>    <TASK>
>    dump_stack_lvl+0x68/0xa0
>    print_report+0xcf/0x610
>    kasan_report+0xb5/0xe0
>    ftrace_location+0x90/0x120
>    register_kprobe+0x14b/0xa40
>    kprobe_init+0x2d/0xff0 [kprobe_example]
>    do_one_initcall+0x8f/0x2d0
>    do_init_module+0x13a/0x3c0
>    load_module+0x3082/0x33d0
>    init_module_from_file+0xd2/0x130
>    __x64_sys_finit_module+0x306/0x440
>    do_syscall_64+0x68/0x140
>    entry_SYSCALL_64_after_hwframe+0x71/0x79
> 
> The root cause is that, in lookup_rec(), ftrace record of some address
> is being searched in ftrace pages of some module, but those ftrace pages
> at the same time is being freed in ftrace_release_mod() as the
> corresponding module is being deleted:
> 
>            CPU1                       |      CPU2
>   register_kprobes() {                | delete_module() {
>     check_kprobe_address_safe() {     |
>       arch_check_ftrace_location() {  |
>         ftrace_location() {           |
>           lookup_rec() // USE!        |   ftrace_release_mod() // Free!
> 
> To fix this issue:
>   1. Hold rcu lock as accessing ftrace pages in ftrace_location_range();
>   2. Use ftrace_location_range() instead of lookup_rec() in
>      ftrace_location();
>   3. Call synchronize_rcu() before freeing any ftrace pages both in
>      ftrace_process_locs()/ftrace_release_mod()/ftrace_free_mem().
> 
> [Fix]
> 
> Noble:  fixed via stable
> Jammy:  fixed via stable
> Focal:  Backport - adjusted contexts due to missing commits, see [Backport]
> Bionic: fix sent to esm ML
> Xenial: fix sent to esm ML
> Trusty: won't fix
> 
> [Test Case]
> 
> Compile and boot tested
> 
> [Where problems could occur]
> 
> The primary fix affects those who use kprobes, especially when creating an
> event which leads to ftrace based optimization. Even though the fix
> itself is unlikely to introduce any regression as it's confined to the sync
> issue, the multiple prerequisite commits for the fix touch ftrace
> infrastructures, thus an issue with those would be visible to the user
> via unpredicted system behavior or a system crash when directly using
> any ftrace features.
> 
> 
> Artem Savkov (1):
>   ftrace: Return the first found result in lookup_rec()
> 
> Steven Rostedt (VMware) (1):
>   ftrace: Separate out functionality from ftrace_location_range()
> 
> Zheng Yejian (1):
>   ftrace: Fix possible use-after-free issue in ftrace_location()
> 
>  kernel/trace/ftrace.c | 64 ++++++++++++++++++++++++++++---------------
>  1 file changed, 42 insertions(+), 22 deletions(-)
> 
> -- 
> 2.43.0
>