Execution with Unnecessary Privileges Affecting openshift4/insights-runtime-extractor-rhel9 package, versions *


Severity

Recommended
0.0
high
0
10

Based on Red Hat Enterprise Linux security rating.

Threat Intelligence

EPSS
0.17% (6th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-RHEL8-OPENSHIFT4INSIGHTSRUNTIMEEXTRACTORRHEL9-21087792
  • published16 Oct 2026
  • disclosed14 Oct 2026

Introduced: 14 Oct 2026

NewCVE-2026-104795  (opens in a new tab)
CWE-250  (opens in a new tab)

How to fix?

There is no fixed version for RHEL:8 openshift4/insights-runtime-extractor-rhel9.

NVD Description

Note: Versions mentioned in the description apply only to the upstream openshift4/insights-runtime-extractor-rhel9 package and not the openshift4/insights-runtime-extractor-rhel9 package as distributed by RHEL. See How to fix? for RHEL:8 relevant fixed versions and status.

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

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

CVSS Base Scores

version 3.1