CVE-2026-104795

HighCVSS 8.8/10Last modified Oct 20, 2026

Description

The insights-runtime-extractor runs as a privileged DaemonSet (`hostPID: true`) that scans container processes for runtime fingerprinting. When scanning a container, the coordinator:

1. **fork()s** a child process 2. **setns()** into the target container's PID and mount namespaces 3. **fchdir()** back to an orphaned FD pointing at the extractor's own root filesystem (where `/crio.sock` is hostPath-mounted) 4. Calls **only `seteuid(target_uid)`** — changing the effective UID but leaving the **real UID and saved-set-UID at 0** and **retaining the permitted capability set** 5. The `check_no_privileged_perms()` guard inspects only the Effective capability set (so it passes), and is **skipped entirely when the target runs as uid 0** 6. The `VersionExecutable` fingerprint invokes `fpr_kind_executable` with `process.command_line[0]` — the target's argv[0], read from `/proc/<pid>/cmdline` and **fully controlled by the workload** 7. `fpr_kind_executable` calls `exec.Command(executable, "--version").Output()` — executing the **workload's own binary** inside the workload's mount namespace while **ruid=0 in the host user namespace**

The executed process can call `setuid(0)` to restore full root with `CAP_SYS_ADMIN`, and inherits the orphaned cwd which resolves into the extractor container's filesystem containing the host CRI-O socket.

## Affected Code

### 1. Insufficient privilege drop (Rust — extractor coordinator)

**File:** `extractor/src/insights_runtime_extractor.rs`

```rust // Lines 139-146 — seteuid-only drop, guard skipped for root containers join_process_namespaces(process.pid)?; change_dir(current_dir); switch_user(*process.uid)?; if *process.uid != 0 { perms::check_no_privileged_perms() .expect("Must not have privileged permissions to run fingerprints"); } fingerprint::run_fingerprints(&config, out_dir, &process); ```

```rust // Lines 182-185 — only effective UID changed; ruid/suid stay 0 fn switch_user(uid: u32) -> Result<(), ScannerError> { debug!("... Becoming user: {uid}"); seteuid(uid.into()).map_err(|e| ScannerError::Errno(e)) } ```

### 2. Execution of untrusted binary (Go — fingerprint)

**File:** `fingerprints/pkg/utils/file.go`

```go // Lines 75-80 — executes a path taken verbatim from workload's argv[0] func GetExecutableVersionOutput(executable string) (string, error) { out, err := exec.Command(executable, "--version").Output() if err != nil { return "", err } return string(out), nil } ```

### 3. Workload-controlled path forwarded (Rust — version_executable)

**File:** `version_executable.rs`

```rust // Lines 29-34 — workload-controlled command_line[0] forwarded to fingerprint return Some(vec![ fpr_kind_executable, out_dir.to_string(), String::from(&process.command_line[0]), String::from(&version_executable.runtime_kind_name), ]); ```

## Attack Pattern

**Attacker:** Any tenant able to schedule a pod (unprivileged, any namespace) **Victim:** The node running the insights-runtime-extractor DaemonSet **Trigger:** Automatic — the DaemonSet scans all container processes on the node

**Attack sequence:**

1. Attacker creates a pod whose process name matches a configured versioned-executable pattern (`node`, `python`, `python3`, `MainThread`, or contains `java`) 2. The pod's main binary (at the path matching argv[0]) is a malicious executable that calls `setuid(0)` to restore root 3. When the insights operator triggers a scan, the DaemonSet forks, enters the attacker's mount namespace, and executes the attacker's binary with ruid=0 4. The attacker's code regains full root with `CAP_SYS_ADMIN` in the host user namespace 5. The inherited cwd contains the host CRI-O socket → full node compromise

Metrics

CVSS 3.1 8.8/10CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

Weakness enumeration

Affected software

Source: the vendor's advisory (CNA). NVD analysis pending.

No affected versions have been published.

Timeline

Published
Oct 14, 2026
Last modified
Oct 20, 2026
NVD status
Awaiting Analysis

Related CVEs from 2026

CVE-2026-1047978.1The Advanced Form Integration — Connect Forms to 300+ Apps plugin for WordPress is vulnerable to Authentication Bypass via Unverified PasswoCVE-2026-1047989.8The My Calendar – Accessible Event Manager plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, CVE-2026-10485.4A weakness has been identified in LigeroSmart up to 6.1.26. Impacted is an unknown function of the file /otrs/index.pl?Action=AgentTicketZooCVE-2026-1048009.8The AGE-GATE plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1.0 via the 'width (and heighCVE-2026-1048019.1The PPOM – Product Addons & Custom Fields for WooCommerce plugin for WordPress is vulnerable to arbitrary file deletion due to insufficient CVE-2026-1048039.8The WPCOM Member plugin for WordPress is vulnerable to Authentication Bypass in all versions up to, and including, 1.7.27 via the `uuid` andCVE-2026-1048058.5DigitalCanion has discovered a vulnerability in the backup restoration functionality that allows an attacker with access to the configured bCVE-2026-1048065.5DigitalCanion has discovered a path traversal vulnerability that allows an attacker to access files outside of the intended directory. TCVE-2026-1048071.9DigitalCanion has discovered a stored Cross-Site Scripting (XSS) vulnerability that allows an authenticated malicious user to inject persistCVE-2026-1048081.9DigitalCanion has discovered a stored Cross-Site Scripting (XSS) vulnerability that allows an authenticated malicious user to inject persistCVE-2026-1048098.4DigitalCanion has discovered a vulnerability that allows an attacker to cause the system to load an attacker-controlled .so file instead of CVE-2026-1048108.4This vulnerability allows remote attackers to delete sensitive files on vulnerable installations of Mitel MiVoice Office 400. Authentication