fix(cve): CVE-2026-33186 - upgrade grpcio 1.76.0 -> 1.80.0 [rhoai-3.3]#2190
Conversation
…txt (opendatahub-io#2886) RHAIENG-2458: CVE-2025-66418 urllib3 decompression vulnerability - Create dependencies/cve-constraints.txt as single source of truth for CVE-induced minimum version constraints - Update pylocks_generator.sh to use --constraints flag with CVE file - Update comments on urllib3 overrides in jupyter images to explain that override is needed because odh-elyra's appengine-python-standard has an obnoxious urllib3<2 constraint - Add docs/cves/python.md documenting the CVE resolution workflow This approach: - Centralizes CVE fixes in one file - Applies constraints at resolution time via uv pip compile --constraints - Uses override-dependencies only where needed (odh-elyra conflict) - Prevents CVEs from returning through transitive dependencies Thanks to Adriana Theodorakopoulou for contributing the CVE resolution workflow documentation. (cherry picked from commit 2e8d387)
(cherry picked from commit 012d396)
…generated-code failure (opendatahub-io#3034) The check-generated-code CI job is failing on main and all PRs because astral-sh/setup-uv@v7 installs version: "latest" (currently uv 0.10.6), which produces different pylock.toml output than the committed files. The root cause is astral-sh/uv#18081 (released in uv 0.10.5, 2026-02-23) which added wheel filtering to pylock.toml even in --universal mode. See opendatahub-io#3032. Fix: pin uv version in uv.toml using required-version, remove version: "latest" from all workflows so setup-uv auto-detects the pin, and regenerate pylocks. 1. Create uv.toml at repo root required-version = "==0.10.6" setup-uv@v7 auto-detects this and installs the pinned version. Locally, uv errors if the running version doesn't match. 2. Update .github/workflows/code-quality.yaml Two setup-uv blocks (lines 17-24 and 46-53): - Remove version: "latest" line - Rename step from "Install the latest version of uv" to "Install uv" 3. Update .github/workflows/docs.yaml One setup-uv block (lines 21-28): - Remove version: "latest" line - Rename step 4. Update .github/workflows/security.yaml One setup-uv block (lines 19-26): - Remove version: "latest" line - Rename step 5. Update .github/workflows/build-notebooks-TEMPLATE.yaml One setup-uv block (lines 304-311): - Remove version: "latest" line - Rename step 6. Update ci/generate_code.sh Line 4 has a fallback pip install "uv==0.9.6" — update to "uv==0.10.6" to match the pinned version. 7. Regenerate pylocks bash ci/generate_code.sh This regenerates the 6 affected pylock.toml files with uv 0.10.6 filtering. - uv.toml (new) - .github/workflows/code-quality.yaml - .github/workflows/docs.yaml - .github/workflows/security.yaml - .github/workflows/build-notebooks-TEMPLATE.yaml - ci/generate_code.sh - 6 pylock.*.toml files (regenerated) # Check that uv reads the required-version and doesn't error uv version # Regenerate and verify no diff bash ci/generate_code.sh git diff --stat # should show no changes after regeneration * ISSUE opendatahub-io#3032: chore(uv): create a ./uv wrapper to run the correct version of uv 1. Pre-flight check (lines 93-100): Added explicit validation that $UV wrapper exists and is executable before the existing command -v uv check. This prevents a misleading version error if the wrapper is missing. 2. Constraints flag (lines 291-316): Changed constraints_flag from a plain string to a bash array (local -a constraints_flag=()), and expanded it as "${constraints_flag[@]}" in the pip compile invocation. This avoids word-splitting on paths containing spaces. (cherry picked from commit 137aa9b)
…generator.sh` to Python (opendatahub-io#3057) **Files created:** - `scripts/pylocks_generator.py` -- Python rewrite of the bash script using typer for CLI **Files modified:** - `pyproject.toml` -- added `typer` to dev dependencies - `uv.lock` -- updated by `uv lock` to include typer as explicit dep - `Makefile` -- `refresh-lock-files` target now calls `python3 scripts/pylocks_generator.py` - `ci/generate_code.sh` -- uses `"${REPO_ROOT}/uv" run scripts/pylocks_generator.py` (consistent with adjacent lines) - `scripts/lockfile-generators/create-requirements-lockfile.sh` -- all references updated from `.sh` to `.py` **Files deleted:** - `scripts/pylocks_generator.sh` -- the original bash script **Verification results:** - `--help` shows the correct typer CLI with `INDEX_MODE` and `TARGET_DIR` arguments - Running against `jupyter/minimal/ubi9-python-3.12` produced byte-identical lock files to the bash script (zero diff after fixing arg formatting) - Correctly detects Python version, flavors, effective mode, and generates all three flavor locks (CPU, CUDA, ROCM) Minimal, focused PR: rewrite the script, update call sites, delete old script. No tests, no ruff include changes (follow-up). - **1 deleted file** (`pylocks_generator.sh`, 376 lines) - **1 added file** (`pylocks_generator.py`, ~200-250 lines), structured to mirror the bash script's section layout so reviewers can compare side by side - **4 small edits** (pyproject.toml, Makefile, ci/generate_code.sh, create-requirements-lockfile.sh) Add `typer` to `[dependency-groups] dev` in [pyproject.toml](pyproject.toml) (it's already in `uv.lock` as a transitive dep, but needs to be explicit). Run `uv lock` to sync. Use typer for CLI with the same interface as the bash script: ```python """Generate Python dependency lock files (pylock.toml) using uv pip compile.""" from __future__ import annotations import os import re import subprocess import sys from pathlib import Path import typer ROOT_DIR = Path(__file__).resolve().parent.parent UV = ROOT_DIR / "uv" CVE_CONSTRAINTS_FILE = ROOT_DIR / "dependencies" / "cve-constraints.txt" PUBLIC_INDEX = "--default-index=https://pypi.org/simple" MAIN_DIRS = ["jupyter", "runtimes", "rstudio", "codeserver"] UV_MIN_VERSION = (0, 4, 0) app = typer.Typer() @app.command() def main( index_mode: str = typer.Argument("auto", help="..."), target_dir: Path | None = typer.Argument(None, help="..."), ) -> None: ... ``` Key functions (same logical sections as the bash script): - `read_conf_value(conf_file: Path, key: str) -> str | None` -- simple line parser replacing awk - `check_uv()` -- verify `./uv` exists, parse version, compare as `tuple(int, ...)` >= `(0, 4, 0)` - `find_target_dirs(target_dir: Path | None) -> list[Path]` -- `pathlib.glob("**/pyproject.toml")` - `detect_flavors(project_dir: Path) -> set[str]` -- check `Dockerfile.{cpu,cuda,rocm}` existence - `get_index_flags(project_dir: Path, flavor: str) -> list[str] | None` -- read `build-args/<flavor>.conf` - `run_lock(project_dir, flavor, index_flags, mode, python_version, upgrade) -> bool` -- `subprocess.run(cwd=project_dir)` with list args Implementation notes: - Build the `uv pip compile` command as a list, conditionally appending `--upgrade` - Use `cwd=target_dir` in `subprocess.run()` and `os.path.relpath()` for CVE constraints path - `FORCE_LOCKFILES_UPGRADE` env var read via `os.environ.get()` - [Makefile](Makefile) line 443: `bash scripts/pylocks_generator.sh $(INDEX_MODE) $(DIR)` -> `python3 scripts/pylocks_generator.py $(INDEX_MODE) $(DIR)` - [ci/generate_code.sh](ci/generate_code.sh) line 11: `bash scripts/pylocks_generator.sh` -> `"${REPO_ROOT}/uv" run scripts/pylocks_generator.py` (matches the two lines above it) - [scripts/lockfile-generators/create-requirements-lockfile.sh](scripts/lockfile-generators/create-requirements-lockfile.sh) -- all references: - Line 31: `PYLOCKS_GENERATOR="scripts/pylocks_generator.sh"` -> `.py` - Line 43: help text reference - Line 57: help text reference - Lines 73-74: guard check and error message - Line 115: `bash "$PYLOCKS_GENERATOR"` -> `python3 "$PYLOCKS_GENERATOR"` Clean deletion. It remains in git history. Run `python3 scripts/pylocks_generator.py --help` and a targeted invocation like `python3 scripts/pylocks_generator.py auto jupyter/minimal/ubi9-python-3.12`. * Here's what I addressed from the CodeRabbit review: **Fixed (3 items):** - **Makefile**: Changed `python3` to `./uv run` so typer is available via the dev environment - **`mode: str` -> `mode: IndexMode`**: `run_lock` now takes the enum directly, and the caller passes `IndexMode.rh_index` / `IndexMode.public_index` instead of raw strings - **`find_target_dirs` sort/dedup**: Uses a `set` for dedup and returns `sorted(dirs)` for stable CI output **Rejected (4 items):** - **`@app.callback()`**: Tested it -- produces a misleading `COMMAND [ARGS]...` in help. `@app.command()` works correctly with enum arguments; `auto` is parsed as the enum value, not a subcommand name - **`read_conf_value` hardening (export/quotes)**: The actual `.conf` files don't use these patterns, and the original bash awk parser didn't handle them either. Unnecessary scope creep - **Skipped dirs tracking**: The bash script didn't track these either. Behavior parity - **`source "$CONF_FILE"` in create-requirements-lockfile.sh**: Pre-existing, not introduced by this PR (cherry picked from commit 8da26d3)
…pt (opendatahub-io#3077) (cherry picked from commit 8239f40)
The shell script was replaced by the Python rewrite in this PR. Update docs/cves/python.md to reference pylocks_generator.py and the ./uv wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update grpcio from 1.76.0 to 1.80.0 across all 13 workbench and
pipeline runtime images to fix gRPC-Go authorization bypass via
improper HTTP/2 :path pseudo-header validation.
Changes:
- Updated grpcio in 13 pylock.toml files: 1.76.0 -> 1.80.0
- Added grpcio>=1.79.3 constraint to dependencies/cve-constraints.txt
Affected images fixed:
- jupyter/{datascience,pytorch,tensorflow,rocm/*,pytorch+llmcompressor,trustyai}
- runtimes/{datascience,pytorch,tensorflow,rocm-*,pytorch+llmcompressor}
Note: codeserver, minimal images do not have grpcio as a dependency
(no change needed for those images).
Resolves: RHOAIENG-55333, RHOAIENG-55334, RHOAIENG-55335, RHOAIENG-55336,
RHOAIENG-55337, RHOAIENG-55338, RHOAIENG-55339, RHOAIENG-55340,
RHOAIENG-55341, RHOAIENG-55342, RHOAIENG-55332, RHOAIENG-55323,
RHOAIENG-55324, RHOAIENG-55325, RHOAIENG-55326, RHOAIENG-55327,
RHOAIENG-55328, RHOAIENG-55329
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
@swattamw2024 — This PR is from a fork. Recommended: Push your branch to the main repo for full CI: Then open a new PR from that branch. No push access? A maintainer will cherry-pick and test your changes. See CONTRIBUTING.md for details. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (38)
📝 WalkthroughWalkthroughThis PR establishes a pinned Changesuv Pinning & Lock Generation Refactor
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
CVE Details
CVE-2026-33186 — gRPC-Go: Authorization bypass via improper HTTP/2
:pathpseudo-header validationgrpcio(Python bindings for gRPC-Go)Fix Summary
grpcio>=1.79.3constraint todependencies/cve-constraints.txtpylock.tomllock filesNot Affected (grpcio not in dependency tree)
codeserver,minimalimages — grpcio is not a direct or transitive dependencyTest Results
Verification performed:
dependencies/cve-constraints.txtupdated with minimum version constraintBreaking Changes
None expected. grpcio is a pure gRPC transport library. The 1.76.0 → 1.80.0 upgrade contains the security fix and no breaking API changes per the gRPC changelog.
Verification Steps
Risk Assessment
Low — Version pin constraint added to centralized CVE constraints file. Lock files updated with correct cryptographic hashes from PyPI. The upgrade path (1.76.0 → 1.80.0) is a minor-version bump with no breaking changes.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes & Security
Chores
Documentation