{
  "schema_version": "1.6.1",
  "id": "RPI-CVE-2024-26706",
  "modified": "2026-10-09T11:39:44Z",
  "upstream": [
    "CVE-2024-26706"
  ],
  "published": "2024-04-03T14:55:57Z",
  "summary": "parisc: Fix random data corruption from exception handler",
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\nparisc: Fix random data corruption from exception handler\n\nThe current exception handler implementation, which assists when accessing\nuser space memory, may exhibit random data corruption if the compiler decides\nto use a different register than the specified register %r29 (defined in\nASM_EXCEPTIONTABLE_REG) for the error code. If the compiler choose another\nregister, the fault handler will nevertheless store -EFAULT into %r29 and thus\ntrash whatever this register is used for.\nLooking at the assembly I found that this happens sometimes in emulate_ldd().\n\nTo solve the issue, the easiest solution would be if it somehow is\npossible to tell the fault handler which register is used to hold the error\ncode. Using %0 or %1 in the inline assembly is not posssible as it will show\nup as e.g. %r29 (with the \"%r\" prefix), which the GNU assembler can not\nconvert to an integer.\n\nThis patch takes another, better and more flexible approach:\nWe extend the __ex_table (which is out of the execution path) by one 32-word.\nIn this word we tell the compiler to insert the assembler instruction\n\"or %r0,%r0,%reg\", where %reg references the register which the compiler\nchoosed for the error return code.\nIn case of an access failure, the fault handler finds the __ex_table entry and\ncan examine the opcode. The used register is encoded in the lowest 5 bits, and\nthe fault handler can then store -EFAULT into this register.\n\nSince we extend the __ex_table to 3 words we can't use the BUILDTIME_TABLE_SORT\nconfig option any longer.",
  "severity": [
    {
      "type": "CVSS_V3",
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
    }
  ],
  "affected": [
    {
      "package": {
        "ecosystem": "Raspberry Pi OS:12",
        "name": "linux"
      },
      "versions": [
        "1:6.1.47-1+rpt4"
      ],
      "ecosystem_specific": {
        "binaries": [
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-2712",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v6",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7l",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v8",
            "binary_version": "1:6.1.47-1+rpt4"
          }
        ]
      },
      "database_specific": {
        "per_version": {
          "1:6.1.47-1+rpt4": {
            "linux_commit": "655fc658a15ae7a6f37103754adb39ba52a9a14e",
            "upstream_version": "6.1.47",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": "6.1.79",
            "compiled_filter": false
          }
        }
      }
    }
  ],
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://www.cve.org/CVERecord?id=CVE-2024-26706"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/23027309b099ffc4efca5477009a11dccbdae592"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/fa69a8063f8b27f3c7434a0d4f464a76a62f24d2"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/ce31d79aa1f13a2345791f84935281a2c194e003"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/8b1d72395635af45410b66cc4c4ab37a12c4a831"
    }
  ],
  "database_specific": {
    "source": "https://git.kernel.org/pub/scm/linux/security/vulns.git",
    "upstream_modified": "2026-08-05T11:52:36Z",
    "severity": {
      "source": "kernel CNA",
      "cvss_v3_score": 7.8,
      "cvss_v3_severity": "High",
      "scenario": "AV:L - Triggering requires executing an unaligned load/store instruction or issuing a syscall with an invalid user pointer on the affected PA-RISC machine, so the attacker must be able to run code locally. There is no network-reachable path into `handle_unaligned()`/`fixup_exception()`.\nAC:L - The attacker deterministically controls the trigger \u2014 mmap a region, unmap the adjacent page, and execute an unaligned access straddling the boundary (or pass a PROT_NONE pointer to any get_user()/put_user() syscall) \u2014 and can repeat it at will with no race to win. The only build-dependent factor is which register GCC allocated, a static property of the deployed binary that the attacker can inspect (parisc has no KASLR) and that was confirmed to occur in practice in `emulate_ldd()`.\nPR:L - Any unprivileged local user can execute an unaligned instruction or call a syscall with a bad pointer; no capabilities, namespaces, or special file access are needed. Unaligned emulation is enabled by default (`unaligned_enabled = 1`).\nUI:N - The attacking process triggers the fault entirely on its own by executing the unaligned instruction or making the syscall. No victim action or cooperation is required.\nS:U - The corruption is confined to kernel registers and kernel memory within the same security authority; there is no hypervisor, IOMMU, or sandbox boundary crossed.\nC:H - The fault handler clobbers whatever live kernel value the compiler placed in %r29 \u2014 a length, index, or pointer at an attacker-chosen call site \u2014 which can be steered into out-of-bounds kernel reads whose results are returned to userspace, and failed get_user()/copy paths are reported as successful so the kernel acts on data it never validly read. Per the guidance, memory corruption leverageable for information disclosure scores High.\nI:H - This is arbitrary kernel data corruption: in `emulate_ldd()` a clobbered `toreg` turns `regs->gr[toreg] = val` into an out-of-bounds write past `pt_regs` on the kernel stack with attacker-influenced data, and failed `put_user()`/`cacheflush()` operations are silently reported as having succeeded. Kernel-stack out-of-bounds writes are a control-flow-hijack primitive.\nA:H - Overwriting a live kernel register with -EFAULT (0xfffffff2) turns pointers and counters into invalid values, producing immediate oops/panic when dereferenced, and the condition is trivially and repeatedly reproducible by an unprivileged user."
    }
  }
}
