In the Linux kernel, the following vulnerability has been resolved:
arm64: probes: Fix uprobes for big-endian kernels
The arm64 uprobes code is broken for big-endian kernels as it doesn't convert the in-memory instruction encoding (which is always little-endian) into the kernel's native endianness before analyzing and simulating instructions. This may result in a few distinct problems:
The kernel may may erroneously reject probing an instruction which can safely be probed.
The kernel may erroneously erroneously permit stepping an instruction out-of-line when that instruction cannot be stepped out-of-line safely.
The kernel may erroneously simulate instruction incorrectly dur to interpretting the byte-swapped encoding.
The endianness mismatch isn't caught by the compiler or sparse because:
The arch_uprobe::{insn,ixol} fields are encoded as arrays of u8, so the compiler and sparse have no idea these contain a little-endian 32-bit value. The core uprobes code populates these with a memcpy() which similarly does not handle endianness.
While the uprobeopcodet type is an alias for _le32, both archuprobeanalyzeinsn() and archuprobeskipsstep() cast from u8[] to the similarly-named probeopcode_t, which is an alias for u32. Hence there is no endianness conversion warning.
Fix this by changing the archuprobe::{insn,ixol} fields to _le32 and adding the appropriate _le32to_cpu() conversions prior to consuming the instruction encoding. The core uprobes copies these fields as opaque ranges of bytes, and so is unaffected by this change.
At the same time, remove MAXUINSNBYTES and consistently use AARCH64INSNSIZE for clarity.
Tested with the following:
| #include <stdio.h> | #include <stdbool.h> | | #define noinline attribute((noinline)) | | static noinline void *adrpself(void) | { | void *addr; | | asm volatile( | " adrp %x0, adrpself\n" | " add %x0, %x0, :lo12:adrpself\n" | : "=r" (addr)); | } | | | int main(int argc, char *argv) | { | void *ptr = adrpself(); | bool equal = (ptr == adrpself); | | printf("adrpself => %p\n" | "adrpself() => %p\n" | "%s\n", | adrpself, ptr, equal ? "EQUAL" : "NOT EQUAL"); | | return 0; | }
.... where the adrp_self() function was compiled to:
| 00000000004007e0 <adrp_self>: | 4007e0: 90000000 adrp x0, 400000 <__ehdr_start> | 4007e4: 911f8000 add x0, x0, #0x7e0 | 4007e8: d65f03c0 ret
Before this patch, the ADRP is not recognized, and is assumed to be steppable, resulting in corruption of the result:
| # ./adrp-self | adrpself => 0x4007e0 | adrpself() => 0x4007e0 | EQUAL | # echo 'p /root/adrp-self:0x007e0' > /sys/kernel/tracing/uprobeevents | # echo 1 > /sys/kernel/tracing/events/uprobes/enable | # ./adrp-self | adrpself => 0x4007e0 | adrp_self() => 0xffffffffff7e0 | NOT EQUAL
After this patch, the ADRP is correctly recognized and simulated:
| # ./adrp-self | adrpself => 0x4007e0 | adrpself() => 0x4007e0 | EQUAL | # | # echo 'p /root/adrp-self:0x007e0' > /sys/kernel/tracing/uprobeevents | # echo 1 > /sys/kernel/tracing/events/uprobes/enable | # ./adrp-self | adrpself => 0x4007e0 | adrp_self() => 0x4007e0 | EQUAL
[
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"331369981530098186207028752649961265460",
"35577906078444044207063252142143537985",
"263596701768593459565858721095159177629",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-024c2e7b",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf60d19d40184e43d9a624e55a0da73be09e938d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-07c2f63a",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e6ab336213918575124d6db43dc5d3554526242e",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-1370bbec",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8165bf83b8a64be801d59cd2532b0d1ffed74d00",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-348063f9",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3d2530c65be04e93720e30f191a7cf1a3aa8b51c",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"331369981530098186207028752649961265460",
"35577906078444044207063252142143537985",
"263596701768593459565858721095159177629",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-3596357f",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b6a638cb600e13f94b5464724eaa6ab7f3349ca2",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-39b752ae",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@13f8f1e05f1dc36dbba6cba0ae03354c0dafcde7",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-3b750013",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b6a638cb600e13f94b5464724eaa6ab7f3349ca2",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-3df720b5",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b6a638cb600e13f94b5464724eaa6ab7f3349ca2",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-403edab7",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b6a638cb600e13f94b5464724eaa6ab7f3349ca2",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"331369981530098186207028752649961265460",
"35577906078444044207063252142143537985",
"263596701768593459565858721095159177629",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-56fb66f9",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf9ddf9ed94c15564a05bbf6e9f18dffa0c7df80",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"331369981530098186207028752649961265460",
"35577906078444044207063252142143537985",
"263596701768593459565858721095159177629",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-5c918158",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@14841bb7a531b96e2dde37423a3b33e75147c60d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-61887f70",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf60d19d40184e43d9a624e55a0da73be09e938d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-629ed129",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf9ddf9ed94c15564a05bbf6e9f18dffa0c7df80",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-6975032b",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@13f8f1e05f1dc36dbba6cba0ae03354c0dafcde7",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"295628060322644765597934787484516239848",
"216915994064438294320255724514111794870",
"70062523114342829194622162003061474685",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-6dd69d2a",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8165bf83b8a64be801d59cd2532b0d1ffed74d00",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-765884e1",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8165bf83b8a64be801d59cd2532b0d1ffed74d00",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-7fc4bd04",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@14841bb7a531b96e2dde37423a3b33e75147c60d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-85b21024",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf9ddf9ed94c15564a05bbf6e9f18dffa0c7df80",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-93bc3863",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e6ab336213918575124d6db43dc5d3554526242e",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-9b62715f",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf60d19d40184e43d9a624e55a0da73be09e938d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-ad420c9c",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@13f8f1e05f1dc36dbba6cba0ae03354c0dafcde7",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"331369981530098186207028752649961265460",
"35577906078444044207063252142143537985",
"263596701768593459565858721095159177629",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-b844a889",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e6ab336213918575124d6db43dc5d3554526242e",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"function_hash": "190057794995704618393774873000063691091",
"length": 451.0
},
"id": "CVE-2024-50194-bde74397",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@14841bb7a531b96e2dde37423a3b33e75147c60d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_analyze_insn"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-c138f894",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf60d19d40184e43d9a624e55a0da73be09e938d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-cac60335",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8165bf83b8a64be801d59cd2532b0d1ffed74d00",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-cd61ccd8",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3d2530c65be04e93720e30f191a7cf1a3aa8b51c",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-d30152d9",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3d2530c65be04e93720e30f191a7cf1a3aa8b51c",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"295628060322644765597934787484516239848",
"216915994064438294320255724514111794870",
"70062523114342829194622162003061474685",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-d450f3f9",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@13f8f1e05f1dc36dbba6cba0ae03354c0dafcde7",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-e2c8534f",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e6ab336213918575124d6db43dc5d3554526242e",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"295628060322644765597934787484516239848",
"216915994064438294320255724514111794870",
"70062523114342829194622162003061474685",
"147768428082721975326790441627505663728",
"281906305532469885814582536561460410655",
"319317739482478901941323834820442686521",
"181947194729604871059883937943812622979",
"58720188169066155703632809531426551576"
]
},
"id": "CVE-2024-50194-ee92c88a",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3d2530c65be04e93720e30f191a7cf1a3aa8b51c",
"signature_version": "v1",
"target": {
"file": "arch/arm64/include/asm/uprobes.h"
},
"deprecated": false
},
{
"digest": {
"threshold": 0.9,
"line_hashes": [
"286997269253330455651698230616604008184",
"86704906428838200389852730420590957978",
"127756701570753421519165193071370824605",
"190880943507110127271727243905933639046",
"75578957313638104694331705261480460845",
"319706764299637532798802829772211684991",
"153575252707357250994207111951360497409",
"9020696087230251274256559803908942184"
]
},
"id": "CVE-2024-50194-f54d8674",
"signature_type": "Line",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@cf9ddf9ed94c15564a05bbf6e9f18dffa0c7df80",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c"
},
"deprecated": false
},
{
"digest": {
"function_hash": "228947618315894153168292189152945250908",
"length": 292.0
},
"id": "CVE-2024-50194-f7896658",
"signature_type": "Function",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@14841bb7a531b96e2dde37423a3b33e75147c60d",
"signature_version": "v1",
"target": {
"file": "arch/arm64/kernel/probes/uprobes.c",
"function": "arch_uprobe_skip_sstep"
},
"deprecated": false
}
]