From 14ee0ab19dc87fc18facfd22a4d975cad9fe149f Mon Sep 17 00:00:00 2001 From: anubhutiv Date: Thu, 6 Aug 2026 15:27:59 -0700 Subject: [PATCH 1/2] chore(customizer): fix CVEs in RL image Signed-off-by: anubhutiv --- docker-bake.hcl | 6 +----- docker/rl/Dockerfile.nmp-rl-base | 29 ++++++++++------------------- docker/rl/README.md | 13 ------------- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index 640f89d730..ee0fa33149 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -100,7 +100,7 @@ variable "NEMO_RL_REPO" { # RL pins Gym as a git submodule (-> soluwalana/Gym over https), so Gym rides in with the RL git ADD # - no separate Gym pin needed. variable "NEMO_RL_REF" { - default = "edba0f96edcecd8349302a3d93b1249d8a067d0e" # soluwalana/RL nmp/customizer + default = "1427564b347ee0a4b672182a8a98048ed2785217" # soluwalana/RL nmp/customizer } variable "RL_BASE_CONTEXT" { default = "" @@ -426,14 +426,10 @@ target "rl-platform-workspace" { # Heavy base: cuda-dl-base + NeMo-RL (with its Gym/Automodel/Megatron-Bridge submodules) built FROM # SOURCE (Python 3.13, CUDA 13). RL is pinned via NEMO_RL_REF; Gym rides in as RL's own submodule -# (no separate pin). The ffmpeg-vlm wheels are reused for the cp313 av/opencv/decord2 CVE swap. target "nmp-rl-base-builder" { target = "nmp-rl-base" context = "." dockerfile = "docker/rl/Dockerfile.nmp-rl-base" - contexts = { - ffmpeg-vlm-wheel-image = ffmpeg_vlm_wheel_context() - } args = { NEMO_RL_REPO = NEMO_RL_REPO NEMO_RL_REF = NEMO_RL_REF diff --git a/docker/rl/Dockerfile.nmp-rl-base b/docker/rl/Dockerfile.nmp-rl-base index 356acd1585..9f738afd74 100644 --- a/docker/rl/Dockerfile.nmp-rl-base +++ b/docker/rl/Dockerfile.nmp-rl-base @@ -41,10 +41,6 @@ ARG UV_VERSION=0.11.33 ARG PYTHON_VERSION=3.13.14 ARG CMAKE_VERSION=4.0.3 -# Reuse the shared FFmpeg/VLM wheels (cp313 av / opencv-headless / decord2), supplied by bake as a -# named context (see docker/base/Dockerfile.python-wheels). Replaces the FFmpeg-bundling PyPI copies. -FROM ffmpeg-vlm-wheel-image AS ffmpeg-vlm-wheel-src - # ---- RL source (+ its submodules, incl. Gym) via BuildKit's git ADD ---- # RL pins Gym, Automodel and Megatron-Bridge (+ nested Megatron-LM) as git submodules, all over # https, so `ADD #` recurses and fetches them anonymously. Submodule CONTENT arrives @@ -249,22 +245,17 @@ find "${UV_CACHE_DIR}" -type d -path "*ray/_private/runtime_env/agent/thirdparty # jackson-databind / jackson-core CVEs: drop ray's bundled ray_dist.jar, which only backs Ray's Java # worker support (unused - no JVM here). Removed before the prefetch so no venv symlinks to it. find "${UV_CACHE_DIR}" -type d -path "*/ray/jars" -exec rm -rf {} + || true -EOF -# Replace the FFmpeg-bundling av / opencv / decord2 copies with vendored cp313 wheels (CVE). -RUN --mount=from=ffmpeg-vlm-wheel-src,target=/tmp/ffmpeg,readonly <<"EOF" bash -exu -for site in /opt/nemo_rl_venv/lib/python*/site-packages; do - [ -d "${site}" ] || continue - rm -rf \ - "${site}/av" "${site}"/av-*.dist-info "${site}/av.libs" \ - "${site}/cv2" "${site}/opencv_python_headless.libs" "${site}"/opencv_python_headless-*.dist-info \ - "${site}/decord" "${site}"/decord-*.dist-info "${site}/decord.libs" \ - "${site}/decord2" "${site}"/decord2-*.dist-info "${site}/decord2.libs" -done -uv pip install --python /opt/nemo_rl_venv/bin/python --no-cache --no-deps --reinstall \ - /tmp/ffmpeg/wheels/av-*-abi3-manylinux_2_28_*.whl \ - /tmp/ffmpeg/wheels/opencv_python_headless-*cp313*.whl \ - /tmp/ffmpeg/wheels/decord2-*cp313*.whl +# FFmpeg CVEs (CVE-2026-8461 + CVE-2026-64830..64835): PyNvVideoCodec bundles FFmpeg 8.1.1 shared +# libraries, which the scan reports as `ffmpeg` whatever the Python package version is. vLLM pins it +# so it cannot leave the lock, but nothing on the DPO/GRPO path reaches it: vLLM defaults to the +# `opencv` video backend and imports PyNvVideoCodec inside decode_frames_pynvvideocodec(), so only +# the opt-in `pynvvideocodec` backend breaks. Upgrading does not help - 2.2.0 ships FFmpeg 8.1.2, +# which fixes only one of the seven. The second pattern is the wheel's vendored FFmpeg source +# tarball. Removed before the prefetch so no venv symlinks into it; only these two directories go, +# so uv still sees the package as cached and does not re-download it. +find "${UV_CACHE_DIR}" -type d \ + \( -name PyNvVideoCodec -o -name 'pynvvideocodec-*.data' \) -exec rm -rf {} + || true EOF # Full RL source including submodules (Automodel, Megatron-Bridge + nested Megatron-LM, Gym). Copied diff --git a/docker/rl/README.md b/docker/rl/README.md index eb43d6cbba..a1617c638c 100644 --- a/docker/rl/README.md +++ b/docker/rl/README.md @@ -349,19 +349,6 @@ the uv cache + venv prefetch rather than via wheel images: stages pinned to RL's exact commits, kept in lockstep with `uv.lock`. - **Transformer-Engine** is the longest compile, but it is not built at all now — it only exists in the unused `automodel` / `mcore` extras (see the note above). - -## CVE handling - -- **Version floors** for the ecosystem (aiohttp, cryptography, urllib3, protobuf, av, - …) come from NeMo-RL's `constraint-dependencies` / `override-dependencies` in its - `pyproject.toml`. We inherit them by building from RL's lock — nothing to do here. -- **FFmpeg-bundling wheels** (`av`, `opencv-python-headless`, `decord2`) statically - embed FFmpeg codec libraries that carry CVEs regardless of the Python package - version, so a version bump alone doesn't fix them. The base deletes the PyPI copies - and reinstalls clean `cp313` wheels built against a patched FFmpeg (from - `docker/base/Dockerfile.python-wheels`). -- **Ray's bundled aiohttp** is removed from the uv cache to fully address its CVE. -- **The interpreter needs `UV_PYTHON`, not just `PYTHON_VERSION`.** NeMo-RL ships a `.python-version` pinning an exact patch release, which uv honours over whatever `uv python install` provisioned. Bumping `PYTHON_VERSION` alone therefore fixed nothing: every venv came up on RL's version while ours sat unused on disk, so the image shipped From 4ade415685ee56fc7058381e83a2ec9b2323d21a Mon Sep 17 00:00:00 2001 From: anubhutiv Date: Thu, 6 Aug 2026 18:59:19 -0700 Subject: [PATCH 2/2] update nemo-rl tag Signed-off-by: anubhutiv --- docker-bake.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index ee0fa33149..d9b66d7db4 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -100,7 +100,7 @@ variable "NEMO_RL_REPO" { # RL pins Gym as a git submodule (-> soluwalana/Gym over https), so Gym rides in with the RL git ADD # - no separate Gym pin needed. variable "NEMO_RL_REF" { - default = "1427564b347ee0a4b672182a8a98048ed2785217" # soluwalana/RL nmp/customizer + default = "ace40313d474f33cabc9a8fdf13d8dd4dda218c8" # soluwalana/RL nmp/customizer } variable "RL_BASE_CONTEXT" { default = ""