CVE: CVE-2022-50579
Published: 2025-10-22
Description: In the Linux kernel, the following vulnerability has been resolved:

arm64: ftrace: fix module PLTs with mcount

Li Huafei reports that mcount-based ftrace with module PLTs was broken
by commit:

  a[PII_REDACTED]e4c6f ("arm64: ftrace: consistently handle PLTs.")

When a module PLTs are used and a module is loaded sufficiently far away
from the kernel, we'll create PLTs for any branches which are
out-of-range. These are separate from the special ftrace trampoline
PLTs, which the module PLT code doesn't directly manipulate.

When mcount is in use this is a problem, as each mcount callsite in a
module will be initialized to point to a module PLT, but since commit
a[PII_REDACTED]e4c6f ftrace_make_nop() will assume that the callsite has
been initialized to point to the special ftrace trampoline PLT, and
ftrace_find_callable_addr() rejects other cases.

This means that when ftrace tries to initialize a callsite via
ftrace_make_nop(), the call to ftrace_find_callable_addr() will find
that the `_mcount` stub is out-of-range and is not handled by the ftrace
PLT, resulting in a splat:

| ftrace_test: loading out-of-tree module taints kernel.
| ftrace: no module PLT for _mcount
| ------------[ ftrace bug ]------------
| ftrace failed to modify
| [<ffff[PII_REDACTED]14>] 0xffff[PII_REDACTED]14
|  actual:   44:00:00:94
| Initializing ftrace call sites
| ftrace record flags: 2000000
|  (0)
|  expected tramp: ffff80000802eb3c
| ------------[ cut here ]------------
| WARNING: CPU: 3 PID: 157 at kernel/trace/ftrace.c:2120 ftrace_bug+0x94/0x270
| Modules linked in:
| CPU: 3 PID: 157 Comm: insmod Tainted: G           O       6.0.0-rc6-00151-gcd722513a189-dirty #22
| Hardware name: linux,dummy-virt (DT)
| pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
| pc : ftrace_bug+0x94/0x270
| lr : ftrace_bug+0x21c/0x270
| sp : ffff80000b2bbaf0
| x29: ffff80000b2bbaf0 x28: [PII_REDACTED] x27: ffff0000c4d38000
| x26: [PII_REDACTED] x25: ffff800009d7e000 x24: ffff0000c4d86e00
| x23: [PII_REDACTED] x22: ffff80000a62b000 x21: ffff8000098ebea8
| x20: ffff0000c4d38000 x19: ffff80000aa24158 x18: ffffffffffffffff
| x17: [PII_REDACTED] x16: 0a0d2d2d2d2d2d2d x15: ffff800009aa9118
| x14: [PII_REDACTED] x13: [PII_REDACTED] x12: [PII_REDACTED]
| x11: 203a706d61727420 x10: [PII_REDACTED] x9 : [PII_REDACTED]
| x8 : c0000000ffffefff x7 :[PII_REDACTED]017fe8 x6 :[PII_REDACTED]00bff4
| x5 :[PII_REDACTED]057fa8 x4 : [PII_REDACTED] x3 : [PII_REDACTED]
| x2 : ad2cb14bb5438900 x1 : [PII_REDACTED] x0 : [PII_REDACTED]
| Call trace:
|  ftrace_bug+0x94/0x270
|  ftrace_process_locs+0x308/0x430
|  ftrace_module_init+0x44/0x60
|  load_module+0x15b4/0x1ce8
|  __do_sys_init_module+0x1ec/0x238
|  __arm64_sys_init_module+0x24/0x30
|  invoke_syscall+0x54/0x118
|  el0_svc_common.constprop.4+0x84/0x100
|  do_el0_svc+0x3c/0xd0
|  el0_svc+0x1c/0x50
|  el0t_64_sync_handler+0x90/0xb8
|  el0t_64_sync+0x15c/0x160
| ---[ end trace [PII_REDACTED] ]---
| ---------test_init-----------

Fix this by reverting to the old behaviour of ignoring the old
instruction when initialising an mcount callsite in a module, which was
the behaviour prior to commit a[PII_REDACTED]e4c6f.
References: https://git.kernel.org/stable/c/0f77b6b2ba70d7c9d69ef39694e283ded9f8b5f2; https://git.kernel.org/stable/c/657de36c72f57fa172a66b06f826b3f5bc56f42e; https://git.kernel.org/stable/c/6c93b683cedaef745884cb9d554d02ed6266b897