Fedora Account System
Red Hat Associate
Red Hat Customer
The LMEvalJob controller in trustyai-service-operator filters a set of protected environment variables from the main evaluation container, but never applies that same filtering to user-supplied sidecar containers, allowing an admin-controlled security policy (whether remote/untrusted code execution is permitted) to be re-enabled by any authenticated cluster user. Vulnerable code (controllers/lmes/lmevaljob_controller.go, CreatePod, confirmed present at commit 4da2e474b7db2ad221cd9e64f8d9794470f5dfcc on main, and unchanged on the latest release branch, release/1.38.0): 947: var envVars = removeProtectedEnvVars(job.Spec.Pod.GetContainer().GetEnv()) ... 1369: containers = append(containers, job.Spec.Pod.GetSideCards()...) removeProtectedEnvVars (line 1743) strips TRUST_REMOTE_CODE, HF_DATASETS_TRUST_REMOTE_CODE, HF_DATASETS_OFFLINE, HF_HUB_OFFLINE, and TRANSFORMERS_OFFLINE from the main container's env only. The sanctioned way to enable remote code execution requires both job.Spec.AllowCodeExecution=true AND the operator's own deploy-time permConfig.AllowCodeExecution=true (an admin-controlled setting); absent that, disallowRemoteCodeEnvVars forces TRUST_REMOTE_CODE=0 onto the main container (lines 1043-1055). Sidecar containers, appended unfiltered at line 1369, go through none of this: a user can set TRUST_REMOTE_CODE=1 directly on a sidecar's own env. validation.go's ValidateUserInput() (called before CreatePod) validates model name, args, task names, git URLs and shell metacharacters, but never validates Pod.Volumes, Pod.SideCars, or Pod.SecurityContext (api/lmes/v1alpha1/lmevaljob_types.go:425). The sidecar can also request a volumeMount for the "shared" emptyDir volume that the main container mounts at /opt/app-root/src/bin, the same path the "driver" init container populates with the eval driver binary that the main container's Command executes, giving the sidecar a path to tamper with what the operator-vetted main container runs. RBAC precondition (broader than a namespace-edit role): config/components/lmes/rbac/default_lmeval_user_rolebinding.yaml is a ClusterRoleBinding granting lmeval-user-role (create/delete/get/list/patch/update/watch on lmevaljobs.trustyai.opendatahub.io) to the system:authenticated group, cluster-wide. Any authenticated user of the cluster can trigger this, and none of them have direct pod-create rights, the LMEvalJob CRD is their only path to pod content, which is exactly why the missing sidecar filtering matters. Example trigger, an LMEvalJob whose pod.sideCars sets the protected env vars directly: apiVersion: trustyai.opendatahub.io/v1alpha1 kind: LMEvalJob metadata: name: exploit spec: model: hf modelArgs: - name: pretrained value: some/model taskList: taskNames: ["arc_easy"] pod: sideCars: - name: bypass image: <any-image> env: - name: TRUST_REMOTE_CODE value: "1" - name: HF_DATASETS_TRUST_REMOTE_CODE value: "1" volumeMounts: - name: shared mountPath: /opt/app-root/src/bin Source: Project Glasswing (Mythos) security audit, FIND-004, tracked as RHOAIENG-69541. This flaw covers only the sidecar env var bypass sub-finding; the same Jira issue's volume-type and securityContext-override sub-findings were independently agreed to be hardening rather than CVE-worthy, since OpenShift's default SCC (restricted-v2) already blocks hostPath mounts and privileged securityContext at admission time.