diff --git a/meta-python/recipes-devtools/python/python3-virtualenv/CVE-2026-113725.patch b/meta-python/recipes-devtools/python/python3-virtualenv/CVE-2026-113725.patch new file mode 100644 index 0000000000..3528680b40 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-virtualenv/CVE-2026-113725.patch @@ -0,0 +1,88 @@ +From c3104e02474b652832a9bbaae79f6e1696296932 Mon Sep 17 00:00:00 2001 +From: Bernát Gábor +Date: Sun, 11 Oct 2026 17:36:53 -0700 +Subject: [PATCH] fix(activation): escape the bash prompt for both PS1 + passes (#3390) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +bash handles `PS1` in two passes each time it draws the prompt: it first +decodes backslash prompt escapes, turning `\\` into `\` and `\$` into +`$` (or `#` for root), and then expands the result. The bash `activate` +script escaped the environment name for the expansion pass only (#3326), +so a backslash in the name undoes that escaping. 🔐 A name such as +`a\$(touch PWNED)`, from the directory, `--prompt` or +`VIRTUALENV_PROMPT`, runs the command each time bash draws the prompt. +For root, `\$` decodes to `#`, so the same name renders wrong but runs +nothing. + +Under bash, `activate` now escapes backslashes, dollar signs and +backticks a second time, so both passes leave the name literal. zsh does +no decode pass, so it keeps the single escaping added in 5b915367. The +prompt tests gain cases for a backslash before `$(...)` and before +backticks, and for names with a backslash before `$`, before a backtick, +doubled, and trailing; they render through bash 5.2 and zsh 5.9 and pass +as root and as an unprivileged user. + +Every release up to 21.14.6 is affected, and earlier releases before +21.13.0 do not escape the name at all. + +CVE: CVE-2026-113725 +Upstream-Status: Backport [https://github.com/pypa/virtualenv/commit/c3104e02474b652832a9bbaae79f6e1696296932] + +Backport Changes: +- Omit the release-only changelog fragment; the release documentation + directory is absent from the 21.2.1 source distribution. + +Signed-off-by: Hetvi Thakar +--- + src/virtualenv/activation/bash/activate.sh | 8 +++++++- + tests/unit/activation/test_bash.py | 6 ++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/virtualenv/activation/bash/activate.sh b/src/virtualenv/activation/bash/activate.sh +index 0a372ff..1551d85 100644 +--- a/src/virtualenv/activation/bash/activate.sh ++++ b/src/virtualenv/activation/bash/activate.sh +@@ -119,7 +119,13 @@ if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + # bash, and zsh under PROMPT_SUBST, re-expand backslashes, dollar signs and backticks in PS1 on every redraw; + # zsh gets the escaping even without the option, since a user can set it after activation. The guards keep + # the substitution away from POSIX shells such as dash, which reject it with "Bad substitution" +- if [ -n "${BASH_VERSION-}${ZSH_VERSION-}" ]; then ++ if [ -n "${BASH_VERSION-}" ]; then ++ # bash first decodes its backslash prompt escapes, turning \\ into \ and \$ into $ (or # for root), and only ++ # then expands the result, so each character needs escaping for both passes ++ _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\\/\\\\\\\\}" ++ _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\$/\\\\\$}" ++ _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\`/\\\\\`}" ++ elif [ -n "${ZSH_VERSION-}" ]; then + _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\\/\\\\}" + _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\$/\\\$}" + _VIRTUAL_PROMPT="${_VIRTUAL_PROMPT//\`/\\\`}" +diff --git a/tests/unit/activation/test_bash.py b/tests/unit/activation/test_bash.py +index defd2ed..4512932 100644 +--- a/tests/unit/activation/test_bash.py ++++ b/tests/unit/activation/test_bash.py +@@ -200,6 +200,8 @@ def prompt_after_activate( + pytest.param("x$(touch PWNED)y", "env", id="prompt-command-substitution"), + pytest.param("x`touch PWNED`y", "env", id="prompt-backticks"), + pytest.param("x${$(touch PWNED)}y", "env", id="prompt-parameter-expansion"), ++ pytest.param("x\\$(touch PWNED)y", "env", id="prompt-backslash-command-substitution"), ++ pytest.param("x\\`touch PWNED`y", "env", id="prompt-backslash-backticks"), + pytest.param(None, "x$(touch PWNED)y", id="dirname-command-substitution"), + ], + ) +@@ -217,6 +219,10 @@ def test_prompt_does_not_run_commands( + [ + pytest.param("myenv", id="plain"), + pytest.param("a%n$HOME\\b`c`", id="special-characters"), ++ pytest.param("a\\$HOME", id="backslash-before-dollar"), ++ pytest.param("a\\`c`", id="backslash-before-backtick"), ++ pytest.param("x\\\\y", id="doubled-backslash"), ++ pytest.param("e\\", id="trailing-backslash"), + ], + ) + def test_prompt_renders_name_literally( +-- +2.35.6 diff --git a/meta-python/recipes-devtools/python/python3-virtualenv_21.2.1.bb b/meta-python/recipes-devtools/python/python3-virtualenv_21.2.1.bb index cfb220fe41..9cf1ea3b6b 100644 --- a/meta-python/recipes-devtools/python/python3-virtualenv_21.2.1.bb +++ b/meta-python/recipes-devtools/python/python3-virtualenv_21.2.1.bb @@ -20,6 +20,7 @@ SRC_URI += " \ file://CVE-2026-113776.patch \ file://CVE-2026-113726-dependent.patch \ file://CVE-2026-113726.patch \ + file://CVE-2026-113725.patch \ " BBCLASSEXTEND = "native nativesdk"