From 790dc713f56e698197a82425b03f3f0c2bf96ac6 Mon Sep 17 00:00:00 2001 From: davdhacs <105243888+davdhacs@users.noreply.github.com> Date: Fri, 14 Aug 2026 21:59:28 -0600 Subject: [PATCH] fix: make BASH_ENV writable by arbitrary (Prow/OpenShift) UIDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BASH_ENV is baked as /etc/initial-bash.env, a root-owned 0644 file. cci-export() (the /bin/bash-wrapper mechanism) appends to and rewrites (mv) that file on every call. Under OpenShift/Prow, the container runs as an arbitrary non-root UID in GID 0, which cannot write /etc or a root-only file — so every cci-export call emits "Permission denied" (an mv failure plus two append failures), spamming CI logs ~1450x per test step. Reading/sourcing the file is fine (world-readable), so the noise is purely the writes. Move BASH_ENV to a dedicated group-writable directory (/var/lib/bash-env/env, GID 0, 0775 dir / 0664 file) so the arbitrary UID can write it. This silences the spam at the source, image-wide, and makes the downstream workarounds (scripts/ci/lib.sh ci_export swap, .openshift-ci/dispatch.sh guard) unnecessary. Also dropped the stale CircleCI framing in the comment (we only use GitHub Actions and Prow now). Verified by simulating an arbitrary UID (uid=1000670000, gid=0) against apollo-ci:stackrox-test-0.5.11: before, each cci-export prints 3 "Permission denied" lines; after the relocation, zero. Note: since CircleCI is retired, the whole cci-export/BASH_ENV apparatus is likely removable in a follow-up; this change is the minimal fix for the log spam. Partially generated with AI assistance (Claude). --- images/scanner-test.Dockerfile | 15 ++++++++++++--- images/stackrox-test.Dockerfile | 15 ++++++++++++--- images/stackrox-ui-test.Dockerfile | 15 ++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/images/scanner-test.Dockerfile b/images/scanner-test.Dockerfile index 24ce54e8..dce446fc 100644 --- a/images/scanner-test.Dockerfile +++ b/images/scanner-test.Dockerfile @@ -26,9 +26,18 @@ RUN set -ex \ bash -c 'dir="$(dirname "${1}")"; new_dir="${dir#/static-tmp}"; mkdir -p "${new_dir}"; cp "${1}" "${new_dir}";' -- {} \ && rm -r /static-tmp -# Circle CI uses BASH_ENV to pass an environment for bash. Other environments need -# an initial BASH_ENV as a foundation for cci-export(). -ENV BASH_ENV /etc/initial-bash.env +# cci-export() (see /bin/bash-wrapper) persists env vars across bash invocations +# by appending them to the file named by BASH_ENV, which bash sources on startup. +# This file must be writable by the arbitrary non-root UID (in GID 0) that +# OpenShift/Prow assigns at runtime; /etc is not group-writable, so the appends +# and rewrite (mv) fail with "Permission denied" on every bash invocation and +# spam CI logs. Host it in a dedicated group-writable directory instead. +RUN mkdir -p /var/lib/bash-env \ + && mv /etc/initial-bash.env /var/lib/bash-env/env \ + && chgrp 0 /var/lib/bash-env /var/lib/bash-env/env \ + && chmod 0775 /var/lib/bash-env \ + && chmod 0664 /var/lib/bash-env/env +ENV BASH_ENV /var/lib/bash-env/env # PostgreSQL environment. ENV PG_MAJOR=15 diff --git a/images/stackrox-test.Dockerfile b/images/stackrox-test.Dockerfile index b7d9070c..32ec838a 100644 --- a/images/stackrox-test.Dockerfile +++ b/images/stackrox-test.Dockerfile @@ -23,9 +23,18 @@ RUN set -ex \ && find /static-tmp -type f -print0 | \ xargs -0 -I '{}' -n1 bash -c 'dir="$(dirname "${1}")"; new_dir="${dir#/static-tmp}"; mkdir -p "${new_dir}"; cp "${1}" "${new_dir}";' -- {} \ && rm -r /static-tmp -# Circle CI uses BASH_ENV to pass an environment for bash. Other environments need -# an initial BASH_ENV as a foundation for cci-export(). -ENV BASH_ENV /etc/initial-bash.env +# cci-export() (see /bin/bash-wrapper) persists env vars across bash invocations +# by appending them to the file named by BASH_ENV, which bash sources on startup. +# This file must be writable by the arbitrary non-root UID (in GID 0) that +# OpenShift/Prow assigns at runtime; /etc is not group-writable, so the appends +# and rewrite (mv) fail with "Permission denied" on every bash invocation and +# spam CI logs. Host it in a dedicated group-writable directory instead. +RUN mkdir -p /var/lib/bash-env \ + && mv /etc/initial-bash.env /var/lib/bash-env/env \ + && chgrp 0 /var/lib/bash-env /var/lib/bash-env/env \ + && chmod 0775 /var/lib/bash-env \ + && chmod 0664 /var/lib/bash-env/env +ENV BASH_ENV /var/lib/bash-env/env # Install Postgres repo RUN dnf --disablerepo="*" install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm diff --git a/images/stackrox-ui-test.Dockerfile b/images/stackrox-ui-test.Dockerfile index 43e1f5c7..07ed66a6 100644 --- a/images/stackrox-ui-test.Dockerfile +++ b/images/stackrox-ui-test.Dockerfile @@ -23,9 +23,18 @@ RUN set -ex \ && find /static-tmp -type f -print0 | \ xargs -0 -I '{}' -n1 bash -c 'dir="$(dirname "${1}")"; new_dir="${dir#/static-tmp}"; mkdir -p "${new_dir}"; cp "${1}" "${new_dir}";' -- {} \ && rm -r /static-tmp -# Circle CI uses BASH_ENV to pass an environment for bash. Other environments need -# an initial BASH_ENV as a foundation for cci-export(). -ENV BASH_ENV /etc/initial-bash.env +# cci-export() (see /bin/bash-wrapper) persists env vars across bash invocations +# by appending them to the file named by BASH_ENV, which bash sources on startup. +# This file must be writable by the arbitrary non-root UID (in GID 0) that +# OpenShift/Prow assigns at runtime; /etc is not group-writable, so the appends +# and rewrite (mv) fail with "Permission denied" on every bash invocation and +# spam CI logs. Host it in a dedicated group-writable directory instead. +RUN mkdir -p /var/lib/bash-env \ + && mv /etc/initial-bash.env /var/lib/bash-env/env \ + && chgrp 0 /var/lib/bash-env /var/lib/bash-env/env \ + && chmod 0775 /var/lib/bash-env \ + && chmod 0664 /var/lib/bash-env/env +ENV BASH_ENV /var/lib/bash-env/env # Setup and install some prerequities RUN dnf update -y \