* [OE-core][scarthgap][PATCH] python3-click: fix CVE-2026-7246
@ 2026-08-21 16:32 Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-09-05 23:16 ` Yoann Congal
0 siblings, 1 reply; 3+ messages in thread
From: Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-08-21 16:32 UTC (permalink / raw)
To: openembedded-core; +Cc: Darsh Kelaiya
From: Darsh Kelaiya <dkelaiya@cisco.com>
This patch applies the upstream fix for CVE-2026-7246 as referenced
in [2], using the upstream commit identified in [1].
The backport also adapts editor regression tests from the upstream
test and documentation follow-up identified in [3]. This follow-up
does not contain an additional production security fix.
[1] https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42
[2] https://github.com/tsigouris007/security-advisories/security/advisories/GHSA-47fr-3ffg-hgmw
[3] https://github.com/pallets/click/commit/b55294797ef32e22eb41e7d9657edb8faefa4976
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
.../python/python3-click/CVE-2026-7246.patch | 245 ++++++++++++++++++
.../python/python3-click_8.1.7.bb | 5 +-
2 files changed, 249 insertions(+), 1 deletion(-)
create mode 100644 meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
diff --git a/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
new file mode 100644
index 0000000000..47ee1a551f
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
@@ -0,0 +1,245 @@
+From cb30f575b1a251e8698909bca2a443d41dad1824 Mon Sep 17 00:00:00 2001
+From: Kevin Deldycke <kevin@deldycke.com>
+Date: Wed, 4 Mar 2026 14:51:58 +0400
+Subject: [PATCH] Document and fix command string sanitizing with `shlex.split`
+
+Removes last use of `shell=True` use for command invokation for defense-in-depth.
+Refs: #1026, #1477 and #2775
+
+CVE: CVE-2026-7246
+Upstream-Status: Backport [https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42]
+
+Backport Changes:
+- Click 8.1.7 uses Editor.edit_file(filename), not the newer
+ Editor.edit_files(filenames) API. Apply the argv-list change
+ to one filename without adding the multi-file API.
+- Adapt editor tests from b96c2601 and follow-up b5529479 to
+ the single-file API. Keep portable normalization, quoting,
+ failure, environment, Windows, and malformed-command cases.
+- Omit CHANGES.rst because release notes are not needed for
+ the source backport.
+- Omit pager changes and pager-only follow-up tests because
+ Click 8.1.7 uses older pager APIs and CVE-2026-7246 affects
+ click.edit(), not pager execution.
+- Omit the unrelated _translate_ch_to_exc() return cleanup.
+
+(cherry picked from commit b96c2601af4e01341b4d2c0db494ebee4aef8f42)
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ src/click/_termui_impl.py | 10 ++-
+ tests/test_termui.py | 163 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 172 insertions(+), 1 deletion(-)
+
+diff --git a/src/click/_termui_impl.py b/src/click/_termui_impl.py
+index f744657..3589160 100644
+--- a/src/click/_termui_impl.py
++++ b/src/click/_termui_impl.py
+@@ -501,6 +501,8 @@ class Editor:
+ return "vi"
+
+ def edit_file(self, filename: str) -> None:
++ """Open a file in the user's editor."""
++ import shlex
+ import subprocess
+
+ editor = self.get_editor()
+@@ -511,7 +513,13 @@ class Editor:
+ environ.update(self.env)
+
+ try:
+- c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True)
++ # Split in POSIX mode (the default) for the same reasons as
++ # upstream pager(): strips quotes from tokens and preserves
++ # quoted Windows paths. See issue #1026 and PR #1477.
++ c = subprocess.Popen(
++ args=shlex.split(editor) + [filename],
++ env=environ,
++ )
+ exit_code = c.wait()
+ if exit_code != 0:
+ raise ClickException(
+diff --git a/tests/test_termui.py b/tests/test_termui.py
+index 7cfa939..eda9a80 100644
+--- a/tests/test_termui.py
++++ b/tests/test_termui.py
+@@ -1,10 +1,12 @@
+ import platform
+ import time
++from unittest.mock import patch
+
+ import pytest
+
+ import click._termui_impl
+ from click._compat import WIN
++from click._termui_impl import Editor
+
+
+ class FakeClock:
+@@ -369,6 +371,167 @@ def test_fast_edit(runner):
+ assert result == "aTest\nbTest\n"
+
+
++@pytest.mark.parametrize(
++ ("editor_cmd", "filename", "expected_args"),
++ [
++ pytest.param(
++ "myeditor --wait --flag",
++ "file1.txt",
++ ["myeditor", "--wait", "--flag", "file1.txt"],
++ id="editor with args",
++ ),
++ pytest.param(
++ "vi",
++ 'file"; rm -rf / ; echo "',
++ ["vi", 'file"; rm -rf / ; echo "'],
++ id="shell metacharacters in filename",
++ ),
++ # Issue #1026: editor path with spaces must be quoted.
++ pytest.param(
++ '"C:\\Program Files\\Sublime Text 3\\sublime_text.exe"',
++ "f.txt",
++ ["C:\\Program Files\\Sublime Text 3\\sublime_text.exe", "f.txt"],
++ id="quoted windows path with spaces (issue 1026)",
++ ),
++ # PR #1477: pager/editor command with flags, like ``less -FRSX``.
++ pytest.param(
++ "less -FRSX",
++ "f.txt",
++ ["less", "-FRSX", "f.txt"],
++ id="command with flags (pr 1477)",
++ ),
++ # Issue #1026: quoted command with ``--wait`` flag.
++ pytest.param(
++ '"my command" --option value arg',
++ "f.txt",
++ ["my command", "--option", "value", "arg", "f.txt"],
++ id="quoted command with args (issue 1026)",
++ ),
++ # PR #1477: unquoted Unix path.
++ pytest.param(
++ "/usr/bin/vim",
++ "f.txt",
++ ["/usr/bin/vim", "f.txt"],
++ id="unix absolute path",
++ ),
++ # Issue #1026: macOS path with escaped space.
++ pytest.param(
++ "/Applications/Sublime\\ Text.app/Contents/SharedSupport/bin/subl",
++ "f.txt",
++ ["/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl", "f.txt"],
++ id="escaped space in unix path (issue 1026)",
++ ),
++ pytest.param(
++ " vim ",
++ "f.txt",
++ ["vim", "f.txt"],
++ id="leading and trailing whitespace",
++ ),
++ pytest.param(
++ "vim\t--clean",
++ "f.txt",
++ ["vim", "--clean", "f.txt"],
++ id="tab-separated tokens",
++ ),
++ pytest.param(
++ "'/Applications/My Editor.app/Contents/MacOS/editor'",
++ "f.txt",
++ ["/Applications/My Editor.app/Contents/MacOS/editor", "f.txt"],
++ id="single-quoted path with spaces",
++ ),
++ pytest.param(
++ '"my editor" --wait --new-window',
++ "file 1.txt",
++ ["my editor", "--wait", "--new-window", "file 1.txt"],
++ id="quoted editor with flags and filename with spaces",
++ ),
++ pytest.param(
++ "vim -u NONE -N",
++ "f.txt",
++ ["vim", "-u", "NONE", "-N", "f.txt"],
++ id="multiple short flags",
++ ),
++ pytest.param(
++ "editor",
++ 'file"name.txt',
++ ["editor", 'file"name.txt'],
++ id="filename with double quote",
++ ),
++ pytest.param(
++ "editor",
++ "file'name.txt",
++ ["editor", "file'name.txt"],
++ id="filename with single quote",
++ ),
++ ],
++)
++def test_editor_path_normalization(editor_cmd, filename, expected_args):
++ with patch("subprocess.Popen") as mock_popen:
++ mock_popen.return_value.wait.return_value = 0
++ Editor(editor=editor_cmd).edit_file(filename)
++
++ mock_popen.assert_called_once()
++ args = mock_popen.call_args[1].get("args") or mock_popen.call_args[0][0]
++ assert args == expected_args
++ assert mock_popen.call_args[1].get("shell") is None
++
++
++@pytest.mark.skipif(not WIN, reason="Windows-specific editor paths")
++@pytest.mark.parametrize(
++ ("editor_cmd", "expected_cmd"),
++ [
++ pytest.param(
++ "notepad",
++ ["notepad"],
++ id="plain notepad",
++ ),
++ pytest.param(
++ '"C:\\Program Files\\Sublime Text 3\\sublime_text.exe" --wait',
++ ["C:\\Program Files\\Sublime Text 3\\sublime_text.exe", "--wait"],
++ id="quoted path with flag",
++ ),
++ ],
++)
++def test_editor_windows_path_normalization(editor_cmd, expected_cmd):
++ """Verify that Popen receives unquoted Windows editor paths."""
++ with patch("subprocess.Popen") as mock_popen:
++ mock_popen.return_value.wait.return_value = 0
++ Editor(editor=editor_cmd).edit_file("f.txt")
++
++ args = mock_popen.call_args[1].get("args") or mock_popen.call_args[0][0]
++ assert args == expected_cmd + ["f.txt"]
++ assert mock_popen.call_args[1].get("shell") is None
++
++
++def test_editor_env_passed_through():
++ with patch("subprocess.Popen") as mock_popen:
++ mock_popen.return_value.wait.return_value = 0
++ Editor(editor="vi", env={"MY_VAR": "1"}).edit_file("f.txt")
++
++ env = mock_popen.call_args[1].get("env")
++ assert env is not None
++ assert env["MY_VAR"] == "1"
++
++
++def test_editor_failure_exception():
++ with patch("subprocess.Popen") as mock_popen:
++ mock_popen.return_value.wait.return_value = 1
++ with pytest.raises(click.ClickException, match="Editing failed"):
++ Editor(editor="vi").edit_file("f.txt")
++
++
++def test_editor_nonexistent_exception():
++ with patch("subprocess.Popen", side_effect=OSError("not found")):
++ with pytest.raises(click.ClickException, match="not found"):
++ Editor(editor="nonexistent").edit_file("f.txt")
++
++
++def test_editor_unclosed_quote():
++ """An unclosed quote in the editor command raises ValueError."""
++ with pytest.raises(ValueError, match="No closing quotation"):
++ Editor(editor='"unclosed').edit_file("f.txt")
++
++
+ @pytest.mark.parametrize(
+ ("prompt_required", "required", "args", "expect"),
+ [
diff --git a/meta/recipes-devtools/python/python3-click_8.1.7.bb b/meta/recipes-devtools/python/python3-click_8.1.7.bb
index 7d91e1af83..3c6f4df5e2 100644
--- a/meta/recipes-devtools/python/python3-click_8.1.7.bb
+++ b/meta/recipes-devtools/python/python3-click_8.1.7.bb
@@ -12,7 +12,9 @@ SRC_URI[sha256sum] = "ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b
inherit pypi setuptools3 ptest
-SRC_URI += "file://run-ptest"
+SRC_URI += "file://run-ptest \
+ file://CVE-2026-7246.patch \
+ "
RDEPENDS:${PN}-ptest += " \
python3-pytest \
@@ -34,6 +36,7 @@ CLEANBROKEN = "1"
RDEPENDS:${PN} += "\
python3-io \
python3-threading \
+ python3-shell \
"
BBCLASSEXTEND = "native nativesdk"
--
2.35.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [OE-core][scarthgap][PATCH] python3-click: fix CVE-2026-7246
2026-08-21 16:32 [OE-core][scarthgap][PATCH] python3-click: fix CVE-2026-7246 Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
@ 2026-09-05 23:16 ` Yoann Congal
2026-09-07 9:26 ` [scarthgap][PATCH] " Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
0 siblings, 1 reply; 3+ messages in thread
From: Yoann Congal @ 2026-09-05 23:16 UTC (permalink / raw)
To: dkelaiya, openembedded-core
On Fri Aug 21, 2026 at 6:32 PM CEST, Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org wrote:
> From: Darsh Kelaiya <dkelaiya@cisco.com>
>
> This patch applies the upstream fix for CVE-2026-7246 as referenced
> in [2], using the upstream commit identified in [1].
>
> The backport also adapts editor regression tests from the upstream
> test and documentation follow-up identified in [3]. This follow-up
> does not contain an additional production security fix.
>
> [1] https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42
> [2] https://github.com/tsigouris007/security-advisories/security/advisories/GHSA-47fr-3ffg-hgmw
> [3] https://github.com/pallets/click/commit/b55294797ef32e22eb41e7d9657edb8faefa4976
>
> Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
> ---
> .../python/python3-click/CVE-2026-7246.patch | 245 ++++++++++++++++++
> .../python/python3-click_8.1.7.bb | 5 +-
> 2 files changed, 249 insertions(+), 1 deletion(-)
> create mode 100644 meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
>
> diff --git a/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
> new file mode 100644
> index 0000000000..47ee1a551f
> --- /dev/null
> +++ b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
> @@ -0,0 +1,245 @@
> +From cb30f575b1a251e8698909bca2a443d41dad1824 Mon Sep 17 00:00:00 2001
> +From: Kevin Deldycke <kevin@deldycke.com>
> +Date: Wed, 4 Mar 2026 14:51:58 +0400
> +Subject: [PATCH] Document and fix command string sanitizing with `shlex.split`
> +
> +Removes last use of `shell=True` use for command invokation for defense-in-depth.
> +Refs: #1026, #1477 and #2775
> +
> +CVE: CVE-2026-7246
> +Upstream-Status: Backport [https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42]
> +
> +Backport Changes:
> +- Click 8.1.7 uses Editor.edit_file(filename), not the newer
> + Editor.edit_files(filenames) API. Apply the argv-list change
> + to one filename without adding the multi-file API.
> +- Adapt editor tests from b96c2601 and follow-up b5529479 to
Hello,
This commit has both b96c2601 and b5529479 squashed. Please keep
upstream backport patches split.
Can you send a v2 with as the CVE fix (b96c2601) and its followup
(b5529479)?
Thanks!
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [scarthgap][PATCH] python3-click: fix CVE-2026-7246
2026-09-05 23:16 ` Yoann Congal
@ 2026-09-07 9:26 ` Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
0 siblings, 0 replies; 3+ messages in thread
From: Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-09-07 9:26 UTC (permalink / raw)
To: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 3415 bytes --]
On Sun, Sep 6, 2026 at 04:46 AM, Yoann Congal wrote:
>
> On Fri Aug 21, 2026 at 6:32 PM CEST, Darsh Kelaiya -X (dkelaiya - E
> INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org wrote:
>
>> From: Darsh Kelaiya <dkelaiya@cisco.com>
>>
>> This patch applies the upstream fix for CVE-2026-7246 as referenced
>> in [2], using the upstream commit identified in [1].
>>
>> The backport also adapts editor regression tests from the upstream
>> test and documentation follow-up identified in [3]. This follow-up
>> does not contain an additional production security fix.
>>
>> [1] https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42
>>
>> [2] https://github.com/tsigouris007/security-advisories/security/advisories/GHSA-47fr-3ffg-hgmw
>>
>> [3] https://github.com/pallets/click/commit/b55294797ef32e22eb41e7d9657edb8faefa4976
>>
>>
>> Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
>> ---
>> .../python/python3-click/CVE-2026-7246.patch | 245 ++++++++++++++++++
>> .../python/python3-click_8.1.7.bb | 5 +-
>> 2 files changed, 249 insertions(+), 1 deletion(-)
>> create mode 100644
>> meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
>>
>> diff --git
>> a/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
>> b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
>> new file mode 100644
>> index 0000000000..47ee1a551f
>> --- /dev/null
>> +++ b/meta/recipes-devtools/python/python3-click/CVE-2026-7246.patch
>> @@ -0,0 +1,245 @@
>> +From cb30f575b1a251e8698909bca2a443d41dad1824 Mon Sep 17 00:00:00 2001
>> +From: Kevin Deldycke <kevin@deldycke.com>
>> +Date: Wed, 4 Mar 2026 14:51:58 +0400
>> +Subject: [PATCH] Document and fix command string sanitizing with
>> `shlex.split`
>> +
>> +Removes last use of `shell=True` use for command invokation for
>> defense-in-depth.
>> +Refs: #1026, #1477 and #2775
>> +
>> +CVE: CVE-2026-7246
>> +Upstream-Status: Backport [ https://github.com/pallets/click/commit/b96c2601af4e01341b4d2c0db494ebee4aef8f42
>> ]
>> +
>> +Backport Changes:
>> +- Click 8.1.7 uses Editor.edit_file(filename), not the newer
>> + Editor.edit_files(filenames) API. Apply the argv-list change
>> + to one filename without adding the multi-file API.
>> +- Adapt editor tests from b96c2601 and follow-up b5529479 to
>
> Hello,
>
> This commit has both b96c2601 and b5529479 squashed. Please keep
> upstream backport patches split.
>
> Can you send a v2 with as the CVE fix (b96c2601) and its followup
> (b5529479)?
>
> Thanks!
>
> --
> Yoann Congal
> Smile ECS
Hi Yoann,
While preparing v2, I noticed that NVD now marks CVE-2026-7246 as disputed and states that the Pallets Click project does not consider it a valid vulnerability:
https://nvd.nist.gov/vuln/detail/CVE-2026-7246
However, the published advisory identifies upstream commit b96c2601 as the fix:
https://github.com/tsigouris007/security-advisories/security/advisories/GHSA-47fr-3ffg-hgmw
Upstream describes the removal of shell=True as defense-in-depth, so I wanted to confirm the preferred handling. Should I replace the backport patches with a status entry such as:
CVE_STATUS[CVE-2026-7246] = "disputed: Pallets Click does not consider this a valid vulnerability"
Or should I continue with the split v2 backport patches as hardening?
Thanks,
Darsh
[-- Attachment #2: Type: text/html, Size: 4324 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-07 9:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 16:32 [OE-core][scarthgap][PATCH] python3-click: fix CVE-2026-7246 Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-09-05 23:16 ` Yoann Congal
2026-09-07 9:26 ` [scarthgap][PATCH] " Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.