{
  "schema_version": "1.6.1",
  "id": "RPI-CVE-2026-99233",
  "modified": "2026-11-03T05:30:01Z",
  "upstream": [
    "CVE-2026-99233"
  ],
  "published": "2026-11-02T15:14:24Z",
  "summary": "tracing/histograms: Verify event_call identity when updating synth_event refcount",
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\ntracing/histograms: Verify event_call identity when updating synth_event refcount\n\nIn event_hist_trigger_parse() and hist_unreg_all(), the histogram\nregistration and unregistration paths look up find_synth_event() using\ntrace_event_name(file->event_call) and adjust se->ref if a match is\nfound.\n\nBecause find_synth_event() only compares the event basename, registering\nor removing a histogram on a non-synthetic trace event whose basename\nmatches a synthetic event erroneously modifies the synthetic event's\nreference count.  If a histogram is registered on the non-synthetic\nevent before the synthetic event is created and removed afterwards,\nse->ref is decremented without a matching increment, allowing the\nsynthetic event to be freed while an active histogram action still holds\na pointer to it.\n\nIntroduce find_synth_event_call() to verify that &se->call matches\nfile->event_call before adjusting se->ref.",
  "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.191",
            "compiled_filter": false
          }
        }
      }
    }
  ],
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://www.cve.org/CVERecord?id=CVE-2026-99233"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/381f543ed35c434d5b707369aa5dcd69ecf440af"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/4472579bd1c83708b6fe623c870cdf728e947205"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/23b4106e8b35823acc79e206c7745f55b9cfd78b"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/06e816bed499fe47f39f12044382cc5d064485fb"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/5597bb8db6855fcb97a67196d227fea359bcd81c"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/cf4e31d5da80fae4c9cdbe7af55b7c3ad213f0e4"
    }
  ],
  "database_specific": {
    "source": "https://git.kernel.org/pub/scm/linux/security/vulns.git",
    "upstream_modified": "2026-11-02T16:03:24Z",
    "severity": {
      "source": "kernel CNA",
      "cvss_v3_score": 7.8,
      "cvss_v3_severity": "High",
      "scenario": "AV:L - The colliding basename is supplied by local writes: event_trigger_write() \u2192 trigger_process_regex() \u2192 event_hist_trigger_parse()/hist_unreg_all() on events/<system>/<event>/trigger, and synth_events_write() \u2192 create_or_delete_synth_event() on synthetic_events. No network protocol carries this input.\nAC:L - The attacker drives a fully ordered sequence: a hist on a non-synth event (no se->ref++), then a same-basename synth event, then an ACTION_TRACE hist that stores data->synth_event and increments se->ref, then the !hist/hist_unreg_all path which decrements se->ref, then synth_event_delete(). event_mutex serializes it; no victim-owned state is required.\nPR:L - event_trigger_open() and synth_events_open() only call security_locked_down(LOCKDOWN_TRACEFS); both files are TRACE_MODE_WRITE (0640) with no capable() check. tracefs_parse_param() accepts uid=/gid= and tracefs_apply_options() applies that owner, so a delegated tracing user can write them; tracefs has no FS_USERNS_MOUNT.\nUI:N - The attacker writes the hist commands, creates and deletes the colliding synth event via synth_events_write(), and can fire the leftover ACTION_TRACE histogram from their own process (any syscall that hits the remaining event). No separate victim action is required.\nS:U - destroy_synth_event() kfree's struct synth_event while action_trace() still holds data->synth_event; that UAF is confined to the host tracing heap and does not cross a VM, IOMMU, or sandbox boundary.\nC:H - Once free_synth_event() has kfree'd the object, action_trace() still reads data->synth_event and trace_synth() follows event->tp and tp->funcs; reclaiming that kmalloc object lets the attacker control those reads, giving a kernel-memory disclosure primitive.\nI:H - trace_synth() calls probe_func taken from the dangling event->tp->funcs, and a later action_data_destroy() does data->synth_event->ref-- on the freed object; spraying the reclaimed synth_event therefore yields a function-pointer hijack and a write primitive.\nA:H - trace_synth() does static_key_enabled(&tp->key) on event->tp from the freed synth_event the first time the leftover histogram fires, which oopses on a poisoned or unmapped pointer; the UAF is repeatable at will."
    }
  }
}
