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
Published: 2026-10-14
Score: 8.8 High
EPSS: < 1% Very Low
KEV: No
Impact: Escalation to host root leading to full node compromise
Action: Immediate Patch
AI Analysis

Impact

The insights-runtime-extractor runs as a privileged DaemonSet that scans every running container on the node. Its scanning routine forks a child, enters the target container’s PID and mount namespaces, changes directory to an orphaned file descriptor pointing at the extractor’s root, and then only calls seteuid() to lower its effective UID. This is a CWE‑250 vulnerability, as the process improperly releases privileges. This leaves the real UID, saved set‑UID, and all permitted capabilities unchanged. When the auditor later executes the workload’s own binary inside the same mount namespace while still having root real UID and CAP_SYS_ADMIN, the binary can call setuid(0) to regain full root privileges. The process inherits a working directory that points back to the extractor container’s filesystem, which contains the host CRI‑O socket, giving the attacker unrestricted access to the host’s container runtime. The impact is therefore a complete privilege escalation to the host, allowing control of the node, data exfiltration, and further lateral movement.

Affected Systems

Red Hat OpenShift Container Platform 4 is affected, as the platform deploys insights-runtime-extractor as a privileged DaemonSet with hostPID enabled. No specific version information beyond the platform release is provided, but any installation containing the default collector daemon is vulnerable.

Risk and Exploitability

The CVSS score of 8.8 indicates a high severity vulnerability. The EPSS score is 0.00165, indicating a very low but nonzero likelihood of exploitation. The absence of a KEV listing does not diminish its potential risk, because the exploitation path is available to any tenant capable of scheduling a pod. The likely attack vector is from an unprivileged tenant creating a pod that runs a malicious binary whose entry point matches a recognized fingerprint pattern; the DaemonSet will automatically scan the pod, execute the binary under root real UID, and obtain host‑level privileges. The exploit requires only the ability to schedule a pod, which is a common entitlement in OpenShift environments.

Generated by OpenCVE AI on October 16, 2026 at 00:08 UTC.

Remediation

Vendor Workaround

The vulnerability requires a code fix to implement a complete privilege drop (setting all three UID/GID fields, clearing all Linux capability sets, and setting `PR_SET_NO_NEW_PRIVS`) before executing any fingerprint binary.


OpenCVE Recommended Actions

  • Apply the official Red Hat patch that performs a full privilege drop, including setting the real UID, clearing all capability sets, and enabling PR_SET_NO_NEW_PRIVS before executing any fingerprint binary.
  • If the official patch is not yet available, implement the CNA workaround by ensuring that the insights-runtime-extractor performs a complete privilege drop before executing any fingerprint binary.
  • Re‑configure the insights‑runtime‑extractor DaemonSet to run without hostPID or as a non‑root user so it cannot enter other containers’ namespaces.
  • Remove or restrict the ability for tenants to schedule pods that could match the versioned‑executable patterns, or enforce image signing and scanning to prevent malicious binaries from being deployed.

Generated by OpenCVE AI on October 16, 2026 at 00:08 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Fri, 30 Oct 2026 04:30:00 +0000

Type Values Removed Values Added
CPEs cpe:/a:redhat:openshift:5

Thu, 29 Oct 2026 17:15:00 +0000

Type Values Removed Values Added
CPEs cpe:/a:redhat:openshift:4.19::el9
cpe:/a:redhat:openshift:4.20::el9
cpe:/a:redhat:openshift:4.22::el9
References

Tue, 20 Oct 2026 13:45:00 +0000

Type Values Removed Values Added
CPEs cpe:/a:redhat:openshift:4 cpe:/a:redhat:openshift:4.21::el9
References

Thu, 15 Oct 2026 13:30:00 +0000

Type Values Removed Values Added
References
Metrics threat_severity

None

threat_severity

Important


Wed, 14 Oct 2026 16:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'none', 'Technical Impact': 'total'}, 'version': '2.0.3'}


Wed, 14 Oct 2026 11:00:00 +0000

Type Values Removed Values Added
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
Title Insights-runtime-extractor: insights-runtime-extractor: container escape via privileged binary execution
First Time appeared Redhat
Redhat openshift
Weaknesses CWE-250
CPEs cpe:/a:redhat:openshift:4
Vendors & Products Redhat
Redhat openshift
References
Metrics cvssV3_1

{'score': 8.8, 'vector': 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H'}


Subscriptions

Redhat Openshift
cve-icon MITRE

Status: PUBLISHED

Assigner: redhat

Published:

Updated: 2026-10-30T04:26:30.832Z

Reserved: 2026-10-02T13:07:13.820Z

Link: CVE-2026-104795

cve-icon Vulnrichment

Updated: 2026-10-14T15:26:49.725Z

cve-icon NVD

Status : Awaiting Analysis

Published: 2026-10-14T11:16:59.937

Modified: 2026-10-30T05:16:57.997

Link: CVE-2026-104795

cve-icon Redhat

Severity : Important

Publid Date: 2026-10-14T09:47:53Z

Links: CVE-2026-104795 - Bugzilla

cve-icon OpenCVE Enrichment

Updated: 2026-10-16T00:15:14Z

Weaknesses
  • CWE-250

    Execution with Unnecessary Privileges