All vulnerabilities
CVE-2026-104795

Insights-runtime-extractor: insights-runtime-extractor: container escape via privileged binary execution

Red Hat Red Hat OpenShift Container Platform 4.21Operating systems
CVSS
8.8High
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)0.17%Chance of exploitation activity in the next 30 days, higher than 6% of CVEs. Scored 23 Oct 2026FIRST EPSS
Fixed inNone listedNo source names a fixed version. Check the vendor advisory below
Published14 Oct 2026Updated 20 Oct 2026CVE List

What fixes it

No source in this snapshot names a fixed version. The vendor advisories under References are the place to check.

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)

  1. 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

  1. 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

  1. 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

  1. 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

// 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);
// 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

// 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

// 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)

  1. The pod's main binary (at the path matching argv[0]) is a malicious

executable that calls setuid(0) to restore root

  1. 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

  1. The attacker's code regains full root with CAP_SYS_ADMIN in the host user

namespace

  1. The inherited cwd contains the host CRI-O socket → full node compromise

Text from CVE List

Affected versions 1

  • Red Hat OpenShift Container Platform 4.21unaffected: 1792008935 and laterCVE List

References 3