blob: 7d4d5942f7fd9884b47ed96aa729dbd22a0eb378 [file] [log] [blame]
From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: <linux-cve-announce@vger.kernel.org>
Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org>
Subject: CVE-2024-50099: arm64: probes: Remove broken LDR (literal) uprobe support
Description
===========
In the Linux kernel, the following vulnerability has been resolved:
arm64: probes: Remove broken LDR (literal) uprobe support
The simulate_ldr_literal() and simulate_ldrsw_literal() functions are
unsafe to use for uprobes. Both functions were originally written for
use with kprobes, and access memory with plain C accesses. When uprobes
was added, these were reused unmodified even though they cannot safely
access user memory.
There are three key problems:
1) The plain C accesses do not have corresponding extable entries, and
thus if they encounter a fault the kernel will treat these as
unintentional accesses to user memory, resulting in a BUG() which
will kill the kernel thread, and likely lead to further issues (e.g.
lockup or panic()).
2) The plain C accesses are subject to HW PAN and SW PAN, and so when
either is in use, any attempt to simulate an access to user memory
will fault. Thus neither simulate_ldr_literal() nor
simulate_ldrsw_literal() can do anything useful when simulating a
user instruction on any system with HW PAN or SW PAN.
3) The plain C accesses are privileged, as they run in kernel context,
and in practice can access a small range of kernel virtual addresses.
The instructions they simulate have a range of +/-1MiB, and since the
simulated instructions must itself be a user instructions in the
TTBR0 address range, these can address the final 1MiB of the TTBR1
acddress range by wrapping downwards from an address in the first
1MiB of the TTBR0 address range.
In contemporary kernels the last 8MiB of TTBR1 address range is
reserved, and accesses to this will always fault, meaning this is no
worse than (1).
Historically, it was theoretically possible for the linear map or
vmemmap to spill into the final 8MiB of the TTBR1 address range, but
in practice this is extremely unlikely to occur as this would
require either:
* Having enough physical memory to fill the entire linear map all the
way to the final 1MiB of the TTBR1 address range.
* Getting unlucky with KASLR randomization of the linear map such
that the populated region happens to overlap with the last 1MiB of
the TTBR address range.
... and in either case if we were to spill into the final page there
would be larger problems as the final page would alias with error
pointers.
Practically speaking, (1) and (2) are the big issues. Given there have
been no reports of problems since the broken code was introduced, it
appears that no-one is relying on probing these instructions with
uprobes.
Avoid these issues by not allowing uprobes on LDR (literal) and LDRSW
(literal), limiting the use of simulate_ldr_literal() and
simulate_ldrsw_literal() to kprobes. Attempts to place uprobes on LDR
(literal) and LDRSW (literal) will be rejected as
arm_probe_decode_insn() will return INSN_REJECTED. In future we can
consider introducing working uprobes support for these instructions, but
this will require more significant work.
The Linux kernel CVE team has assigned CVE-2024-50099 to this issue.
Affected and fixed versions
===========================
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 4.19.323 with commit cc86f2e9876c8b5300238cec6bf0bd8c842078ee
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 5.4.285 with commit ae743deca78d9e4b7f4f60ad2f95e20e8ea057f9
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 5.10.228 with commit 3728b4eb27910ffedd173018279a970705f2e03a
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 5.15.169 with commit ad4bc35a6d22e9ff9b67d0d0c38bce654232f195
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 6.1.114 with commit bae792617a7e911477f67a3aff850ad4ddf51572
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 6.6.58 with commit 9f1e7735474e7457a4d919a517900e46868ae5f6
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 6.11.5 with commit 20cde998315a3d2df08e26079a3ea7501abce6db
Issue introduced in 4.10 with commit 9842ceae9fa8deae141533d52a6ead7666962c09 and fixed in 6.12 with commit acc450aa07099d071b18174c22a1119c57da8227
Please see https://www.kernel.org for a full list of currently supported
kernel versions by the kernel community.
Unaffected versions might change over time as fixes are backported to
older supported kernel versions. The official CVE entry at
https://cve.org/CVERecord/?id=CVE-2024-50099
will be updated if fixes are backported, please check that for the most
up to date information about this issue.
Affected files
==============
The file(s) affected by this issue are:
arch/arm64/kernel/probes/decode-insn.c
Mitigation
==========
The Linux kernel CVE team recommends that you update to the latest
stable kernel version for this, and many other bugfixes. Individual
changes are never tested alone, but rather are part of a larger kernel
release. Cherry-picking individual commits is not recommended or
supported by the Linux kernel community at all. If however, updating to
the latest release is impossible, the individual changes to resolve this
issue can be found at these commits:
https://git.kernel.org/stable/c/cc86f2e9876c8b5300238cec6bf0bd8c842078ee
https://git.kernel.org/stable/c/ae743deca78d9e4b7f4f60ad2f95e20e8ea057f9
https://git.kernel.org/stable/c/3728b4eb27910ffedd173018279a970705f2e03a
https://git.kernel.org/stable/c/ad4bc35a6d22e9ff9b67d0d0c38bce654232f195
https://git.kernel.org/stable/c/bae792617a7e911477f67a3aff850ad4ddf51572
https://git.kernel.org/stable/c/9f1e7735474e7457a4d919a517900e46868ae5f6
https://git.kernel.org/stable/c/20cde998315a3d2df08e26079a3ea7501abce6db
https://git.kernel.org/stable/c/acc450aa07099d071b18174c22a1119c57da8227