CVE-2021-46997
Publication date:
28/02/2024
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
arm64: entry: always set GIC_PRIO_PSR_I_SET during entry<br />
<br />
Zenghui reports that booting a kernel with "irqchip.gicv3_pseudo_nmi=1"<br />
on the command line hits a warning during kernel entry, due to the way<br />
we manipulate the PMR.<br />
<br />
Early in the entry sequence, we call lockdep_hardirqs_off() to inform<br />
lockdep that interrupts have been masked (as the HW sets DAIF wqhen<br />
entering an exception). Architecturally PMR_EL1 is not affected by<br />
exception entry, and we don&#39;t set GIC_PRIO_PSR_I_SET in the PMR early in<br />
the exception entry sequence, so early in exception entry the PMR can<br />
indicate that interrupts are unmasked even though they are masked by<br />
DAIF.<br />
<br />
If DEBUG_LOCKDEP is selected, lockdep_hardirqs_off() will check that<br />
interrupts are masked, before we set GIC_PRIO_PSR_I_SET in any of the<br />
exception entry paths, and hence lockdep_hardirqs_off() will WARN() that<br />
something is amiss.<br />
<br />
We can avoid this by consistently setting GIC_PRIO_PSR_I_SET during<br />
exception entry so that kernel code sees a consistent environment. We<br />
must also update local_daif_inherit() to undo this, as currently only<br />
touches DAIF. For other paths, local_daif_restore() will update both<br />
DAIF and the PMR. With this done, we can remove the existing special<br />
cases which set this later in the entry code.<br />
<br />
We always use (GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET) for consistency with<br />
local_daif_save(), as this will warn if it ever encounters<br />
(GIC_PRIO_IRQOFF | GIC_PRIO_PSR_I_SET), and never sets this itself. This<br />
matches the gic_prio_kentry_setup that we have to retain for<br />
ret_to_user.<br />
<br />
The original splat from Zenghui&#39;s report was:<br />
<br />
| DEBUG_LOCKS_WARN_ON(!irqs_disabled())<br />
| WARNING: CPU: 3 PID: 125 at kernel/locking/lockdep.c:4258 lockdep_hardirqs_off+0xd4/0xe8<br />
| Modules linked in:<br />
| CPU: 3 PID: 125 Comm: modprobe Tainted: G W 5.12.0-rc8+ #463<br />
| Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015<br />
| pstate: 604003c5 (nZCv DAIF +PAN -UAO -TCO BTYPE=--)<br />
| pc : lockdep_hardirqs_off+0xd4/0xe8<br />
| lr : lockdep_hardirqs_off+0xd4/0xe8<br />
| sp : ffff80002a39bad0<br />
| pmr_save: 000000e0<br />
| x29: ffff80002a39bad0 x28: ffff0000de214bc0<br />
| x27: ffff0000de1c0400 x26: 000000000049b328<br />
| x25: 0000000000406f30 x24: ffff0000de1c00a0<br />
| x23: 0000000020400005 x22: ffff8000105f747c<br />
| x21: 0000000096000044 x20: 0000000000498ef9<br />
| x19: ffff80002a39bc88 x18: ffffffffffffffff<br />
| x17: 0000000000000000 x16: ffff800011c61eb0<br />
| x15: ffff800011700a88 x14: 0720072007200720<br />
| x13: 0720072007200720 x12: 0720072007200720<br />
| x11: 0720072007200720 x10: 0720072007200720<br />
| x9 : ffff80002a39bad0 x8 : ffff80002a39bad0<br />
| x7 : ffff8000119f0800 x6 : c0000000ffff7fff<br />
| x5 : ffff8000119f07a8 x4 : 0000000000000001<br />
| x3 : 9bcdab23f2432800 x2 : ffff800011730538<br />
| x1 : 9bcdab23f2432800 x0 : 0000000000000000<br />
| Call trace:<br />
| lockdep_hardirqs_off+0xd4/0xe8<br />
| enter_from_kernel_mode.isra.5+0x7c/0xa8<br />
| el1_abort+0x24/0x100<br />
| el1_sync_handler+0x80/0xd0<br />
| el1_sync+0x6c/0x100<br />
| __arch_clear_user+0xc/0x90<br />
| load_elf_binary+0x9fc/0x1450<br />
| bprm_execve+0x404/0x880<br />
| kernel_execve+0x180/0x188<br />
| call_usermodehelper_exec_async+0xdc/0x158<br />
| ret_from_fork+0x10/0x18
Severity CVSS v4.0: Pending analysis
Last modification:
24/12/2024