(CVE-2024-34594) Samsung Galaxy Kernel Information Disclosure via Debug proc Entry Leading to KASLR Bypass

CVE: CVE-2024-34594

Affected Versions: Samsung Galaxy S22 (samsung/r0qcsx/r0q:14/UP1A.231005.007/S901WVLS4DWL3:user/release-keys); Select Android 12, 13, 14 devices with Qualcomm chipsets

CVSS3.1: 5.5 (Medium) — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Summary

Product Samsung Galaxy Kernel (RKP Test Driver)
Vendor Samsung
Severity Medium — a local unprivileged attacker can read kernel memory addresses, bypassing KASLR
Affected Versions Samsung Galaxy S22 (Android 14); select Android 12, 13, 14 devices with Qualcomm chipsets; prior to SMR Jul-2024 Release 1
Tested Versions Samsung Galaxy S22 (S901WVLS4DWL3)
CVE Identifier CVE-2024-34594
CVE Description Exposure of sensitive information in the proc file system in Samsung Galaxy kernels allows local attackers to access kernel memory addresses prior to SMR Jul-2024 Release 1
CWE Classification(s) CWE-200: Exposure of Sensitive Information to an Unauthorized Actor

CVSS3.1 Scoring System

Base Score: 5.5 (Medium) Vector String: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Metric Value
Attack Vector (AV) Local
Attack Complexity (AC) Low
Privileges Required (PR) Low
User Interaction (UI) None
Scope (S) Unchanged
Confidentiality (C) High
Integrity (I) None
Availability (A) None

Product Background

The Samsung Galaxy S22 is a high-end smartphone running Samsung’s custom Android kernel. Samsung’s kernel includes a Real-time Kernel Protection (RKP) subsystem designed to enforce memory integrity at runtime. As part of this subsystem, a test driver registers a /proc/rkp_test entry to validate RKP behaviour during development.

Technical Details

rkp_test_init, marked __init, installs a proc entry at /proc/rkp_test on every boot. When read, it invokes rkp_read, which runs a series of RKP test cases and outputs their results — including detailed kernel virtual address ranges — directly to userspace:

ssize_t rkp_read(struct file *filep, char __user *buffer, size_t count, loff_t *ppos)
{
    int ret = 0, temp_ret = 0, i = 0;
    struct test_case tc_funcs[] = {
        {test_case_user_pxn,         "TEST USER_PXN"},
        {test_case_user_pgtable_ro,  "TEST USER_PGTABLE_RO"},
        {test_case_kernel_pgtable_ro,"TEST KERNEL_PGTABLE_RO"},
        {test_case_kernel_l3pgt_ro,  "TEST KERNEL TEXT HEAD TAIL L3PGT RO"},
        {test_case_kernel_range_rwx, "TEST KERNEL_RANGE_RWX"},
    };
    int tc_num = sizeof(tc_funcs)/sizeof(struct test_case);

    static bool done = false;
    if (done)
        return 0;
    done = true;

    if ((!ha1) || (!ha2)) {
        buf_print("ERROR RKP_TEST ha1 is NULL\n");
        goto error;
    }

    for (i = 0; i < tc_num; i++) {
        buf_print("RKP_TEST_CASE %d ===========> RUNNING %s\n", i, tc_funcs[i].describe);
        temp_ret = tc_funcs[i].fn();
        if (temp_ret)
            buf_print("RKP_TEST_CASE %d ===========> %s FAILED WITH %d ERRORS\n",
                i, tc_funcs[i].describe, temp_ret);
        else
            buf_print("RKP_TEST_CASE %d ===========> %s PASSED\n", i, tc_funcs[i].describe);
        ret += temp_ret;
    }

    if (ret)
        buf_print("RKP_TEST SUMMARY: FAILED WITH %d ERRORS\n", ret);
    else
        buf_print("RKP_TEST SUMMARY: PASSED\n");

error:
    return simple_read_from_buffer(buffer, count, ppos, rkp_test_buf, rkp_test_len);
}

The TEST KERNEL_RANGE_RWX test case outputs the exact start and end virtual addresses of key kernel regions, including STEXT (the kernel text base):

RKP_TEST_CASE 4 ===========> RUNNING TEST KERNEL_RANGE_RWX
    | MEMORY RANGES  |            START -              END |       RO       RW      PXN       PX
    |VMALLOC -  STEXT| ffffffc008000000 - ffffffc008198000 |        0        0        0        0
    |STEXT - ETEXT|    ffffffc008198000 - ffffffc0099c8000 |     6192        0        0     6192
    |ETEXT - ERODATA|  ffffffc0099c8000 - ffffffc00a3d3000 |     2571        0     2571        0
    |ERODATA -MEM_END| ffffffc00a3d3000 - fffffffffffff000 |   172478   113045   285281      242
RKP_TEST_CASE 4 ===========> TEST KERNEL_RANGE_RWX PASSED

The kernel slide can be calculated directly from the STEXT value, fully defeating KASLR. The proc entry is accessible to any unprivileged process and requires no special permissions.

Proof of Concept

adb shell
cat /proc/rkp_test

Samsung’s fix removed the unnecessary proc file system entries to prevent exposure of sensitive kernel information.

Credit

Billy Jheng Bing-Jhong and Pan Zhenpeng of STAR Labs SG Pte. Ltd.

Timeline