* [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes
@ 2026-11-06 14:43 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 01/27] python3-git: fix CVE-2026-67326 Yogita Urade
` (27 more replies)
0 siblings, 28 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
Backport 27 GitPython security fixes covering 28 CVEs to the python3-git
3.1.43 recipe on wrynose. The series adds the fixes as patches and updates
the recipe to apply them.
CVE-2026-78678 and CVE-2026-78679 are addressed together. The CVE-2026-76222
fix includes a regression correction and follow-up patch, CVE-2026-73619
and CVE-2026-87819 are each carried in two patches. The patches retain
upstream references.
Changes in v2:
- Re-reviewed all patches and removed changes that were not needed for the backports.
- Restored upstream commit metadata and corrected CVE references.
- Updated Backport Changes notes to describe the differences from upstream.
- Removed trailing whitespace and regenerated the series diffstat.
Yogita Urade (27):
python3-git: fix CVE-2026-67326
python3-git: fix CVE-2026-67323
python3-git: Fix CVE-2026-67325
python3-git: Fix CVE-2026-67324
python3-git: fix CVE-2026-67322
python3-git: fix CVE-2026-69097
python3-git: fix CVE-2026-73625
python3-git: fix CVE-2026-73623
python3-git: fix CVE-2026-73624
python3-git: fix CVE-2026-73622
python3-git: fix CVE-2026-73621
python3-git: fix CVE-2026-73620
python3-git: fix CVE-2026-73619
python3-git: fix CVE-2026-76221
python3-git: fix CVE-2026-76220
python3-git: fix CVE-2026-76219
python3-git: fix CVE-2026-76218
python3-git: fix CVE-2026-76217
python3-git: fix CVE-2026-76222
python3-git: fix CVE-2026-78678 CVE-2026-78679
python3-git: fix CVE-2026-78677
python3-git: fix CVE-2026-78676
python3-git: fix CVE-2026-78675
python3-git: fix CVE-2026-87817
python3-git: fix CVE-2026-87818
python3-git: Fix CVE-2026-87819
python3-git: fix CVE-2026-100689
.../python/python3-git/CVE-2026-100689.patch | 91 +++++
.../python/python3-git/CVE-2026-67322.patch | 171 ++++++++
.../python/python3-git/CVE-2026-67323.patch | 356 +++++++++++++++++
.../python/python3-git/CVE-2026-67324.patch | 94 +++++
.../python/python3-git/CVE-2026-67325_p1.patch | 49 +++
.../python/python3-git/CVE-2026-67325_p2.patch | 52 +++
.../python/python3-git/CVE-2026-67326.patch | 107 +++++
.../python/python3-git/CVE-2026-69097.patch | 60 +++
.../python/python3-git/CVE-2026-73619_p1.patch | 58 +++
.../python/python3-git/CVE-2026-73619_p2.patch | 43 ++
.../python/python3-git/CVE-2026-73620.patch | 130 ++++++
.../python/python3-git/CVE-2026-73621.patch | 72 ++++
.../python/python3-git/CVE-2026-73622.patch | 60 +++
.../python/python3-git/CVE-2026-73623.patch | 53 +++
.../python/python3-git/CVE-2026-73624.patch | 139 +++++++
.../python/python3-git/CVE-2026-73625.patch | 59 +++
.../python/python3-git/CVE-2026-76217.patch | 179 +++++++++
.../python/python3-git/CVE-2026-76218.patch | 92 +++++
.../python/python3-git/CVE-2026-76219.patch | 153 +++++++
.../python/python3-git/CVE-2026-76220.patch | 65 +++
.../python/python3-git/CVE-2026-76221.patch | 59 +++
.../python3-git/CVE-2026-76222-regression.patch | 39 ++
.../python/python3-git/CVE-2026-76222_p1.patch | 118 ++++++
.../python/python3-git/CVE-2026-76222_p2.patch | 45 +++
.../python/python3-git/CVE-2026-78675.patch | 47 +++
.../python/python3-git/CVE-2026-78676.patch | 67 ++++
.../python/python3-git/CVE-2026-78677.patch | 87 ++++
.../CVE-2026-78678_CVE-2026-78679.patch | 220 ++++++++++
.../python/python3-git/CVE-2026-87817.patch | 443 +++++++++++++++++++++
.../python/python3-git/CVE-2026-87818.patch | 55 +++
.../python/python3-git/CVE-2026-87819_p1.patch | 78 ++++
.../python/python3-git/CVE-2026-87819_p2.patch | 146 +++++++
meta/recipes-devtools/python/python3-git_3.1.43.bb | 32 ++
33 files changed, 3519 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67322.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67323.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67324.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67325_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67325_p2.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67326.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-69097.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73619_p2.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73620.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73623.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73625.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76217.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76219.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76220.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76221.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222-regression.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78677.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78678_CVE-2026-78679.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87817.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch
--
2.53.0
^ permalink raw reply [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 01/27] python3-git: fix CVE-2026-67326
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 02/27] python3-git: fix CVE-2026-67323 Yogita Urade
` (26 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/54538428f79b0c91ba52cda5229856a6edf7ac06
[2] https://security-tracker.debian.org/tracker/CVE-2026-67326
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Cleaned whitespace in the Backport Changes note.
---
.../python/python3-git/CVE-2026-67326.patch | 107 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 108 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67326.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67326.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67326.patch
new file mode 100644
index 0000000000..82fc987fcc
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67326.patch
@@ -0,0 +1,107 @@
+From 89d7d33485f67d5f25777079797ae6d1a4538f86 Mon Sep 17 00:00:00 2001
+From: "GPT 5.5" <codex@openai.com>
+Date: Tue, 5 May 2026 21:34:42 +0800
+Subject: [PATCH] Validate config key section names before writing
+
+GitConfigParser already rejected CR, LF, and NUL in config values before
+writing, but section and option names could still reach configparser. Because
+GitPython writes section headers itself, a newline-bearing section name could
+split the output into additional headers.
+
+Reject CR, LF, and NUL in section and option names on write paths that create
+or set config keys: add_section(), set(), set_value(), add_value(), and
+rename_section() destinations. This matches Git config key validation behavior;
+Git source commit 94f057755b7941b321fd11fec1b2e3ca5313a4e0 reports invalid keys
+containing newlines from config.c, and local git 2.50.1 rejects newline-bearing
+config keys.
+
+Add a regression test covering unsafe section and option names while preserving
+safe writes.
+
+CVE: CVE-2026-67326
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/54538428f79b0c91ba52cda5229856a6edf7ac06]
+
+Backport Changes:
+- Omitted test/test_config.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 54538428f79b0c91ba52cda5229856a6edf7ac06)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/config.py | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/git/config.py b/git/config.py
+index 1595d51f..236de3a6 100644
+--- a/git/config.py
++++ b/git/config.py
+@@ -71,6 +71,9 @@ class MetaParserBuilder:
+
+ See: https://git-scm.com/docs/git-config#_conditional_includes
+ """
++UNSAFE_CONFIG_CHARS_RE = re.compile(r"[\r\n\x00]")
++"""Characters that cannot be safely written in config names or values."""
++
+
+
+ class MetaParserBuilder(abc.ABCMeta): # noqa: B024
+@@ -759,6 +762,7 @@ GitConfigParser.add_section
+
+ def add_section(self, section: str) -> None:
+ """Assures added options will stay in order."""
++ self._assure_config_name_safe(section, "section")
+ return super().add_section(section)
+
+ @property
+@@ -865,9 +869,13 @@ GitConfigParser._value_to_string_safe
+
+ def _value_to_string_safe(self, value: Union[str, bytes, int, float, bool]) -> str:
+ value_str = self._value_to_string(value)
+- if re.search(r"[\r\n\x00]", value_str):
++ if UNSAFE_CONFIG_CHARS_RE.search(value_str):
+ raise ValueError("Git config values must not contain CR, LF, or NUL")
+ return value_str
++ def _assure_config_name_safe(self, name: "cp._SectionName", label: str) -> None:
++ if isinstance(name, str) and UNSAFE_CONFIG_CHARS_RE.search(name):
++ raise ValueError("Git config %s names must not contain CR, LF, or NUL" % label)
++
+
+ @needs_values
+ @set_dirty_and_flush_changes
+@@ -877,6 +885,8 @@ GitConfigParser.set
+ option: str,
+ value: Union[str, bytes, int, float, bool, None] = None,
+ ) -> None:
++ self._assure_config_name_safe(section, "section")
++ self._assure_config_name_safe(option, "option")
+ if value is not None:
+ value = self._value_to_string_safe(value)
+ return super().set(section, option, value)
+@@ -901,6 +911,8 @@ GitConfigParser.set_value
+ :return:
+ This instance
+ """
++ self._assure_config_name_safe(section, "section")
++ self._assure_config_name_safe(option, "option")
+ value_str = self._value_to_string_safe(value)
+ if not self.has_section(section):
+ self.add_section(section)
+@@ -929,6 +941,8 @@ GitConfigParser.add_value
+ :return:
+ This instance
+ """
++ self._assure_config_name_safe(section, "section")
++ self._assure_config_name_safe(option, "option")
+ value_str = self._value_to_string_safe(value)
+ if not self.has_section(section):
+ self.add_section(section)
+@@ -949,6 +963,7 @@ GitConfigParser.rename_section
+ """
+ if not self.has_section(section):
+ raise ValueError("Source section '%s' doesn't exist" % section)
++ self._assure_config_name_safe(new_name, "section")
+ if self.has_section(new_name):
+ raise ValueError("Destination section '%s' already exists" % new_name)
+
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index ebb5e4b442..474206d4ed 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -21,6 +21,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-44243_p2.patch \
file://CVE-2026-44244_p1.patch \
file://CVE-2026-44244_p2.patch \
+ file://CVE-2026-67326.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 02/27] python3-git: fix CVE-2026-67323
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 01/27] python3-git: fix CVE-2026-67326 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 03/27] python3-git: Fix CVE-2026-67325 Yogita Urade
` (25 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/701ce32fe5ba8cb622c0e0342a376a6beb47d738
[2] https://security-tracker.debian.org/tracker/CVE-2026-67323
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Changed the ls_remote documentation to describe --upload-pack
without --exec.
---
.../python/python3-git/CVE-2026-67323.patch | 356 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 357 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67323.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67323.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67323.patch
new file mode 100644
index 0000000000..3901f6244b
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67323.patch
@@ -0,0 +1,356 @@
+From 80bf84d6f24adcc181b78d71fa94544924a85b2c Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Sun, 12 Jul 2026 15:06:42 +0200
+Subject: [PATCH] fix: Guard unsafe git command options (GHSA-956x-8gvw-wg5v)
+
+Reject command options that can execute arbitrary helpers or write files when passed through archive, revision traversal, blame, clone, fetch, pull, push, and ls-remote APIs. Validate positional option tokens and transformed keyword options consistently, including Git-supported long-option abbreviations, attached short-option values, and falsey stringifiable remotes. Preserve explicit allow_unsafe_options and allow_unsafe_protocols escape hatches.
+
+Add regression coverage for each guarded API, option spelling and abbreviation forms, inert keyword values, mixed positional and keyword candidates, tuple blame options, stringifiable remotes, and unsafe commands that must not create marker files.
+
+CVE: CVE-2026-67323
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/701ce32fe5ba8cb622c0e0342a376a6beb47d738]
+
+Backport Changes:
+- Omitted test/test_clone.py, test/test_commit.py, test/test_git.py,
+ test/test_remote.py, test/test_repo.py because the current PyPI
+ source archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Reviewed-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 701ce32fe5ba8cb622c0e0342a376a6beb47d738)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 37 +++++++++++++++++++++-
+ git/objects/commit.py | 12 +++++++
+ git/remote.py | 15 ++++++--
+ git/repo/base.py | 80 +++++++++++++++++++++++++++++++++++++++----
+ 4 files changed, 133 insertions(+), 11 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index bb8f93a8..87866be2 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -414,6 +414,11 @@ class Git:
+ "_version_info_token",
+ )
+
++ unsafe_git_ls_remote_options = [
++ # This option allows arbitrary command execution in git-ls-remote.
++ "--upload-pack",
++ ]
++
+ re_unsafe_protocol = re.compile(r"(.+)::.+")
+
+ def __getstate__(self) -> Dict[str, Any]:
+@@ -742,6 +747,20 @@ Git.check_unsafe_options
+ f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
+ )
+
++ @classmethod
++ def _option_candidates(cls, args: Sequence[Any] = (), kwargs: Optional[Mapping[str, Any]] = None) -> List[str]:
++ """Collect possible option spellings before command-line transformation."""
++ options = [
++ option for option in cls._unpack_args([arg for arg in args if arg is not None]) if option.startswith("-")
++ ]
++ if kwargs:
++ for key, value in kwargs.items():
++ values = value if isinstance(value, (list, tuple)) else (value,)
++ if any(value is True or (value is not False and value is not None) for value in values):
++ key = str(key)
++ options.append(f"-{key}" if len(key) == 1 else f"--{dashify(key)}")
++ return options
++
+ class AutoInterrupt:
+ """Process wrapper that terminates the wrapped process on finalization.
+
+@@ -999,6 +1019,22 @@ Git.__getattr__
+ return super().__getattribute__(name)
+ return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
+
++ def ls_remote(
++ self,
++ *args: Any,
++ allow_unsafe_options: bool = False,
++ **kwargs: Any,
++ ) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], "Git.AutoInterrupt"]:
++ """List references in a remote repository.
++
++ :param allow_unsafe_options:
++ Allow unsafe options, like ``--upload-pack``.
++ """
++ if not allow_unsafe_options:
++ candidate_options = self._option_candidates(args, kwargs)
++ Git.check_unsafe_options(options=candidate_options, unsafe_options=self.unsafe_git_ls_remote_options)
++ return self._call_process("ls_remote", *args, **kwargs)
++
+ def set_persistent_git_options(self, **kwargs: Any) -> None:
+ """Specify command line options to the git executable for subsequent
+ subcommand calls.
+@@ -1488,7 +1524,7 @@ Git._unpack_args
+ return args
+
+ @classmethod
+- def _unpack_args(cls, arg_list: Sequence[str]) -> List[str]:
++ def _unpack_args(cls, arg_list: Sequence[Any]) -> List[str]:
+ outlist = []
+ if isinstance(arg_list, (list, tuple)):
+ for arg in arg_list:
+diff --git a/git/objects/commit.py b/git/objects/commit.py
+index d957c905..6e2ff759 100644
+--- a/git/objects/commit.py
++++ b/git/objects/commit.py
+@@ -85,6 +85,12 @@ class Commit:
+
+ # INVARIANTS
+ default_encoding = "UTF-8"
++ # Options to :manpage:`git-rev-list(1)` that can overwrite files.
++ unsafe_git_rev_options = [
++ "--output",
++ "-o",
++ ]
++
+
+ type: Literal["commit"] = "commit"
+
+@@ -302,6 +308,7 @@ Commit.iter_items
+ repo: "Repo",
+ rev: Union[str, "Commit", "SymbolicReference"],
+ paths: Union[PathLike, Sequence[PathLike]] = "",
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> Iterator["Commit"]:
+ R"""Find all commits matching the given criteria.
+@@ -329,6 +336,11 @@ Commit.iter_items
+ if "pretty" in kwargs:
+ raise ValueError("--pretty cannot be used as parsing expects single sha's only")
+ # END handle pretty
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([rev], kwargs), unsafe_options=cls.unsafe_git_rev_options
++ )
++
+
+ # Use -- in all cases, to prevent possibility of ambiguous arguments.
+ # See https://github.com/gitpython-developers/GitPython/issues/264.
+diff --git a/git/remote.py b/git/remote.py
+index f2ecd0f3..cafa1f84 100644
+--- a/git/remote.py
++++ b/git/remote.py
+@@ -1061,7 +1061,10 @@ Remote.fetch
+ Git.check_unsafe_protocols(ref)
+
+ if not allow_unsafe_options:
+- Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=self.unsafe_git_fetch_options)
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=self.unsafe_git_fetch_options,
++ )
+
+ proc = self.repo.git.fetch(
+ "--", self, *args, as_process=True, with_stdout=False, universal_newlines=False, v=verbose, **kwargs
+@@ -1115,7 +1118,10 @@ Remote.pull
+ Git.check_unsafe_protocols(ref)
+
+ if not allow_unsafe_options:
+- Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=self.unsafe_git_pull_options)
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=self.unsafe_git_pull_options,
++ )
+
+ proc = self.repo.git.pull(
+ "--", self, refspec, with_stdout=False, as_process=True, universal_newlines=False, v=True, **kwargs
+@@ -1188,7 +1194,10 @@ Remote.push
+ Git.check_unsafe_protocols(ref)
+
+ if not allow_unsafe_options:
+- Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=self.unsafe_git_push_options)
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=self.unsafe_git_push_options,
++ )
+
+ proc = self.repo.git.push(
+ "--",
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 8059fceb..e9e7aa66 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -159,6 +159,20 @@ class Repo:
+ ``protocol.allow`` and ``core.gitProxy`` to execute arbitrary commands:
+ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---configltkeygtltvaluegt
+ """
++ unsafe_git_archive_options = [
++ # Allows arbitrary command execution through the remote git-upload-archive command.
++ "--exec",
++ # Writes output to a caller-controlled filesystem path.
++ "--output",
++ "-o",
++ ]
++
++ unsafe_git_revision_options = [
++ # This option allows output to be written to arbitrary files before revision parsing.
++ "--output",
++ "-o",
++ ]
++
+
+ # Invariants
+ config_level: ConfigLevels_Tup = ("system", "user", "global", "repository")
+@@ -743,6 +757,7 @@ Repo.iter_commits
+ self,
+ rev: Union[str, Commit, "SymbolicReference", None] = None,
+ paths: Union[PathLike, Sequence[PathLike]] = "",
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> Iterator[Commit]:
+ """An iterator of :class:`~git.objects.commit.Commit` objects representing the
+@@ -759,6 +774,9 @@ Repo.iter_commits
+ :param kwargs:
+ Arguments to be passed to :manpage:`git-rev-list(1)`.
+ Common ones are ``max_count`` and ``skip``.
++ :param allow_unsafe_options:
++ Allow unsafe options in the revision argument, like ``--output``.
++
+
+ :note:
+ To receive only commits between two named revisions, use the
+@@ -770,7 +788,18 @@ Repo.iter_commits
+ if rev is None:
+ rev = self.head.commit
+
+- return Commit.iter_items(self, rev, paths, **kwargs)
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([rev], kwargs), unsafe_options=self.unsafe_git_revision_options
++ )
++
++ return Commit.iter_items(
++ self,
++ rev,
++ paths,
++ allow_unsafe_options=allow_unsafe_options,
++ **kwargs,
++ )
+
+ def merge_base(self, *rev: TBD, **kwargs: Any) -> List[Commit]:
+ R"""Find the closest common ancestor for the given revision
+@@ -1035,7 +1064,9 @@ Repo.blame_incremental
+ # reveal_type(self.head.reference) # => Reference
+ return self.head.reference
+
+- def blame_incremental(self, rev: str | HEAD | None, file: str, **kwargs: Any) -> Iterator["BlameEntry"]:
++ def blame_incremental(
++ self, rev: str | HEAD | None, file: str, allow_unsafe_options: bool = False, **kwargs: Any
++ ) -> Iterator["BlameEntry"]:
+ """Iterator for blame information for the given file at the given revision.
+
+ Unlike :meth:`blame`, this does not return the actual file's contents, only a
+@@ -1046,6 +1077,9 @@ Repo.blame_incremental
+ uncommitted changes. Otherwise, anything successfully parsed by
+ :manpage:`git-rev-parse(1)` is a valid option.
+
++ :param allow_unsafe_options:
++ Allow unsafe options in revision argument, like ``--output``.
++
+ :return:
+ Lazy iterator of :class:`BlameEntry` tuples, where the commit indicates the
+ commit to blame for the line, and range indicates a span of line numbers in
+@@ -1055,6 +1089,10 @@ Repo.blame_incremental
+ a continuous range spanning all line numbers in the file.
+ """
+
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([rev], kwargs), unsafe_options=self.unsafe_git_revision_options
++ )
+ data: bytes = self.git.blame(rev, "--", file, p=True, incremental=True, stdout_as_string=False, **kwargs)
+ commits: Dict[bytes, Commit] = {}
+
+@@ -1132,7 +1170,8 @@ Repo.blame
+ rev: Union[str, HEAD, None],
+ file: str,
+ incremental: bool = False,
+- rev_opts: Optional[List[str]] = None,
++ rev_opts: Optional[Sequence[str]] = None,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> List[List[Commit | List[str | bytes] | None]] | Iterator[BlameEntry] | None:
+ """The blame information for the given file at the given revision.
+@@ -1141,6 +1180,9 @@ Repo.blame
+ Revision specifier. If ``None``, the blame will include all the latest
+ uncommitted changes. Otherwise, anything successfully parsed by
+ :manpage:`git-rev-parse(1)` is a valid option.
++ :param allow_unsafe_options:
++ Allow unsafe options in revision argument, like ``--output``.
++
+
+ :return:
+ list: [git.Commit, list: [<line>]]
+@@ -1151,9 +1193,14 @@ Repo.blame
+ appearance.
+ """
+ if incremental:
+- return self.blame_incremental(rev, file, **kwargs)
+- rev_opts = rev_opts or []
+- data: bytes = self.git.blame(rev, *rev_opts, "--", file, p=True, stdout_as_string=False, **kwargs)
++ return self.blame_incremental(rev, file, allow_unsafe_options=allow_unsafe_options, **kwargs)
++ rev_opts_list = list(rev_opts or [])
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([rev, rev_opts_list], kwargs),
++ unsafe_options=self.unsafe_git_revision_options,
++ )
++ data: bytes = self.git.blame(rev, *rev_opts_list, "--", file, p=True, stdout_as_string=False, **kwargs)
+ commits: Dict[str, Commit] = {}
+ blames: List[List[Commit | List[str | bytes] | None]] = []
+
+@@ -1364,7 +1411,10 @@ Repo.clone_from
+ if not allow_unsafe_protocols:
+ Git.check_unsafe_protocols(str(url))
+ if not allow_unsafe_options:
+- Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=cls.unsafe_git_clone_options)
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=cls.unsafe_git_clone_options,
++ )
+ if not allow_unsafe_options and multi:
+ Git.check_unsafe_options(options=multi, unsafe_options=cls.unsafe_git_clone_options)
+
+@@ -1539,6 +1589,8 @@ Repo.archive
+ ostream: Union[TextIO, BinaryIO],
+ treeish: Optional[str] = None,
+ prefix: Optional[str] = None,
++ allow_unsafe_options: bool = False,
++ allow_unsafe_protocols: bool = False,
+ **kwargs: Any,
+ ) -> Repo:
+ """Archive the tree at the given revision.
+@@ -1560,6 +1612,12 @@ Repo.archive
+ * You may specify the special ``path`` keyword, which may either be a
+ repository-relative path to a directory or file to place into the archive,
+ or a list or tuple of multiple paths.
++ :param allow_unsafe_options:
++ Allow unsafe options, like ``--exec`` or ``--output``.
++
++ :param allow_unsafe_protocols:
++ Allow unsafe protocols to be used in ``remote``, like ``ext``.
++
+
+ :raise git.exc.GitCommandError:
+ If something went wrong.
+@@ -1571,6 +1629,14 @@ Repo.archive
+ treeish = self.head.commit
+ if prefix and "prefix" not in kwargs:
+ kwargs["prefix"] = prefix
++ remote = kwargs.get("remote")
++ if not allow_unsafe_protocols and remote is not None:
++ Git.check_unsafe_protocols(str(remote))
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=self.unsafe_git_archive_options,
++ )
+ kwargs["output_stream"] = ostream
+ path = kwargs.pop("path", [])
+ path = cast(Union[PathLike, List[PathLike], Tuple[PathLike, ...]], path)
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 474206d4ed..72eb073196 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -22,6 +22,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-44244_p1.patch \
file://CVE-2026-44244_p2.patch \
file://CVE-2026-67326.patch \
+ file://CVE-2026-67323.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 03/27] python3-git: Fix CVE-2026-67325
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 01/27] python3-git: fix CVE-2026-67326 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 02/27] python3-git: fix CVE-2026-67323 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 04/27] python3-git: fix CVE-2026-67324 Yogita Urade
` (24 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
CVE-2026-67325 concerns bypasses using abbreviated long options.
Commit [1] introduces rejection of those abbreviations, and [2]
refines that check. The CVE description is in [3].
[1] https://github.com/gitpython-developers/GitPython/commit/2ab051697940144545a14d2f4a639c6409c3187f
[2] https://github.com/gitpython-developers/GitPython/commit/181e8ede7543dbbdcee92756cea260f675316c63
[3] https://nvd.nist.gov/vuln/detail/CVE-2026-67325
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Kept p1's UnsafeOptionError raise in upstream's multi-line form.
- Formatted p2's exact-match UnsafeOptionError raise on one line to match
upstream.
---
.../python3-git/CVE-2026-67325_p1.patch | 49 +++++++++++++++++
.../python3-git/CVE-2026-67325_p2.patch | 52 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 2 +
3 files changed, 103 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67325_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67325_p2.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p1.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p1.patch
new file mode 100644
index 0000000000..4c1f3195d9
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p1.patch
@@ -0,0 +1,49 @@
+From 048f65847761514ebccf3cd8a889fef7a0068c07 Mon Sep 17 00:00:00 2001
+From: abhiprd2000 <8292aniarc@gmail.com>
+Date: Thu, 9 Jul 2026 21:22:50 +0530
+Subject: [PATCH] Reject abbreviated forms of unsafe git options
+
+CVE: CVE-2026-67325
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/2ab051697940144545a14d2f4a639c6409c3187f]
+
+Backport Changes:
+- Omitted test/test_clone.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+(cherry picked from commit 2ab051697940144545a14d2f4a639c6409c3187f)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 87866be2..f8fead70 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -739,13 +739,20 @@ Git.check_unsafe_options
+ arbitrary commands. These are blocked by default.
+ """
+ # Options can be of the form `foo`, `--foo`, `--foo bar`, or `--foo=bar`.
++ # Git accepts any unambiguous prefix of a long option, so an abbreviated
++ # spelling such as `--upl` for `--upload-pack` must be rejected too. An
++ # option is unsafe if its canonical name is a prefix of any blocked
++ # option's canonical name.
+ canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
+ for option in options:
+- unsafe_option = canonical_unsafe_options.get(cls._canonicalize_option_name(option))
+- if unsafe_option is not None:
+- raise UnsafeOptionError(
+- f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
+- )
++ candidate = cls._canonicalize_option_name(option)
++ if not candidate:
++ continue
++ for canonical, unsafe_option in canonical_unsafe_options.items():
++ if canonical.startswith(candidate):
++ raise UnsafeOptionError(
++ f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
++ )
+
+ @classmethod
+ def _option_candidates(cls, args: Sequence[Any] = (), kwargs: Optional[Mapping[str, Any]] = None) -> List[str]:
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p2.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p2.patch
new file mode 100644
index 0000000000..65a914f0a0
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67325_p2.patch
@@ -0,0 +1,52 @@
+From 6de6760007664e5e9178b98e616d0b9edc959a53 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Sun, 12 Jul 2026 13:45:42 +0200
+Subject: [PATCH] Address review feedback about unsafe option abbreviations
+
+The prefix check could reject otherwise allowed one-letter short options when an unrelated blocked long option began with the same character. Keep exact matches for every spelling, but restrict prefix matching to explicit long options and multi-character kwargs.
+
+This addresses the review comment: single-letter short options and kwargs must not be treated as long-option abbreviations. It also adds coverage for abbreviated unsafe kwargs so both clone validation paths remain protected.
+
+CVE: CVE-2026-67325
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/181e8ede7543dbbdcee92756cea260f675316c63]
+
+Backport Changes:
+- Omitted test/test_clone.py, test/test_git.py because the current
+ PyPI source archive does not include the test suite and the
+ python3-git recipe does not run it.
+
+Reviewd-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 181e8ede7543dbbdcee92756cea260f675316c63)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index cd22aa83..3b97871e 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -742,14 +742,22 @@ Git.check_unsafe_options
+ # Git accepts any unambiguous prefix of a long option, so an abbreviated
+ # spelling such as `--upl` for `--upload-pack` must be rejected too. An
+ # option is unsafe if its canonical name is a prefix of any blocked
+- # option's canonical name.
++ # option's canonical name. Only long options and multi-character kwargs
++ # can be abbreviations; single-character short options remain exact-match
++ # only.
+ canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
++ options_are_kwargs = all(not option.startswith("-") for option in options)
+ for option in options:
+ candidate = cls._canonicalize_option_name(option)
+ if not candidate:
+ continue
++ unsafe_option = canonical_unsafe_options.get(candidate)
++ if unsafe_option is not None:
++ raise UnsafeOptionError(f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it.")
++ if not (option.startswith("--") or (options_are_kwargs and len(candidate) > 1)):
++ continue
+ for canonical, unsafe_option in canonical_unsafe_options.items():
+ if canonical.startswith(candidate):
+ raise UnsafeOptionError(
+ f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
+ )
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 72eb073196..76a21c670f 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -23,6 +23,8 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-44244_p2.patch \
file://CVE-2026-67326.patch \
file://CVE-2026-67323.patch \
+ file://CVE-2026-67325_p1.patch \
+ file://CVE-2026-67325_p2.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 04/27] python3-git: fix CVE-2026-67324
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (2 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 03/27] python3-git: Fix CVE-2026-67325 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 05/27] python3-git: fix CVE-2026-67322 Yogita Urade
` (23 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
Upstream commit [1] adds joined-short-option parsing, including
clustered forms such as -fuVALUE, while preserving safe attached
values. This behavior matches CVE-2026-67324's description [2] and
the upstream advisory [3]. The commit also adjusts clone-option
handling to preserve long-option abbreviation checks.
[1] https://github.com/gitpython-developers/GitPython/commit/56806080c1348749b07daa4a2024ce47b3cad285
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-67324
[3] https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-v396-v7q4-x2qj
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Refreshed patch context and removed trailing whitespace.
---
.../python/python3-git/CVE-2026-67324.patch | 94 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 95 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67324.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67324.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67324.patch
new file mode 100644
index 0000000000..73722344c1
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67324.patch
@@ -0,0 +1,94 @@
+From b09720b6f8311edac108392bd834e74918836c4f Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Sun, 12 Jul 2026 14:12:16 +0200
+Subject: [PATCH] fix: reject joined unsafe short options
+
+GitPython blocks options such as --upload-pack/-u and --config/-c
+because they can execute arbitrary commands unless unsafe options are
+explicitly allowed. Git also accepts a short option with its value
+joined to the same token, including after clusterable flags. Forms
+such as -uVALUE, -fuVALUE, -cVALUE, and -vcVALUE could therefore
+bypass an exact-token check.
+
+Parse single-dash option tokens sufficiently to recognize blocked
+short options while preserving safe attached values such as
+-oupstream. Also distinguish clone multi-option values from bare
+kwargs so positional values are not treated as long-option
+abbreviations.
+
+This completes the option-validation hardening for
+GHSA-2f96-g7mh-g2hx.
+
+CVE: CVE-2026-67324
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/56806080c1348749b07daa4a2024ce47b3cad285]
+
+Backport Changes:
+- Omitted test/test_clone.py, test/test_git.py, test/test_remote.py
+ because the current PyPI source archive does not include the test
+ suite and the python3-git recipe does not run it.
+
+Reviewed-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 56806080c1348749b07daa4a2024ce47b3cad285)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 40 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 4 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 523029fc..75495dc1 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -734,8 +734,21 @@
+ @classmethod
+ def check_unsafe_options(cls, options: List[str], unsafe_options: List[str]) -> None:
+- """Check for unsafe options.
+-
+- Some options that are passed to ``git <command>`` can be used to execute
+- arbitrary commands. These are blocked by default.
++ """Raise :class:`~git.exc.UnsafeOptionError` for blocked option spellings.
++
++ In addition to exact matches, this rejects abbreviated long options accepted
++ by Git (for example, ``--upl`` for ``--upload-pack``) and unsafe short options
++ whose values are joined to the same token, including after clusterable flags
++ (for example, ``-uVALUE`` and ``-fuVALUE``).
++
++ A list containing only bare names is treated as normalized keyword arguments,
++ so multi-character names such as ``upload_p`` are checked as long-option
++ abbreviations. If any item starts with ``-``, the list is treated as tokenized
++ command-line input: bare items can be option values and are not checked as
++ abbreviations. Thus ``["--origin", "upload"]`` is allowed. Single-dash options
++ use short-option parsing rather than broad prefix matching, preserving safe
++ attached values such as ``-oupstream`` and ``-bcurrent``.
++
++ Some options passed to ``git <command>`` can execute arbitrary commands and
++ are therefore blocked by default unless the caller explicitly allows them.
+ """
+ # Options can be of the form `foo`, `--foo`, `--foo bar`, or `--foo=bar`.
+@@ -747,4 +760,13 @@
+ # only.
+ canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
++ unsafe_short_options = {
++ canonical: option
++ for canonical, option in canonical_unsafe_options.items()
++ if option.startswith("-") and not option.startswith("--") and len(canonical) == 1
++ }
++ # These value-less Git flags can be clustered before another short option
++ # (for example, ``-fuVALUE``). Stop at any other character because it may
++ # begin an attached value, as ``o`` does in the safe option ``-oupstream``.
++ clusterable_short_options = frozenset("46flnqsv")
+ options_are_kwargs = all(not option.startswith("-") for option in options)
+ for option in options:
+@@ -757,3 +779,13 @@
+ raise UnsafeOptionError(f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it.")
++ option_token = option.split("=", 1)[0].split(None, 1)[0]
++ if option_token.startswith("-") and not option_token.startswith("--"):
++ for option_char in option_token[1:]:
++ unsafe_option = unsafe_short_options.get(option_char)
++ if unsafe_option is not None:
++ raise UnsafeOptionError(
++ f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
++ )
++ if option_char not in clusterable_short_options:
++ break
+ if not (option.startswith("--") or (options_are_kwargs and len(candidate) > 1)):
+ continue
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 76a21c670f..ca2efce37e 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -25,6 +25,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-67323.patch \
file://CVE-2026-67325_p1.patch \
file://CVE-2026-67325_p2.patch \
+ file://CVE-2026-67324.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 05/27] python3-git: fix CVE-2026-67322
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (3 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 04/27] python3-git: fix CVE-2026-67324 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 06/27] python3-git: fix CVE-2026-69097 Yogita Urade
` (22 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2
[2] https://security-tracker.debian.org/tracker/CVE-2026-67322
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Converted the caller-supplied URL to str before Git.polish_url(),
and converted the normalized clone URL to str before Git.check_unsafe_protocols().
Expanded Backport Changes to explain these GitPython 3.1.43 adaptations.
---
.../python/python3-git/CVE-2026-67322.patch | 171 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 172 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-67322.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-67322.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-67322.patch
new file mode 100644
index 0000000000..a78d2bd37a
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-67322.patch
@@ -0,0 +1,171 @@
+From 3ae11b59c9c4cf15f04397d58b8a90b621b6571b Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Wed, 15 Jul 2026 16:44:13 +0200
+Subject: [PATCH] fix: prevent environment expansion in clone URLs
+
+Repo.clone_from() expanded environment-variable references in caller-supplied
+URLs before passing them to git clone. This could expose process environment
+values to an untrusted remote and made protocol validation apply to a different
+value than Git received.
+
+Polish clone URLs without variable or home expansion on native and Cygwin
+Git, then apply unsafe-protocol validation to that exact normalized value.
+Preserve the literal URL when normalizing the stored origin after a successful
+clone, while retaining the existing Git.polish_url() default for callers
+that intentionally normalize local paths. Add regression coverage for
+POSIX and Windows variable syntax, Cygwin conversion, stored origins, and
+post-normalization protocol validation.
+
+Git baseline: git clone passes URL arguments through literally; t/t5601-clone.sh
+covers the accepted URL forms without shell-style environment expansion.
+
+Security: GHSA-rwj8-pgh3-r573.
+
+CVE: CVE-2026-67322
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2]
+
+Backport Changes:
+- Omitted test/test_clone.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does not
+ run it.
+- In Repo.clone_from(), stringify caller-supplied url before Git.polish_url()
+ because GitPython 3.1.43 accepts PathLike URLs but polish_url() uses string
+ operations. Stringify normalized clone_url before Git.check_unsafe_protocols()
+ because its regex expects str; validate the normalized value passed to Git.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 8ac5a30519b6f4af85398b9b9d7064ff4d452da2)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 19 ++++++++++++-------
+ git/repo/base.py | 7 ++++---
+ git/util.py | 15 +++++++++------
+ 3 files changed, 25 insertions(+), 16 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 75495dc1..58d219e3 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -670,29 +670,34 @@ Git.polish_url
+
+ @overload
+ @classmethod
+- def polish_url(cls, url: str, is_cygwin: Literal[False] = ...) -> str: ...
++ def polish_url(cls, url: str, is_cygwin: Literal[False] = ..., expand_vars: bool = ...) -> str: ...
+
+ @overload
+ @classmethod
+- def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> str: ...
++ def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None, expand_vars: bool = True) -> str: ...
+
+ @classmethod
+- def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> PathLike:
++ def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None, expand_vars: bool = True) -> PathLike:
+ """Remove any backslashes from URLs to be written in config files.
+
+ Windows might create config files containing paths with backslashes, but git
+ stops liking them as it will escape the backslashes. Hence we undo the escaping
+ just to be sure.
++
++ :param expand_vars:
++ Expand environment variables and an initial ``~``. Disable this for values
++ obtained from an untrusted source, such as remote URLs.
+ """
+ if is_cygwin is None:
+ is_cygwin = cls.is_cygwin()
+
+ if is_cygwin:
+- url = cygpath(url)
++ url = cygpath(url, expand_vars=expand_vars)
+ else:
+- url = os.path.expandvars(url)
+- if url.startswith("~"):
+- url = os.path.expanduser(url)
++ if expand_vars:
++ url = os.path.expandvars(url)
++ if url.startswith("~"):
++ url = os.path.expanduser(url)
+ url = url.replace("\\\\", "\\").replace("\\", "/")
+ return url
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 3380e0c5..d661f036 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -1408,8 +1408,9 @@ Repo.clone_from
+ if multi_options:
+ multi = shlex.split(" ".join(multi_options))
+
++ clone_url = Git.polish_url(str(url), expand_vars=False)
+ if not allow_unsafe_protocols:
+- Git.check_unsafe_protocols(str(url))
++ Git.check_unsafe_protocols(str(clone_url))
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+ options=Git._option_candidates([], kwargs),
+@@ -1421,7 +1422,7 @@ Repo.clone_from
+ proc = git.clone(
+ multi,
+ "--",
+- Git.polish_url(str(url)),
++ clone_url,
+ clone_path,
+ with_extended_output=True,
+ as_process=True,
+@@ -1461,7 +1462,7 @@ Repo.clone_from
+ # escape the backslashes. Hence we undo the escaping just to be sure.
+ if repo.remotes:
+ with repo.remotes[0].config_writer as writer:
+- writer.set_value("url", Git.polish_url(repo.remotes[0].url))
++ writer.set_value("url", Git.polish_url(repo.remotes[0].url, expand_vars=False))
+ # END handle remote repo
+ return repo
+
+diff --git a/git/util.py b/git/util.py
+index 27b239ab..9619937c 100644
+--- a/git/util.py
++++ b/git/util.py
+@@ -382,13 +382,13 @@ _cygexpath
+ return progs
+
+
+-def _cygexpath(drive: Optional[str], path: str) -> str:
++def _cygexpath(drive: Optional[str], path: str, expand_vars: bool = True) -> str:
+ if osp.isabs(path) and not drive:
+ # Invoked from `cygpath()` directly with `D:Apps\123`?
+ # It's an error, leave it alone just slashes)
+ p = path # convert to str if AnyPath given
+ else:
+- p = path and osp.normpath(osp.expandvars(osp.expanduser(path)))
++ p = path and osp.normpath(osp.expandvars(osp.expanduser(path)) if expand_vars else path)
+ if osp.isabs(p):
+ if drive:
+ # Confusing, maybe a remote system should expand vars.
+@@ -416,7 +416,7 @@ cygpath
+ )
+
+
+-def cygpath(path: str) -> str:
++def cygpath(path: str, expand_vars: bool = True) -> str:
+ """Use :meth:`git.cmd.Git.polish_url` instead, that works on any environment."""
+ path = str(path) # Ensure is str and not AnyPath.
+ # Fix to use Paths when 3.5 dropped. Or to be just str if only for URLs?
+@@ -424,12 +424,15 @@ cygpath
+ for regex, parser, recurse in _cygpath_parsers:
+ match = regex.match(path)
+ if match:
+- path = parser(*match.groups())
++ if parser is _cygexpath:
++ path = parser(*match.groups(), expand_vars=expand_vars)
++ else:
++ path = parser(*match.groups())
+ if recurse:
+- path = cygpath(path)
++ path = cygpath(path, expand_vars=expand_vars)
+ break
+ else:
+- path = _cygexpath(None, path)
++ path = _cygexpath(None, path, expand_vars=expand_vars)
+
+ return path
+
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index ca2efce37e..fafb9972ef 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -26,6 +26,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-67325_p1.patch \
file://CVE-2026-67325_p2.patch \
file://CVE-2026-67324.patch \
+ file://CVE-2026-67322.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 06/27] python3-git: fix CVE-2026-69097
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (4 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 05/27] python3-git: fix CVE-2026-67322 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 07/27] python3-git: fix CVE-2026-73625 Yogita Urade
` (21 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/1ed1b924f4e2d2ee7bab296df77b978af21853f1
[2] https://security-tracker.debian.org/tracker/CVE-2026-69097
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Restored the longer upstream commit explanation and Sebastian Thiel
co-author trailer, and corrected the abbreviated upstream/cherry-pick
hash to the full commit hash. The source fix is unchanged.
---
.../python/python3-git/CVE-2026-69097.patch | 60 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 61 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-69097.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-69097.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-69097.patch
new file mode 100644
index 0000000000..55b76ece40
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-69097.patch
@@ -0,0 +1,60 @@
+From 1ed1b924f4e2d2ee7bab296df77b978af21853f1 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Mon, 20 Jul 2026 14:13:22 +0200
+Subject: [PATCH] fix: validate config section delimiters
+
+GHSA-3rp5-jjmw-4wv2 identified that configuration section names could alter the
+structure of serialized config despite the existing control-character checks.
+
+Reject unquoted closing section delimiters across all writer entry points
+while preserving valid delimiters inside quoted subsections and the
+existing option-name behavior. Add regression coverage for unsafe plain and
+quoted-subsection-shaped names as well as a valid quoted subsection.
+
+Git baseline: a23bace963d508bd96983cc637131392d3face18. Git config parsing
+treats an unquoted closing bracket as the end of a basic section header, while
+its extended form permits brackets inside a quoted subsection and requires a
+final bracket after the closing quote.
+
+CVE: CVE-2026-69097
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/1ed1b924f4e2d2ee7bab296df77b978af21853f1]
+
+Backport Changes:
+- Omitted test/test_config.py because the current PyPI
+ source archive does not include the test suite and
+ the python3-git recipe does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 1ed1b924f4e2d2ee7bab296df77b978af21853f1)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/config.py | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/git/config.py b/git/config.py
+index 236de3a6..21f6e8aa 100644
+--- a/git/config.py
++++ b/git/config.py
+@@ -875,6 +875,22 @@ GitConfigParser._assure_config_name_safe
+ def _assure_config_name_safe(self, name: "cp._SectionName", label: str) -> None:
+ if isinstance(name, str) and UNSAFE_CONFIG_CHARS_RE.search(name):
+ raise ValueError("Git config %s names must not contain CR, LF, or NUL" % label)
++ if label == "section" and isinstance(name, str):
++ in_quotes = False
++ escaped = False
++ for index, char in enumerate(name):
++ if escaped:
++ escaped = False
++ elif in_quotes and char == "\\":
++ escaped = True
++ elif char == '"':
++ if not in_quotes and (index == 0 or name[index - 1] not in " \t"):
++ raise ValueError("Git config quoted subsection names must begin after whitespace")
++ in_quotes = not in_quotes
++ elif char == "]" and not in_quotes:
++ raise ValueError("Git config section names must not contain an unquoted closing bracket")
++ if in_quotes:
++ raise ValueError("Git config section names must not contain an unterminated quote")
+
+
+ @needs_values
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index fafb9972ef..781ec512cc 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -27,6 +27,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-67325_p2.patch \
file://CVE-2026-67324.patch \
file://CVE-2026-67322.patch \
+ file://CVE-2026-69097.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 07/27] python3-git: fix CVE-2026-73625
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (5 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 06/27] python3-git: fix CVE-2026-69097 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 08/27] python3-git: fix CVE-2026-73623 Yogita Urade
` (20 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453
[2] https://security-tracker.debian.org/tracker/CVE-2026-73625
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Refreshed the embedded hunk context and index hashes.
---
.../python/python3-git/CVE-2026-73625.patch | 59 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 60 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73625.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73625.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73625.patch
new file mode 100644
index 0000000000..8f2638017c
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73625.patch
@@ -0,0 +1,59 @@
+From ef95f1434023af72deabaf91e7154260d4625271 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Wed, 22 Jul 2026 04:39:00 +0200
+Subject: [PATCH] fix: validate split short-option values
+
+<!-- agent -->
+
+Single-character keyword arguments are transformed into an option token and
+a separate value token. The unsafe-option candidate builder only checked the
+keyword name, allowing an option-like value to bypass guards shared by clone,
+remote, revision, blame, and archive operations.
+
+Include dash-prefixed values only when short options are actually split,
+including sequence values, while preserving bare values and the non-splitting
+compatibility path.
+
+Git baseline a23bace9 defines clone -n and --upload-pack as distinct options,
+matching the argv boundary this validation now preserves.
+
+Refs GHSA-r9mr-m37c-5fr3.
+
+CVE: CVE-2026-73625
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453]
+
+Backport Changes:
+- Omitted test/test_git.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+ not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit e8d0fbf774d1f6baa3b481adfe48bd262e43b453)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index eb7bf055..2ce27290 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -804,11 +804,18 @@ Git._option_candidates
+ option for option in cls._unpack_args([arg for arg in args if arg is not None]) if option.startswith("-")
+ ]
+ if kwargs:
++ split_single_char_options = kwargs.get("split_single_char_options", True)
+ for key, value in kwargs.items():
+ values = value if isinstance(value, (list, tuple)) else (value,)
+ if any(value is True or (value is not False and value is not None) for value in values):
+ key = str(key)
+ options.append(f"-{key}" if len(key) == 1 else f"--{dashify(key)}")
++ if len(key) == 1 and split_single_char_options:
++ options.extend(
++ str(value)
++ for value in values
++ if value is not True and value not in (False, None) and str(value).startswith("-")
++ )
+ return options
+
+ class AutoInterrupt:
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 781ec512cc..551b47fc39 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -28,6 +28,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-67324.patch \
file://CVE-2026-67322.patch \
file://CVE-2026-69097.patch \
+ file://CVE-2026-73625.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 08/27] python3-git: fix CVE-2026-73623
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (6 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 07/27] python3-git: fix CVE-2026-73625 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 09/27] python3-git: fix CVE-2026-73624 Yogita Urade
` (19 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97
[2] https://security-tracker.debian.org/tracker/CVE-2026-73623
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Updated the Backport Changes line wrapping and hunk context.
---
.../python/python3-git/CVE-2026-73623.patch | 53 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 54 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73623.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73623.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73623.patch
new file mode 100644
index 0000000000..7cb48e1511
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73623.patch
@@ -0,0 +1,53 @@
+From 3621c3099fef859e91f9f960707902018a370978 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Wed, 22 Jul 2026 04:43:26 +0200
+Subject: [PATCH] fix: reject unsafe clone templates
+
+<!-- agent -->
+
+Treat git clone --template as unsafe because caller-controlled
+templates can install hooks that execute during clone.
+
+Add regression coverage for both direct option and keyword forms.
+
+References GHSA-6p8h-3wgx-97gf.
+Validated against Git baseline a23bace9.
+
+CVE: CVE-2026-73623
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97]
+
+Backport Changes:
+- Omitted test/test_clone.py because the current PyPI
+ source archive does not include the test suite and
+ the python3-git recipe does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit ffcb5359e87619f4fe4a70a4aff5f08c5580ba97)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/repo/base.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index d661f036..2776c19e 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -148,6 +148,8 @@ Repo.unsafe_git_clone_options
+ # Can override configuration variables that execute arbitrary commands:
+ "--config",
+ "-c",
++ # Can install hooks that execute during clone:
++ "--template",
+ ]
+ """Options to :manpage:`git-clone(1)` that allow arbitrary commands to be executed.
+
+@@ -158,6 +160,9 @@ Repo.unsafe_git_clone_options
+ The ``--config``/``-c`` option allows users to override configuration variables like
+ ``protocol.allow`` and ``core.gitProxy`` to execute arbitrary commands:
+ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---configltkeygtltvaluegt
++
++ The ``--template`` option can install hooks that execute during clone:
++ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---templatetemplate-directory
+ """
+ unsafe_git_archive_options = [
+ # Allows arbitrary command execution through the remote git-upload-archive command.
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 551b47fc39..d996d4f9f5 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -29,6 +29,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-67322.patch \
file://CVE-2026-69097.patch \
file://CVE-2026-73625.patch \
+ file://CVE-2026-73623.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 09/27] python3-git: fix CVE-2026-73624
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (7 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 08/27] python3-git: fix CVE-2026-73623 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 10/27] python3-git: fix CVE-2026-73622 Yogita Urade
` (18 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6
[2] https://security-tracker.debian.org/tracker/CVE-2026-73624
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Cleaned whitespace in the Backport Changes note.
---
.../python/python3-git/CVE-2026-73624.patch | 139 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 140 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch
new file mode 100644
index 0000000000..9db29de43d
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch
@@ -0,0 +1,139 @@
+From 285d6227b9132ed6bab3cc28665e87b2285757ae Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Wed, 22 Jul 2026 04:46:13 +0200
+Subject: [PATCH] fix: guard diff output options
+
+<!-- agent -->
+
+Reject unsafe diff options before revision parsing or Git invocation so
+callers cannot write command output to arbitrary filesystem paths.
+
+Cover commit and index diffs, including option-like revisions, and
+preserve an explicit allow_unsafe_options escape hatch.
+
+References GHSA-fjr4-x663-mwxc.
+Validated against Git baseline a23bace9.
+
+CVE: CVE-2026-73624
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6]
+
+Backport Changes:
+- Omitted test/test_diff.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+ not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 1d51b891d7f236044a6aa17498ec682b63dad6e6)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/diff.py | 14 ++++++++++++--
+ git/index/base.py | 18 ++++++++++++++++--
+ 2 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/git/diff.py b/git/diff.py
+index f89b12d9..9a1f107b 100644
+--- a/git/diff.py
++++ b/git/diff.py
+@@ -9,7 +9,7 @@ import enum
+ import re
+ import warnings
+
+-from git.cmd import handle_process_output
++from git.cmd import Git, handle_process_output
+ from git.compat import defenc
+ from git.objects.blob import Blob
+ from git.objects.util import mode_str_to_int
+@@ -34,7 +34,6 @@ from git.types import Literal, PathLike
+ if TYPE_CHECKING:
+ from subprocess import Popen
+
+- from git.cmd import Git
+ from git.objects.base import IndexObject
+ from git.objects.commit import Commit
+ from git.objects.tree import Tree
+@@ -186,6 +185,7 @@ class Diffable:
+ other: Union[DiffConstants, "Tree", "Commit", str, None] = INDEX,
+ paths: Union[PathLike, List[PathLike], Tuple[PathLike, ...], None] = None,
+ create_patch: bool = False,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> "DiffIndex":
+ """Create diffs between two items being trees, trees and index or an index and
+@@ -215,6 +215,10 @@ class Diffable:
+ applied makes the self to other. Patches are somewhat costly as blobs have
+ to be read and diffed.
+
++ :param allow_unsafe_options:
++ If ``True``, allow options such as ``--output`` that can write to arbitrary
++ filesystem paths.
++
+ :param kwargs:
+ Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to
+ swap both sides of the diff.
+@@ -227,6 +231,12 @@ class Diffable:
+ an instance of :class:`~git.objects.tree.Tree` or
+ :class:`~git.objects.commit.Commit`, or a git command error will occur.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([other], kwargs),
++ unsafe_options=self.repo.unsafe_git_revision_options,
++ )
++
+ args: List[Union[PathLike, Diffable]] = []
+ args.append("--abbrev=40") # We need full shas.
+ args.append("--full-index") # Get full index paths, not only filenames.
+diff --git a/git/index/base.py b/git/index/base.py
+index b8161ea5..dfe7e0dc 100644
+--- a/git/index/base.py
++++ b/git/index/base.py
+@@ -23,6 +23,7 @@ from gitdb.base import IStream
+ from gitdb.db import MemoryDB
+
+ from git.compat import defenc, force_bytes
++from git.cmd import Git
+ import git.diff as git_diff
+ from git.exc import CheckoutError, GitCommandError, GitError, InvalidGitRepositoryError
+ from git.objects import Blob, Commit, Object, Submodule, Tree
+@@ -1477,6 +1478,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+ ] = git_diff.INDEX,
+ paths: Union[PathLike, List[PathLike], Tuple[PathLike, ...], None] = None,
+ create_patch: bool = False,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> git_diff.DiffIndex:
+ """Diff this index against the working copy or a :class:`~git.objects.tree.Tree`
+@@ -1489,6 +1491,12 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+ Will only work with indices that represent the default git index as they
+ have not been initialized with a stream.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([other], kwargs),
++ unsafe_options=self.repo.unsafe_git_revision_options,
++ )
++
+ # Only run if we are the default repository index.
+ if self._file_path != self._index_path():
+ raise AssertionError("Cannot call %r on indices that do not represent the default git index" % self.diff())
+@@ -1507,7 +1515,13 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+ # Invert the existing R flag.
+ cur_val = kwargs.get("R", False)
+ kwargs["R"] = not cur_val
+- return other.diff(self.INDEX, paths, create_patch, **kwargs)
++ return other.diff(
++ self.INDEX,
++ paths,
++ create_patch,
++ allow_unsafe_options=allow_unsafe_options,
++ **kwargs,
++ )
+ # END diff against other item handling
+
+ # If other is not None here, something is wrong.
+@@ -1515,4 +1529,4 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+ raise ValueError("other must be None, Diffable.INDEX, a Tree or Commit, was %r" % other)
+
+ # Diff against working copy - can be handled by superclass natively.
+- return super().diff(other, paths, create_patch, **kwargs)
++ return super().diff(other, paths, create_patch, allow_unsafe_options=allow_unsafe_options, **kwargs)
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index d996d4f9f5..847bdfeab2 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -30,6 +30,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-69097.patch \
file://CVE-2026-73625.patch \
file://CVE-2026-73623.patch \
+ file://CVE-2026-73624.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 10/27] python3-git: fix CVE-2026-73622
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (8 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 09/27] python3-git: fix CVE-2026-73624 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 11/27] python3-git: fix CVE-2026-73621 Yogita Urade
` (17 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162
[2] https://security-tracker.debian.org/tracker/CVE-2026-73622
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Cleaned whitespace in the Backport Changes note.
---
.../python/python3-git/CVE-2026-73622.patch | 60 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 61 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch
new file mode 100644
index 0000000000..a9a31c4f4d
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch
@@ -0,0 +1,60 @@
+From 5043b75a697c0f9110d2014234831dd1bc568a60 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Wed, 22 Jul 2026 15:42:44 +0200
+Subject: [PATCH] fix: prevent environment expansion in remote URLs
+
+Remote and submodule creation expanded environment-variable references in
+caller-supplied URLs before storing them in Git configuration. This could
+expose process environment values through a later network request or a tracked
+.gitmodules file.
+
+Preserve variables literally in the remaining untrusted URL callers while
+retaining Git.polish_url() expansion for intentional local-path normalization.
+Add regression tests covering remote configuration and submodule configuration.
+
+Git baseline: git remote add and git submodule add accept URL arguments
+literally; Git does not perform shell-style environment expansion on those
+arguments.
+
+CVE: CVE-2026-73622
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162]
+
+Backport Changes:
+- Omitted test/test_remote.py, test/test_submodule.py because the current
+ PyPI source archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 863417457a0633db7ea5aed4fd01e0b291a41162)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 2 +-
+ git/remote.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index fa60bcda..43e0ec9a 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -601,7 +601,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ # END verify url
+
+ ## See #525 for ensuring git URLs in config-files are valid under Windows.
+- url = Git.polish_url(url)
++ url = Git.polish_url(url, expand_vars=False)
+
+ # It's important to add the URL to the parent config, to let `git submodule` know.
+ # Otherwise there is a '-' character in front of the submodule listing:
+diff --git a/git/remote.py b/git/remote.py
+index cafa1f84..dd892fdc 100644
+--- a/git/remote.py
++++ b/git/remote.py
+@@ -805,7 +805,7 @@ class Remote(LazyMixin, IterableObj):
+ """
+ scmd = "add"
+ kwargs["insert_kwargs_after"] = scmd
+- url = Git.polish_url(url)
++ url = Git.polish_url(url, expand_vars=False)
+ if not allow_unsafe_protocols:
+ Git.check_unsafe_protocols(url)
+ repo.git.remote(scmd, "--", name, url, **kwargs)
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 847bdfeab2..6456031620 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -31,6 +31,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73625.patch \
file://CVE-2026-73623.patch \
file://CVE-2026-73624.patch \
+ file://CVE-2026-73622.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 11/27] python3-git: fix CVE-2026-73621
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (9 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 10/27] python3-git: fix CVE-2026-73622 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 12/27] python3-git: fix CVE-2026-73620 Yogita Urade
` (16 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/38553b6fddc7f6a667cdb45a6762343a08fc72b2
[2] https://security-tracker.debian.org/tracker/CVE-2026-73621
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Cleaned whitespace in the Backport Changes note.
---
.../python/python3-git/CVE-2026-73621.patch | 72 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 73 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch
new file mode 100644
index 0000000000..49cdb257d0
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch
@@ -0,0 +1,72 @@
+From 3186ded297a9818f887c3de47fc2f0aba6a8b298 Mon Sep 17 00:00:00 2001
+From: Sebastian Thiel <sebastian.thiel@icloud.com>
+Date: Sat, 25 Jul 2026 06:27:01 +0200
+Subject: [PATCH] fix: reject unsafe output options in Commit.count
+
+<!-- agent -->
+
+Commit.count forwards keyword arguments to git rev-list but did not apply the
+unsafe-option validation used by the sibling revision APIs.
+
+Validate forwarded options with the existing Git.check_unsafe_options helper
+and retain the explicit allow_unsafe_options escape hatch. This covers
+GHSA-p538-c434-8v24 without adding another option parser.
+
+Git baseline: git.git a23bace963 defines --output as a shared diff option
+consumed by setup_revisions; t/t6000-rev-list-misc.sh exercises that option
+with rev-list.
+
+CVE: CVE-2026-73621
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/38553b6fddc7f6a667cdb45a6762343a08fc72b2]
+
+Backport Changes:
+- Omitted test/test_commit.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 38553b6fddc7f6a667cdb45a6762343a08fc72b2)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/commit.py | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/git/objects/commit.py b/git/objects/commit.py
+index cc85e7dd..549e12c7 100644
+--- a/git/objects/commit.py
++++ b/git/objects/commit.py
+@@ -269,13 +269,21 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
+ else:
+ return self.message.split(b"\n", 1)[0]
+
+- def count(self, paths: Union[PathLike, Sequence[PathLike]] = "", **kwargs: Any) -> int:
++ def count(
++ self,
++ paths: Union[PathLike, Sequence[PathLike]] = "",
++ allow_unsafe_options: bool = False,
++ **kwargs: Any,
++ ) -> int:
+ """Count the number of commits reachable from this commit.
+
+ :param paths:
+ An optional path or a list of paths restricting the return value to commits
+ actually containing the paths.
+
++ :param allow_unsafe_options:
++ Allow unsafe options, like ``--output``.
++
+ :param kwargs:
+ Additional options to be passed to :manpage:`git-rev-list(1)`. They must not
+ alter the output style of the command, or parsing will yield incorrect
+@@ -284,6 +292,11 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
+ :return:
+ An int defining the number of reachable commits
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs), unsafe_options=self.unsafe_git_rev_options
++ )
++
+ # Yes, it makes a difference whether empty paths are given or not in our case as
+ # the empty paths version will ignore merge commits for some reason.
+ if paths:
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 6456031620..f712a0e699 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -32,6 +32,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73623.patch \
file://CVE-2026-73624.patch \
file://CVE-2026-73622.patch \
+ file://CVE-2026-73621.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 12/27] python3-git: fix CVE-2026-73620
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (10 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 11/27] python3-git: fix CVE-2026-73621 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 13/27] python3-git: fix CVE-2026-73619 Yogita Urade
` (15 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/3af0c2516c5e18c829da30338614688f6b69b49c
[2] https://security-tracker.debian.org/tracker/CVE-2026-73620
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Refreshed the embedded hunk context and index hashes.
---
.../python/python3-git/CVE-2026-73620.patch | 130 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 131 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73620.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73620.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73620.patch
new file mode 100644
index 0000000000..7901c8d28d
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73620.patch
@@ -0,0 +1,130 @@
+From cc80ea13457773907fa7843e274dca8dc7d196a5 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Sun, 26 Jul 2026 05:54:27 +0200
+Subject: [PATCH] Block unsafe checkout-index and tag file options
+
+GHSA-3f7w-8rr8-f37f reports that caller-controlled options forwarded by
+IndexFile.checkout() and TagReference.create() can make Git write to or read
+from arbitrary filesystem paths.
+
+Add regression coverage proving the unsafe options are rejected by default while
+preserving the explicit allow_unsafe_options escape hatch. Reuse GitPython's
+existing option candidate normalization and unsafe-option guard at both public
+API boundaries.
+
+Git baseline: a23bace963d508bd96983cc637131392d3face18.
+Documentation/git-checkout-index.adoc defines --prefix as prepending an output
+path, and Documentation/git-tag.adoc defines -F/--file as reading a tag message
+from a file.
+
+CVE: CVE-2026-73620
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/3af0c2516c5e18c829da30338614688f6b69b49c]
+
+Backport Changes:
+- Omitted test/test_index.py, test/test_refs.py because the current PyPI
+ source archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 3af0c2516c5e18c829da30338614688f6b69b49c)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/index/base.py | 12 ++++++++++++
+ git/refs/tag.py | 13 +++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/git/index/base.py b/git/index/base.py
+index dfe7e0dc..90d4c16f 100644
+--- a/git/index/base.py
++++ b/git/index/base.py
+@@ -129,6 +129,8 @@ IndexFile
+ Make sure you use :meth:`index.write() <write>` once you are done manipulating the
+ index directly before operating on it using the git command.
+ """
++ unsafe_git_checkout_index_options = ["--prefix"]
++
+
+ __slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
+
+@@ -1199,6 +1201,7 @@ IndexFile.checkout
+ paths: Union[None, Iterable[PathLike]] = None,
+ force: bool = False,
+ fprogress: Callable = lambda *args: None,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> Union[None, Iterator[PathLike], Sequence[PathLike]]:
+ """Check out the given paths or all files from the version known to the index
+@@ -1224,6 +1227,9 @@ IndexFile.checkout
+ The provided progress information will contain ``None`` as path and item if
+ no explicit paths are given. Otherwise progress information will be send
+ prior and after a file has been checked out.
++ :param allow_unsafe_options:
++ Allow unsafe options, such as ``--prefix``.
++
+
+ :param kwargs:
+ Additional arguments to be passed to :manpage:`git-checkout-index(1)`.
+@@ -1248,6 +1254,12 @@ IndexFile.checkout
+ i.e. if you want :manpage:`git-checkout(1)`-like behaviour, use
+ ``head.checkout`` instead of ``index.checkout``.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=self.unsafe_git_checkout_index_options,
++ )
++
+ args = ["--index"]
+ if force:
+ args.append("--force")
+diff --git a/git/refs/tag.py b/git/refs/tag.py
+index 1e38663a..487eaa14 100644
+--- a/git/refs/tag.py
++++ b/git/refs/tag.py
+@@ -14,6 +14,7 @@ module imports
+
+ # typing ------------------------------------------------------------------
+
++from git.cmd import Git
+ from typing import Any, TYPE_CHECKING, Type, Union
+
+ from git.types import AnyGitObject, PathLike
+@@ -40,6 +41,8 @@ TagReference
+ print(tagref.tag.message)
+ """
+
++ unsafe_git_tag_options = ["--file", "-F"]
++
+ __slots__ = ()
+
+ _common_default = "tags"
+@@ -92,6 +95,7 @@ TagReference.create
+ reference: Union[str, "SymbolicReference"] = "HEAD",
+ logmsg: Union[str, None] = None,
+ force: bool = False,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> "TagReference":
+ """Create a new tag reference.
+@@ -121,12 +125,21 @@ TagReference.create
+ :param force:
+ If ``True``, force creation of a tag even though that tag already exists.
+
++ :param allow_unsafe_options:
++ Allow unsafe options, such as ``--file``.
++
+ :param kwargs:
+ Additional keyword arguments to be passed to :manpage:`git-tag(1)`.
+
+ :return:
+ A new :class:`TagReference`.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=cls.unsafe_git_tag_options,
++ )
++
+ if "ref" in kwargs and kwargs["ref"]:
+ reference = kwargs["ref"]
+
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index f712a0e699..d47ce73d72 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -33,6 +33,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73624.patch \
file://CVE-2026-73622.patch \
file://CVE-2026-73621.patch \
+ file://CVE-2026-73620.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 13/27] python3-git: fix CVE-2026-73619
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (11 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 12/27] python3-git: fix CVE-2026-73620 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 14/27] python3-git: fix CVE-2026-76221 Yogita Urade
` (14 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [3],
using the commit shown in [1] and [2].
[1] https://github.com/gitpython-developers/GitPython/commit/7a4f5dcb7bf3cbcbf6e438017efcdfe0bc0d36ca
[2] https://github.com/gitpython-developers/GitPython/commit/52199b39ce02c6e8f9fb49e95628b59deebf44c0
[3] https://security-tracker.debian.org/tracker/CVE-2026-73619
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Split the patch into p1 and p2 and updated SRC_URI to apply them in
order. P1 adds the unsafe clone and archive options; p2 clarifies
the --bundle-uri risk and its effect on Git’s URI access.
---
.../python3-git/CVE-2026-73619_p1.patch | 58 +++++++++++++++++++
.../python3-git/CVE-2026-73619_p2.patch | 43 ++++++++++++++
.../python/python3-git_3.1.43.bb | 2 +
3 files changed, 103 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-73619_p2.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch
new file mode 100644
index 0000000000..0f8541216c
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch
@@ -0,0 +1,58 @@
+From 91f2b27eb8976ef5c663f1a0ea8180e2cf28cb10 Mon Sep 17 00:00:00 2001
+From: "GPT 5.6" <codex@openai.com>
+Date: Sun, 26 Jul 2026 06:00:59 +0200
+Subject: [PATCH] Block unsafe archive additions and bundle URI
+
+GHSA-539m-9xh6-q6rr reports incomplete unsafe option lists for archive inputs
+and clone bundle URLs. Caller-controlled archive additions can expose or inject
+filesystem content, while clone --bundle-uri can dereference an additional
+caller-controlled URL.
+
+Extend the existing archive denylist with --add-file and --add-virtual-file,
+and the clone denylist with --bundle-uri. Regression coverage exercises archive
+kwargs plus both clone multi-option and keyword paths.
+
+Git baseline: a23bace963d508bd96983cc637131392d3face18.
+Documentation/git-archive.adoc defines --add-file/--add-virtual-file, and
+Documentation/git-clone.adoc defines --bundle-uri as fetching from the supplied
+URI.
+
+CVE: CVE-2026-73619
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/7a4f5dcb7bf3cbcbf6e438017efcdfe0bc0d36ca]
+
+Backport Changes:
+- Omitted test/test_clone.py, test/test_repo.py because the current PyPI
+ source archive does not include the test suite and the python3-git recipe
+ does not run it.
+
+Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
+(cherry picked from commit 7a4f5dcb7bf3cbcbf6e438017efcdfe0bc0d36ca)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/repo/base.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 2776c19e..4b783586 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -150,6 +150,8 @@ class Repo:
+ "-c",
+ # Can install hooks that execute during clone:
+ "--template",
++ # Fetches from a caller-controlled URL:
++ "--bundle-uri",
+ ]
+ """Options to :manpage:`git-clone(1)` that allow arbitrary commands to be executed.
+
+@@ -171,6 +173,10 @@ class Repo:
+ # Writes output to a caller-controlled filesystem path.
+ "--output",
+ "-o",
++ # Reads from a caller-controlled filesystem path:
++ "--add-file",
++ # Injects a caller-controlled path and contents:
++ "--add-virtual-file",
+ ]
+
+ unsafe_git_revision_options = [
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p2.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p2.patch
new file mode 100644
index 0000000000..70d28217ec
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-73619_p2.patch
@@ -0,0 +1,43 @@
+From 52199b39ce02c6e8f9fb49e95628b59deebf44c0 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Sun, 26 Jul 2026 08:56:06 +0200
+Subject: [PATCH] address review comments
+
+CVE: CVE-2026-73619
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/52199b39ce02c6e8f9fb49e95628b59deebf44c0]
+
+(cherry picked from commit 52199b39ce02c6e8f9fb49e95628b59deebf44c0)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/repo/base.py | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 93d1725..6594101 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -150,10 +150,10 @@ class Repo:
+ "-c",
+ # Can install hooks that execute during clone:
+ "--template",
+- # Fetches from a caller-controlled URL:
++ # Fetches from an additional caller-controlled URI:
+ "--bundle-uri",
+ ]
+- """Options to :manpage:`git-clone(1)` that allow arbitrary commands to be executed.
++ """Options to :manpage:`git-clone(1)` that permit unsafe command execution or I/O.
+
+ The ``--upload-pack``/``-u`` option allows users to execute arbitrary commands
+ directly:
+@@ -165,6 +165,11 @@ class Repo:
+
+ The ``--template`` option can install hooks that execute during clone:
+ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---templatetemplate-directory
++
++ The ``--bundle-uri`` option fetches from an additional URI before fetching from the
++ clone URL. An untrusted value can therefore make Git access local files or
++ unintended network resources:
++ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---bundle-uriuri
+ """
+ unsafe_git_archive_options = [
+ # Allows arbitrary command execution through the remote git-upload-archive command.
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index d47ce73d72..f0ffb70df8 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -34,6 +34,8 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73622.patch \
file://CVE-2026-73621.patch \
file://CVE-2026-73620.patch \
+ file://CVE-2026-73619_p1.patch \
+ file://CVE-2026-73619_p2.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 14/27] python3-git: fix CVE-2026-76221
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (12 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 13/27] python3-git: fix CVE-2026-73619 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 15/27] python3-git: fix CVE-2026-76220 Yogita Urade
` (13 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/a495ccd3b547ccd60b2187215823b72a9c0188bf
[2] https://security-tracker.debian.org/tracker/CVE-2026-76221
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Expanded the embedded commit rationale to describe unsafe option-name
serialization and the validator’s coverage. Added Assisted-by and
Co-authored-by trailers. The source validator remains the same;
the embedded diff removes an extra blank line.
---
.../python/python3-git/CVE-2026-76221.patch | 59 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 60 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76221.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76221.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76221.patch
new file mode 100644
index 0000000000..80198bde6c
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76221.patch
@@ -0,0 +1,59 @@
+From 46f9c03ed10d25146293003791476955f8b26a73 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Sun, 2 Aug 2026 08:57:12 +0000
+Subject: [PATCH] Reject syntax-bearing git config option names
+
+<!-- agent -->
+GHSA-jm78-9fvv-mhgr reports that config option names containing Git
+syntax can be serialized as unintended directives. A regression test showed
+that set, set_value, and add_value accepted delimiter, comment, bracket, and
+whitespace characters in option names.
+
+Restrict written option names to GitPython's established safe character set of
+letters, digits, hyphens, underscores, and dots. This blocks characters that
+can change config syntax while preserving option names historically supported
+by the writer and SectionConstraint.
+
+A broader audit confirmed that every public option-creating config API and
+SectionConstraint delegate reaches this validator; no separate config writer
+sink was found. The behavior was checked against Git cf5497b14, and the full
+config test module plus dotted-option regression pass.
+
+CVE: CVE-2026-76221
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/a495ccd3b547ccd60b2187215823b72a9c0188bf]
+
+Backport Changes:
+- Omitted test/test_config.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit a495ccd3b547ccd60b2187215823b72a9c0188bf)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/config.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/git/config.py b/git/config.py
+index cbfc7ebd..de1b9572 100644
+--- a/git/config.py
++++ b/git/config.py
+@@ -74,6 +74,8 @@ UNSAFE_CONFIG_CHARS_RE
+ UNSAFE_CONFIG_CHARS_RE = re.compile(r"[\r\n\x00]")
+ """Characters that cannot be safely written in config names or values."""
+
++VALID_CONFIG_OPTION_NAME_RE = re.compile(r"^[A-Za-z0-9_.-]+$")
++"""Pattern for option names that can be written without changing config syntax."""
+
+
+ class MetaParserBuilder(abc.ABCMeta): # noqa: B024
+@@ -875,6 +877,8 @@ GitConfigParser._assure_config_name_safe
+ def _assure_config_name_safe(self, name: "cp._SectionName", label: str) -> None:
+ if isinstance(name, str) and UNSAFE_CONFIG_CHARS_RE.search(name):
+ raise ValueError("Git config %s names must not contain CR, LF, or NUL" % label)
++ if label == "option" and isinstance(name, str) and not VALID_CONFIG_OPTION_NAME_RE.fullmatch(name):
++ raise ValueError("Git config option names may contain only letters, digits, '-', '_', or '.'")
+ if label == "section" and isinstance(name, str):
+ in_quotes = False
+ escaped = False
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index f0ffb70df8..42d251a2df 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -36,6 +36,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73620.patch \
file://CVE-2026-73619_p1.patch \
file://CVE-2026-73619_p2.patch \
+ file://CVE-2026-76221.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 15/27] python3-git: fix CVE-2026-76220
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (13 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 14/27] python3-git: fix CVE-2026-76221 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 16/27] python3-git: fix CVE-2026-76219 Yogita Urade
` (12 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/96a888f4d782cb2f80452148e48e60ce4af6d541
[2] https://security-tracker.debian.org/tracker/CVE-2026-76220
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Removed the stale cherry-pick and Signed-off-by trailers and refreshed
the embedded hunk context.
---
.../python/python3-git/CVE-2026-76220.patch | 65 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 66 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76220.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76220.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76220.patch
new file mode 100644
index 0000000000..1a42e7cf04
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76220.patch
@@ -0,0 +1,65 @@
+From 8f29b889df8dff1c1227dafabac0f49306d45838 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Sun, 2 Aug 2026 08:59:57 +0000
+Subject: [PATCH] Check joined short-option values before Git execution
+
+<!-- agent -->
+GHSA-wvpp-8hx9-p66j reports that unsafe-option checks omitted the value
+joined to a one-character option when split_single_char_options was false. A
+regression test reproduced the mismatch: GitPython checked only -n even though
+it emitted a joined -nVALUE token that Git parses as clustered short options.
+
+Collect the exact joined token for unsplit one-character keyword arguments so
+the existing clustered-short-option validation sees every option character.
+The split form and long-option behavior remain unchanged.
+
+A broader audit confirmed that all guarded keyword-forwarding APIs use
+_option_candidates, including clone, ls-remote, fetch, pull, push, archive,
+revision, diff, checkout-index, and tag paths. Git cf5497b14 confirms repeated
+short-option parsing within a joined token. Focused candidate and unsafe-option
+tests pass.
+
+CVE: CVE-2026-76220
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/96a888f4d782cb2f80452148e48e60ce4af6d541]
+
+Backport Changes:
+- Omitted test/test_git.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+ not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 96a888f4d782cb2f80452148e48e60ce4af6d541)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 2ce27290..de68fa34 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -809,13 +809,21 @@ Git._option_candidates
+ values = value if isinstance(value, (list, tuple)) else (value,)
+ if any(value is True or (value is not False and value is not None) for value in values):
+ key = str(key)
+- options.append(f"-{key}" if len(key) == 1 else f"--{dashify(key)}")
+- if len(key) == 1 and split_single_char_options:
++ if len(key) != 1:
++ options.append(f"--{dashify(key)}")
++ elif split_single_char_options:
++ options.append(f"-{key}")
+ options.extend(
+ str(value)
+ for value in values
+ if value is not True and value not in (False, None) and str(value).startswith("-")
+ )
++ else:
++ options.extend(
++ f"-{key}" if value is True else f"-{key}{value}"
++ for value in values
++ if value is True or (value is not False and value is not None)
++ )
+ return options
+
+ class AutoInterrupt:
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 42d251a2df..4a3d516244 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -37,6 +37,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73619_p1.patch \
file://CVE-2026-73619_p2.patch \
file://CVE-2026-76221.patch \
+ file://CVE-2026-76220.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 16/27] python3-git: fix CVE-2026-76219
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (14 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 15/27] python3-git: fix CVE-2026-76220 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 17/27] python3-git: fix CVE-2026-76218 Yogita Urade
` (11 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/9b5dcaf85da5946dbf69dcd53f9edba08f760b32
[2] https://security-tracker.debian.org/tracker/CVE-2026-76219
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Removed the stale cherry-pick and Signed-off-by trailers and refreshed
the embedded hunk context.
---
.../python/python3-git/CVE-2026-76219.patch | 153 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 154 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76219.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76219.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76219.patch
new file mode 100644
index 0000000000..719e80b4e0
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76219.patch
@@ -0,0 +1,153 @@
+From dbf247f0779367b555b55d54941ead00e999eee6 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Sun, 2 Aug 2026 09:06:40 +0000
+Subject: [PATCH] Guard read-tree index output paths
+
+<!-- agent -->
+GHSA-4gmw-gg2m-w46p reports that caller-controlled treeish arguments could
+be parsed by git read-tree as --index-output and select an arbitrary output
+path. A regression test showed that from_tree reached Git instead of raising
+UnsafeOptionError; the same unchecked path was reachable through reset and
+both merge_tree treeish positions.
+
+Add the project-standard unsafe-option guard and explicit opt-out to
+from_tree, merge_tree, and reset. Check positional and keyword candidates so
+abbreviations and alternate forwarding forms are covered before read-tree
+runs.
+
+A broader audit found only two read-tree sinks in the codebase; both are now
+guarded, and reset delegates to the guarded from_tree path. The only remaining
+index-output use is GitPython's controlled temporary index. Git cf5497b14
+confirms read-tree parses this path-taking option before tree arguments.
+Focused index tests and Ruff checks pass.
+
+CVE: CVE-2026-76219
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/9b5dcaf85da5946dbf69dcd53f9edba08f760b32]
+
+Backport Changes:
+- Omitted test/test_index.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does not
+ run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 9b5dcaf85da5946dbf69dcd53f9edba08f760b32)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/index/base.py | 40 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 37 insertions(+), 3 deletions(-)
+
+diff --git a/git/index/base.py b/git/index/base.py
+index e10bfd68..fb1acb1a 100644
+--- a/git/index/base.py
++++ b/git/index/base.py
+@@ -130,6 +130,7 @@ class IndexFile:
+ index directly before operating on it using the git command.
+ """
+ unsafe_git_checkout_index_options = ["--prefix"]
++ unsafe_git_read_tree_options = ["--index-output"]
+
+
+ __slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
+@@ -256,7 +257,12 @@ def merge_tree
+
+ @post_clear_cache
+ @default_index
+- def merge_tree(self, rhs: Treeish, base: Union[None, Treeish] = None) -> "IndexFile":
++ def merge_tree(
++ self,
++ rhs: Treeish,
++ base: Union[None, Treeish] = None,
++ allow_unsafe_options: bool = False,
++ ) -> "IndexFile":
+ """Merge the given `rhs` treeish into the current index, possibly taking
+ a common base treeish into account.
+
+@@ -270,6 +276,9 @@ def merge_tree
+ Optional treeish reference pointing to the common base of `rhs` and this
+ index which equals lhs.
+
++ :param allow_unsafe_options:
++ Allow options that may write to arbitrary paths.
++
+ :return:
+ self (containing the merge and possibly unmerged entries in case of
+ conflicts)
+@@ -280,6 +289,12 @@ def merge_tree
+ yourself, you have to commit the changed index (or make a valid tree from
+ it) and retry with a three-way :meth:`index.from_tree <from_tree>` call.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([base, rhs]),
++ unsafe_options=self.unsafe_git_read_tree_options,
++ )
++
+ # -i : ignore working tree status
+ # --aggressive : handle more merge cases
+ # -m : do an actual merge
+@@ -324,7 +339,13 @@ def from_tree
+ return inst
+
+ @classmethod
+- def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile":
++ def from_tree(
++ cls,
++ repo: "Repo",
++ *treeish: Treeish,
++ allow_unsafe_options: bool = False,
++ **kwargs: Any,
++ ) -> "IndexFile":
+ R"""Merge the given treeish revisions into a new index which is returned.
+ The original index will remain unaltered.
+
+@@ -348,6 +369,9 @@ def from_tree
+ :param kwargs:
+ Additional arguments passed to :manpage:`git-read-tree(1)`.
+
++ :param allow_unsafe_options:
++ Allow options that may write to arbitrary paths.
++
+ :return:
+ New :class:`IndexFile` instance. It will point to a temporary index location
+ which does not exist anymore. If you intend to write such a merged Index,
+@@ -365,6 +389,12 @@ def from_tree
+ if len(treeish) == 0 or len(treeish) > 3:
+ raise ValueError("Please specify between 1 and 3 treeish, got %i" % len(treeish))
+
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates(treeish, kwargs),
++ unsafe_options=cls.unsafe_git_read_tree_options,
++ )
++
+ arg_list: List[Union[Treeish, str]] = []
+ # Ignore that the working tree and index possibly are out of date.
+ if len(treeish) > 1:
+@@ -1398,6 +1428,7 @@ def reset
+ working_tree: bool = False,
+ paths: Union[None, Iterable[PathLike]] = None,
+ head: bool = False,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> "IndexFile":
+ """Reset the index to reflect the tree at the given commit. This will not adjust
+@@ -1429,6 +1460,9 @@ def reset
+ The paths need to exist at the commit, otherwise an exception will be
+ raised.
+
++ :param allow_unsafe_options:
++ Allow options that may write to arbitrary paths.
++
+ :param kwargs:
+ Additional keyword arguments passed to :manpage:`git-reset(1)`.
+
+@@ -1445,7 +1479,7 @@ def reset
+ """
+ # What we actually want to do is to merge the tree into our existing index,
+ # which is what git-read-tree does.
+- new_inst = type(self).from_tree(self.repo, commit)
++ new_inst = type(self).from_tree(self.repo, commit, allow_unsafe_options=allow_unsafe_options)
+ if not paths:
+ self.entries = new_inst.entries
+ else:
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 4a3d516244..df2eea60bc 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -38,6 +38,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-73619_p2.patch \
file://CVE-2026-76221.patch \
file://CVE-2026-76220.patch \
+ file://CVE-2026-76219.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 17/27] python3-git: fix CVE-2026-76218
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (15 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 16/27] python3-git: fix CVE-2026-76219 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 18/27] python3-git: fix CVE-2026-76217 Yogita Urade
` (10 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/d9ddb55bdc66ffe8c9932fe460e6b8c8211e47c7
[2] https://security-tracker.debian.org/tracker/CVE-2026-76218
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Removed the stale cherry-pick and Signed-off-by trailers and
cleaned the Backport Changes formatting.
---
.../python/python3-git/CVE-2026-76218.patch | 92 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 93 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch
new file mode 100644
index 0000000000..1a2bf8ca8e
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch
@@ -0,0 +1,92 @@
+From e9a64de6632678594079cf3e020cbaff44b31615 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 4 Aug 2026 02:48:01 +0000
+Subject: [PATCH] Guard unsafe git init options
+
+<!-- agent -->
+GHSA-9rj7-rf2p-w77r reports that Repo.init forwarded git-init
+options without applying GitPython's unsafe-option policy. A regression
+showed template and abbreviated option spellings reached Git without an
+UnsafeOptionError and could create the destination before validation.
+
+Add a git-init denylist for template installation and separate Git
+directory redirection, check keyword options before any path or directory
+mutation, and provide the standard explicit allow_unsafe_options escape
+hatch. This preserves trusted uses while rejecting untrusted forwarding by
+default.
+
+An audit against Git cf5497b14c5a24f10c13f7e0ee85cb95af13ea6a
+(v2.55.0.windows.3-16-gcf5497b14c) confirmed that init and clone are the
+built-in commands that consume repository template directories. Clone,
+clone_from, and submodule cloning already share the guarded clone helper;
+the similarly named commit option only reads a commit-message template.
+
+Validated with the focused init regression, the clone/init unsafe-option
+suite, 185 config/Git/index/clone tests, Ruff, and basedpyright.
+
+CVE: CVE-2026-76218
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/d9ddb55bdc66ffe8c9932fe460e6b8c8211e47c7]
+
+Backport Changes:
+- Omitted test/test_repo.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+ not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit d9ddb55bdc66ffe8c9932fe460e6b8c8211e47c7)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/repo/base.py | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 4b783586..fd6d660d 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -141,6 +141,14 @@ class Repo:
+ re_author_committer_start = re.compile(r"^(author|committer)")
+ re_tab_full_line = re.compile(r"^\t(.*)$")
+
++ unsafe_git_init_options = [
++ # Can install hooks that execute during later Git commands:
++ "--template",
++ # Redirects the repository metadata to a caller-controlled path:
++ "--separate-git-dir",
++ ]
++ """Options to :manpage:`git-init(1)` that permit unsafe code execution or I/O."""
++
+ unsafe_git_clone_options = [
+ # Executes arbitrary commands:
+ "--upload-pack",
+@@ -1345,6 +1353,7 @@ class Repo:
+ mkdir: bool = True,
+ odbt: Type[GitCmdObjectDB] = GitCmdObjectDB,
+ expand_vars: bool = True,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> "Repo":
+ """Initialize a git repository at the given path if specified.
+@@ -1369,6 +1378,10 @@ class Repo:
+ information disclosure, allowing attackers to access the contents of
+ environment variables.
+
++ :param allow_unsafe_options:
++ Allow unsafe options to be used, such as ``--template`` and
++ ``--separate-git-dir``.
++
+ :param kwargs:
+ Keyword arguments serving as additional options to the
+ :manpage:`git-init(1)` command.
+@@ -1376,6 +1389,11 @@ class Repo:
+ :return:
+ :class:`Repo` (the newly created repo)
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=cls.unsafe_git_init_options,
++ )
+ if path:
+ path = expand_path(path, expand_vars)
+ if mkdir and path and not osp.exists(path):
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index df2eea60bc..173643a49b 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -39,6 +39,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76221.patch \
file://CVE-2026-76220.patch \
file://CVE-2026-76219.patch \
+ file://CVE-2026-76218.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 18/27] python3-git: fix CVE-2026-76217
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (16 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 17/27] python3-git: fix CVE-2026-76218 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 19/27] python3-git: fix CVE-2026-76222 Yogita Urade
` (9 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/f2550b65bf60ca087190981e2c7b6865e201f40c
[2] https://security-tracker.debian.org/tracker/CVE-2026-76217
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Removed the stale cherry-pick and Signed-off-by trailers and
refreshed the embedded hunk context.
---
.../python/python3-git/CVE-2026-76217.patch | 179 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 180 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76217.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76217.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76217.patch
new file mode 100644
index 0000000000..f369c778b0
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76217.patch
@@ -0,0 +1,179 @@
+From c99cba55c8ad6eff105ee61b15f7c683e7e4d878 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 4 Aug 2026 03:18:54 +0000
+Subject: [PATCH] Guard pathspec file inputs in high-level commands
+
+<!-- agent -->
+GHSA-hh9p-6wh2-4mfc reports that high-level rm and checkout wrappers
+forwarded pathspec file options without GitPython's unsafe-option policy.
+A regression showed that both commands surfaced multi-line pathspec data in
+Git errors, while reset consumed the same caller-selected file without a
+validation error. The audit also found that reset's positional commit could
+carry the option before its argument separator.
+
+Define one shared unsafe pathspec-file option list and apply it to
+IndexFile.remove, Head.checkout, and HEAD.reset before invoking Git. Check
+reset's positional commit as well as keyword options, retain the standard
+allow_unsafe_options escape hatch for trusted callers, and cover abbreviated
+long-option spellings.
+
+An audit against Git cf5497b14c5a24f10c13f7e0ee85cb95af13ea6a
+(v2.55.0.windows.3-16-gcf5497b14c) found pathspec-file support in add,
+checkout/restore, commit, reset, rm, and stash. GitPython has no arbitrary
+high-level option forwarding to the other commands, and git mv does not
+support this option.
+
+Validated with focused rejection and opt-in tests, 214 affected-module
+regressions, Ruff, basedpyright, and git diff --check.
+
+CVE: CVE-2026-76217
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/f2550b65bf60ca087190981e2c7b6865e201f40c]
+
+Backport Changes:
+- Omitted test/test_git.py, test/test_index.py, test/test_refs.py because the
+ current PyPI source archive does not include the test suite and the
+ python3-git recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit f2550b65bf60ca087190981e2c7b6865e201f40c)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 6 ++++++
+ git/index/base.py | 10 ++++++++++
+ git/refs/head.py | 27 ++++++++++++++++++++++++++-
+ 3 files changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 63bbb3f7..20abd015 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -421,6 +421,12 @@ class Git(metaclass=_GitMeta):
+
+ re_unsafe_protocol = re.compile(r"(.+)::.+")
+
++ unsafe_git_pathspec_from_file_options = [
++ # Reads pathspecs from a caller-controlled file. Some commands include an
++ # unmatched pathspec in their error output, which can disclose the file.
++ "--pathspec-from-file",
++ ]
++
+ def __getstate__(self) -> Dict[str, Any]:
+ return slots_to_dict(self, exclude=self._excluded_)
+
+
+diff --git a/git/index/base.py b/git/index/base.py
+index fb1acb1a..f5932f2d 100644
+--- a/git/index/base.py
++++ b/git/index/base.py
+@@ -1011,6 +1011,7 @@ IndexFile.remove
+ self,
+ items: Sequence[Union[PathLike, Blob, BaseIndexEntry, "Submodule"]],
+ working_tree: bool = False,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> List[str]:
+ R"""Remove the given items from the index and optionally from the working tree
+@@ -1041,6 +1042,10 @@ IndexFile.remove documentation
+ physically removing the respective file. This may fail if there are
+ uncommitted changes in it.
+
++ :param allow_unsafe_options:
++ Allow unsafe options such as ``--pathspec-from-file`` to be passed to
++ :manpage:`git-rm(1)`.
++
+ :param kwargs:
+ Additional keyword arguments to be passed to :manpage:`git-rm(1)`, such as
+ ``r`` to allow recursive removal.
+@@ -1052,6 +1057,11 @@ IndexFile.remove unsafe-option validation
+ This is interesting to know in case you have provided a directory or globs.
+ Paths are relative to the repository.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=Git.unsafe_git_pathspec_from_file_options,
++ )
+ args = []
+ if not working_tree:
+ args.append("--cached")
+
+diff --git a/git/refs/head.py b/git/refs/head.py
+index 7e6fc337..1b82fbd3 100644
+--- a/git/refs/head.py
++++ b/git/refs/head.py
+@@ -19,6 +19,7 @@ HEAD.reset import
+
+ from typing import Any, Sequence, TYPE_CHECKING, Union
+
++from git.cmd import Git
+ from git.types import Commit_ish, PathLike
+
+ if TYPE_CHECKING:
+@@ -66,6 +67,7 @@ HEAD.reset signature
+ index: bool = True,
+ working_tree: bool = False,
+ paths: Union[PathLike, Sequence[PathLike], None] = None,
++ allow_unsafe_options: bool = False,
+ **kwargs: Any,
+ ) -> "HEAD":
+ """Reset our HEAD to the given commit optionally synchronizing the index and
+@@ -88,12 +90,21 @@ HEAD.reset option validation and documentation
+ Single path or list of paths relative to the git root directory
+ that are to be reset. This allows to partially reset individual files.
+
++ :param allow_unsafe_options:
++ Allow unsafe options such as ``--pathspec-from-file`` to be passed to
++ :manpage:`git-reset(1)`.
++
+ :param kwargs:
+ Additional arguments passed to :manpage:`git-reset(1)`.
+
+ :return:
+ self
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([commit], kwargs),
++ unsafe_options=Git.unsafe_git_pathspec_from_file_options,
++ )
+ mode: Union[str, None]
+ mode = "--soft"
+ if index:
+@@ -238,7 +249,12 @@ Head.checkout signature
+ self.path = "%s/%s" % (self._common_path_default, new_path)
+ return self
+
+- def checkout(self, force: bool = False, **kwargs: Any) -> Union["HEAD", "Head"]:
++ def checkout(
++ self,
++ force: bool = False,
++ allow_unsafe_options: bool = False,
++ **kwargs: Any,
++ ) -> Union["HEAD", "Head"]:
+ """Check out this head by setting the HEAD to this reference, by updating the
+ index to reflect the tree we point to and by updating the working tree to
+ reflect the latest index.
+@@ -250,6 +266,10 @@ Head.checkout documentation
+ If ``False``, :exc:`~git.exc.GitCommandError` will be raised in that
+ situation.
+
++ :param allow_unsafe_options:
++ Allow unsafe options such as ``--pathspec-from-file`` to be passed to
++ :manpage:`git-checkout(1)`.
++
+ :param kwargs:
+ Additional keyword arguments to be passed to git checkout, e.g.
+ ``b="new_branch"`` to create a new branch at the given spot.
+@@ -265,6 +285,11 @@ Head.checkout unsafe-option validation
+ the HEAD detached which is allowed and possible, but remains a special state
+ that some tools might not be able to handle.
+ """
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(
++ options=Git._option_candidates([], kwargs),
++ unsafe_options=Git.unsafe_git_pathspec_from_file_options,
++ )
+ kwargs["f"] = force
+ if kwargs["f"] is False:
+ kwargs.pop("f")
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 173643a49b..4e5eec73f1 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -40,6 +40,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76220.patch \
file://CVE-2026-76219.patch \
file://CVE-2026-76218.patch \
+ file://CVE-2026-76217.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 19/27] python3-git: fix CVE-2026-76222
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (17 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 18/27] python3-git: fix CVE-2026-76217 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 20/27] python3-git: fix CVE-2026-78678 CVE-2026-78679 Yogita Urade
` (8 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [4],
[5] and [6] using the commit shown in [1], regression fix
in [2] and follow-up fix in [3].
[1] https://github.com/gitpython-developers/GitPython/commit/e4b8e7d026ca6abb4cf604f8e77093432ce23c06
[2] https://github.com/gitpython-developers/GitPython/commit/b324c831cbc02c82b99c18113b622d03539d23cd
[3] https://github.com/gitpython-developers/GitPython/commit/4299c990e1ca21896f9485277caf7bb0ae5b404c
[4] https://security-tracker.debian.org/tracker/CVE-2026-76222
[5] https://github.com/gitpython-developers/GitPython/pull/2202
[6] https://github.com/gitpython-developers/GitPython/pull/2205
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Added upstream pull-request references. Removed stale cherry-pick/sign-off
trailers from the embedded p1 and p2 patches and cleaned patch formatting.
---
.../CVE-2026-76222-regression.patch | 39 ++++++
.../python3-git/CVE-2026-76222_p1.patch | 118 ++++++++++++++++++
.../python3-git/CVE-2026-76222_p2.patch | 45 +++++++
.../python/python3-git_3.1.43.bb | 3 +
4 files changed, 205 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222-regression.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76222-regression.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76222-regression.patch
new file mode 100644
index 0000000000..5d416c03a8
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76222-regression.patch
@@ -0,0 +1,39 @@
+From b324c831cbc02c82b99c18113b622d03539d23cd Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 4 Aug 2026 11:07:02 +0200
+Subject: [PATCH] Initialize submodule repository before handled failures
+
+<!-- agent -->
+Direct recursive updates with keep_going could swallow an invalid-name
+validation error and then access mrepo before assignment. Reproduce that
+path and initialize mrepo before validation so recursion is safely skipped.
+
+Git baseline: submodule.c at 883a47ef6496c96a5d6132ed8c87fcd44ebf8d1a
+validates submodule paths before operating on them.
+
+CVE: CVE-2026-76222
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/b324c831cbc02c82b99c18113b622d03539d23cd]
+
+Backport Changes:
+- Omitted .basedpyright/baseline.json and test/test_submodule.py because the
+ current PyPI source archive does not include these development files, and the
+ python3-git recipe does not run the test suite.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit b324c831cbc02c82b99c18113b622d03539d23cd)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index 658259cd..9b1eb0e0 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -743,4 +743,2 @@
+- # To keep things plausible in dry-run mode.
+- if dry_run:
+- mrepo = None
++ mrepo = None
+ # END init mrepo
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch
new file mode 100644
index 0000000000..6c75489610
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch
@@ -0,0 +1,118 @@
+From 3f48614f5b02f67daf311a6681e6e5090a7f7dc3 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Sat, 1 Aug 2026 04:47:40 +0200
+Subject: [PATCH] Validate submodule names before filesystem operations
+
+<!-- agent -->
+Submodule names read from .gitmodules can influence the separate Git directory
+path. Reject empty names, absolute or drive-qualified names, and parent
+components with either path separator.
+
+Validate before constructing module paths and before opening or mutating
+existing checkouts, so a repository initialized by an older vulnerable version
+cannot bypass the guard. Validate programmatic add and rename inputs before
+making changes as well.
+
+Advisory: GHSA-hmq2-w58f-27jc
+
+CVE: CVE-2026-76222
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/e4b8e7d026ca6abb4cf604f8e77093432ce23c06]
+
+Backport Changes:
+- Omitted test/test_submodule.py because the current PyPI source archive
+ does not include the test suite, and the python3-git recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit e4b8e7d026ca6abb4cf604f8e77093432ce23c06)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index 43e0ec9a..a4e0077c 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -6,6 +6,7 @@ __all__ = ["Submodule", "UpdateProgress"]
+ import gc
+ from io import BytesIO
+ import logging
++import ntpath
+ import os
+ import os.path as osp
+ import stat
+@@ -300,10 +301,21 @@ class Submodule(IndexObject, TraversableIterableObj):
+ parser.set_submodule(self)
+ return SectionConstraint(parser, sm_section(self.name))
+
++ @classmethod
++ def _validated_name(cls, name: str) -> str:
++ if (
++ not name
++ or name.startswith(("/", "\\"))
++ or ntpath.splitdrive(name)[0]
++ or ".." in name.replace("\\", "/").split("/")
++ ):
++ raise ValueError("Invalid submodule name %r" % name)
++ return name
++
+ @classmethod
+ def _module_abspath(cls, parent_repo: "Repo", path: PathLike, name: str) -> PathLike:
+ if cls._need_gitfile_submodules(parent_repo.git):
+- return osp.join(parent_repo.git_dir, "modules", name)
++ return osp.join(parent_repo.git_dir, "modules", cls._validated_name(name))
+ if parent_repo.working_tree_dir:
+ return osp.join(parent_repo.working_tree_dir, path)
+ raise NotADirectoryError()
+@@ -516,6 +528,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ raise InvalidGitRepositoryError("Cannot add submodules to bare repositories")
+ # END handle bare repos
+
++ cls._validated_name(name)
+ path = cls._to_relative_path(repo, path)
+
+ # Ensure we never put backslashes into the URL, as might happen on Windows.
+@@ -733,6 +746,8 @@ class Submodule(IndexObject, TraversableIterableObj):
+ # END init mrepo
+
+ try:
++ self._validated_name(self.name)
++
+ # ENSURE REPO IS PRESENT AND UP-TO-DATE
+ #######################################
+ try:
+@@ -999,6 +1014,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ raise ValueError("You must specify to move at least the module or the configuration of the submodule")
+ # END handle input
+
++ self._validated_name(self.name)
+ module_checkout_path = self._to_relative_path(self.repo, module_path)
+
+ # VERIFY DESTINATION
+@@ -1139,6 +1155,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ raise ValueError("Need to specify to delete at least the module, or the configuration")
+ # END handle parameters
+
++ self._validated_name(self.name)
+ # Recursively remove children of this submodule.
+ nc = 0
+ for csm in self.children():
+@@ -1365,6 +1382,9 @@ class Submodule(IndexObject, TraversableIterableObj):
+ if self.name == new_name:
+ return self
+
++ self._validated_name(self.name)
++ self._validated_name(new_name)
++
+ # .git/config
+ with self.repo.config_writer() as pw:
+ # As we ourselves didn't write anything about submodules into the parent
+@@ -1412,6 +1432,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ If a repository was not available.
+ This could also mean that it was not yet initialized.
+ """
++ self._validated_name(self.name)
+ module_checkout_abspath = self.abspath
+ try:
+ repo = git.Repo(module_checkout_abspath)
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch
new file mode 100644
index 0000000000..1f21369acd
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch
@@ -0,0 +1,45 @@
+From 4a0dfd9b336dd9332b347c3af8e8ec536017d863 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 4 Aug 2026 10:08:41 +0200
+Subject: [PATCH] Validate submodule names on every module path branch
+
+<!-- agent -->
+_module_abspath only validated names when Git used separate gitfile
+submodule directories, so legacy Git behavior could accept the same invalid
+name. Validate before selecting the Git-version-dependent path branch and
+cover the legacy branch explicitly.
+
+Git baseline: submodule.c at 883a47ef6496c96a5d6132ed8c87fcd44ebf8d1a
+validates submodule paths before filesystem operations.
+
+CVE: CVE-2026-76222
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/4299c990e1ca21896f9485277caf7bb0ae5b404c]
+
+Backport Changes:
+- Omitted test/test_submodule.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 4299c990e1ca21896f9485277caf7bb0ae5b404c)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index a4e0077c..d25df367 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -314,8 +314,9 @@ class Submodule(IndexObject, TraversableIterableObj):
+
+ @classmethod
+ def _module_abspath(cls, parent_repo: "Repo", path: PathLike, name: str) -> PathLike:
++ name = cls._validated_name(name)
+ if cls._need_gitfile_submodules(parent_repo.git):
+- return osp.join(parent_repo.git_dir, "modules", cls._validated_name(name))
++ return osp.join(parent_repo.git_dir, "modules", name)
+ if parent_repo.working_tree_dir:
+ return osp.join(parent_repo.working_tree_dir, path)
+ raise NotADirectoryError()
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 4e5eec73f1..ef1c687c02 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -41,6 +41,9 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76219.patch \
file://CVE-2026-76218.patch \
file://CVE-2026-76217.patch \
+ file://CVE-2026-76222_p1.patch \
+ file://CVE-2026-76222-regression.patch \
+ file://CVE-2026-76222_p2.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 20/27] python3-git: fix CVE-2026-78678 CVE-2026-78679
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (18 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 19/27] python3-git: fix CVE-2026-76222 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 21/27] python3-git: fix CVE-2026-78677 Yogita Urade
` (7 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2]
and [3], using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6
[2] https://security-tracker.debian.org/tracker/CVE-2026-78678
[3] https://security-tracker.debian.org/tracker/CVE-2026-78679
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Added --exec to the ls_remote unsafe-option list. Converted the
configurable clusterable-short-option string to a frozenset
before membership checks, and updated the ls_remote documentation.
---
.../CVE-2026-78678_CVE-2026-78679.patch | 220 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 221 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78678_CVE-2026-78679.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-78678_CVE-2026-78679.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-78678_CVE-2026-78679.patch
new file mode 100644
index 0000000000..337efbe22f
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-78678_CVE-2026-78679.patch
@@ -0,0 +1,220 @@
+From 51216053bd6885b546be8e9ed2e8e1000e7ee5a3 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Wed, 5 Aug 2026 04:48:36 +0200
+Subject: [PATCH] Block file-reading Git options
+
+<!-- agent -->
+Reject file-reading options passed to blame, diff, and tag APIs. Inspect
+positional values after resolving aliases, recognize unsafe options
+behind command-specific short-flag clusters, and retain the explicit
+allow_unsafe_options escape hatch. This closes GHSA-5xxx-qhh7-9287 and
+GHSA-3wxw-xv34-2frg and covers the adjacent diff order-file sink.
+
+Regression tests cover long, short, and clustered options, incremental blame,
+tag path/reference positionals, the ref keyword alias, both diff entry points,
+and preservation of diff pickaxe behavior.
+
+Git baseline: cf5497b14c; git-blame, git-diff, and git-tag document the relevant file-input options.
+
+CVE: CVE-2026-78678 CVE-2026-78679
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6]
+
+Backport Changes:
+- Omitted test/test_diff.py, test/test_refs.py, test/test_remote.py,
+ test/test_repo.py because the Wrynose PyPI source archive does not include
+ the test suite and the python3-git recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/cmd.py | 11 +++++++----
+ git/diff.py | 7 ++++---
+ git/index/base.py | 3 ++-
+ git/refs/tag.py | 10 ++++++----
+ git/repo/base.py | 24 ++++++++++++++++++++----
+ 5 files changed, 39 insertions(+), 16 deletions(-)
+
+diff --git a/git/cmd.py b/git/cmd.py
+index 20abd015..b8ad449f 100644
+--- a/git/cmd.py
++++ b/git/cmd.py
+@@ -417,6 +417,7 @@ Git.unsafe_git_ls_remote_options
+ unsafe_git_ls_remote_options = [
+ # This option allows arbitrary command execution in git-ls-remote.
+ "--upload-pack",
++ "--exec",
+ ]
+
+ re_unsafe_protocol = re.compile(r"(.+)::.+")
+@@ -743,7 +744,9 @@ Git.check_unsafe_options signature
+ return dashify(option_tokens[0])
+
+ @classmethod
+- def check_unsafe_options(cls, options: List[str], unsafe_options: List[str]) -> None:
++ def check_unsafe_options(
++ cls, options: List[str], unsafe_options: List[str], clusterable_short_options: str = "46flnqsv"
++ ) -> None:
+ """Raise :class:`~git.exc.UnsafeOptionError` for blocked option spellings.
+
+ In addition to exact matches, this rejects abbreviated long options accepted
+@@ -778,7 +781,7 @@ Git.check_unsafe_options clusterable short flags
+ # These value-less Git flags can be clustered before another short option
+ # (for example, ``-fuVALUE``). Stop at any other character because it may
+ # begin an attached value, as ``o`` does in the safe option ``-oupstream``.
+- clusterable_short_options = frozenset("46flnqsv")
++ clusterable_short_options_set = frozenset(clusterable_short_options)
+ options_are_kwargs = all(not option.startswith("-") for option in options)
+ for option in options:
+ candidate = cls._canonicalize_option_name(option)
+@@ -795,7 +798,7 @@ Git.check_unsafe_options short-option parsing
+ raise UnsafeOptionError(
+ f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
+ )
+- if option_char not in clusterable_short_options:
++ if option_char not in clusterable_short_options_set:
+ break
+ if not (option.startswith("--") or (options_are_kwargs and len(candidate) > 1)):
+ continue
+@@ -1101,7 +1104,7 @@ Git.ls_remote documentation
+ """List references in a remote repository.
+
+ :param allow_unsafe_options:
+- Allow unsafe options, like ``--upload-pack``.
++ Allow unsafe options, like ``--upload-pack`` or ``--exec``.
+ """
+ if not allow_unsafe_options:
+ candidate_options = self._option_candidates(args, kwargs)
+
+diff --git a/git/diff.py b/git/diff.py
+index 9a1f107b..032dfb25 100644
+--- a/git/diff.py
++++ b/git/diff.py
+@@ -216,8 +216,8 @@ Diffable.diff documentation
+ to be read and diffed.
+
+ :param allow_unsafe_options:
+- If ``True``, allow options such as ``--output`` that can write to arbitrary
+- filesystem paths.
++ If ``True``, allow options such as ``--output`` and ``-O`` that can write to
++ or read from arbitrary filesystem paths.
+
+ :param kwargs:
+ Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to
+@@ -234,7 +234,8 @@ Diffable.diff unsafe-option validation
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+ options=Git._option_candidates([other], kwargs),
+- unsafe_options=self.repo.unsafe_git_revision_options,
++ unsafe_options=self.repo.unsafe_git_diff_options,
++ clusterable_short_options="46abceflmnpqrstuvwzBCDMNRW",
+ )
+
+ args: List[Union[PathLike, Diffable]] = []
+
+diff --git a/git/index/base.py b/git/index/base.py
+index f5932f2d..0ff15794 100644
+--- a/git/index/base.py
++++ b/git/index/base.py
+@@ -1550,7 +1550,8 @@ IndexFile.diff unsafe-option validation
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+ options=Git._option_candidates([other], kwargs),
+- unsafe_options=self.repo.unsafe_git_revision_options,
++ unsafe_options=self.repo.unsafe_git_diff_options,
++ clusterable_short_options="46abceflmnpqrstuvwzBCDMNRW",
+ )
+
+ # Only run if we are the default repository index.
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index b6fd7620..c91dd1f2 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -198,6 +198,19 @@ Repo unsafe-option lists
+ ]
+
+
++ unsafe_git_blame_options = unsafe_git_revision_options + [
++ # These options read from arbitrary files and expose their contents through blame output.
++ "--contents",
++ "-S",
++ "--ignore-revs-file",
++ ]
++
++ unsafe_git_diff_options = unsafe_git_revision_options + [
++ # Reads caller-controlled order patterns from an arbitrary file.
++ "-O",
++ "--orderfile",
++ ]
++
+ # Invariants
+ config_level: ConfigLevels_Tup = ("system", "user", "global", "repository")
+ """Represents the configuration level of a configuration file."""
+@@ -1102,7 +1115,7 @@ Repo.blame_incremental documentation and validation
+ :manpage:`git-rev-parse(1)` is a valid option.
+
+ :param allow_unsafe_options:
+- Allow unsafe options in revision argument, like ``--output``.
++ Allow unsafe options in revision argument, like ``--output`` or ``--contents``.
+
+ :return:
+ Lazy iterator of :class:`BlameEntry` tuples, where the commit indicates the
+@@ -1115,7 +1128,9 @@ Repo.blame_incremental unsafe-option validation
+
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+- options=Git._option_candidates([rev], kwargs), unsafe_options=self.unsafe_git_revision_options
++ options=Git._option_candidates([rev], kwargs),
++ unsafe_options=self.unsafe_git_blame_options,
++ clusterable_short_options="46bceflnpqstvw",
+ )
+ data: bytes = self.git.blame(rev, "--", file, p=True, incremental=True, stdout_as_string=False, **kwargs)
+ commits: Dict[bytes, Commit] = {}
+@@ -1205,7 +1220,7 @@ Repo.blame documentation
+ uncommitted changes. Otherwise, anything successfully parsed by
+ :manpage:`git-rev-parse(1)` is a valid option.
+ :param allow_unsafe_options:
+- Allow unsafe options in revision argument, like ``--output``.
++ Allow unsafe options in revision argument, like ``--output`` or ``--contents``.
+
+
+ :return:
+@@ -1222,7 +1237,8 @@ Repo.blame unsafe-option validation
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+ options=Git._option_candidates([rev, rev_opts_list], kwargs),
+- unsafe_options=self.unsafe_git_revision_options,
++ unsafe_options=self.unsafe_git_blame_options,
++ clusterable_short_options="46bceflnpqstvw",
+ )
+ data: bytes = self.git.blame(rev, *rev_opts_list, "--", file, p=True, stdout_as_string=False, **kwargs)
+ commits: Dict[str, Commit] = {}
+
+diff --git a/git/refs/tag.py b/git/refs/tag.py
+index 07efa62f..d45fb7eb 100644
+--- a/git/refs/tag.py
++++ b/git/refs/tag.py
+@@ -134,15 +134,17 @@ TagReference.create unsafe-option validation
+ :return:
+ A new :class:`TagReference`.
+ """
++ legacy_ref = kwargs.pop("ref", None)
++ if legacy_ref:
++ reference = legacy_ref
++
+ if not allow_unsafe_options:
+ Git.check_unsafe_options(
+- options=Git._option_candidates([], kwargs),
++ options=Git._option_candidates([path, reference], kwargs),
+ unsafe_options=cls.unsafe_git_tag_options,
++ clusterable_short_options="46adefilnqsv",
+ )
+
+- if "ref" in kwargs and kwargs["ref"]:
+- reference = kwargs["ref"]
+-
+ if "message" in kwargs and kwargs["message"]:
+ kwargs["m"] = kwargs["message"]
+ del kwargs["message"]
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index ef1c687c02..dc7694f593 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -44,6 +44,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76222_p1.patch \
file://CVE-2026-76222-regression.patch \
file://CVE-2026-76222_p2.patch \
+ file://CVE-2026-78678_CVE-2026-78679.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 21/27] python3-git: fix CVE-2026-78677
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (19 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 20/27] python3-git: fix CVE-2026-78678 CVE-2026-78679 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 22/27] python3-git: fix CVE-2026-78676 Yogita Urade
` (6 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/b68afff45af0f49e79a3e2d2162018986b37ad5d
[2] https://security-tracker.debian.org/tracker/CVE-2026-78677
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Clarified the --bundle-uri comment and changed the unsafe-clone-options
docstring to cover unsafe command execution or I/O. The --separate-git-dir
guard is unchanged.
---
.../python/python3-git/CVE-2026-78677.patch | 87 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 88 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78677.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-78677.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-78677.patch
new file mode 100644
index 0000000000..2f7714e6cc
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-78677.patch
@@ -0,0 +1,87 @@
+From 03baa6374b8769a9544292d84040b323c5f1437a Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Mon, 10 Aug 2026 11:20:03 +0200
+Subject: [PATCH] Block separate git directories during clone
+
+<!-- agent -->
+Repo.clone() and Repo.clone_from() did not reject the clone option that
+redirects repository metadata to a caller-controlled path (GHSA-8mcc-hrx5-hvxc).
+Regression coverage exercises both keyword and multi-option input through both
+public clone APIs.
+
+Add the option to the existing clone denylist, matching Repo.init()
+and the documented allow_unsafe_options contract. Git itself registers
+
+The Python package and Alpine test workflows failed across the submodule suite
+because GitPython internally supplies --separate-git-dir when creating modern
+submodule layouts. The new public clone guard correctly rejected that option,
+but could not distinguish the library-generated path from caller input.
+
+Validate caller-provided keyword and multi-options before adding the
+library-controlled metadata path, then explicitly allow the resulting trusted
+clone invocation. This preserves rejection of unsafe clone_multi_options while
+restoring normal submodule creation. Update the one test that intentionally
+invokes Repo.clone_from() with its own separate git directory to opt in
+explicitly.
+
+CVE: CVE-2026-78677
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/b68afff45af0f49e79a3e2d2162018986b37ad5d]
+
+Backport Changes:
+- Omitted test/test_clone.py, test/test_submodule.py because the current PyPI
+ source archive does not include the test suite and the python3-git recipe
+ does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit b68afff45af0f49e79a3e2d2162018986b37ad5d)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 10 ++++++++++
+ git/repo/base.py | 2 ++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index d25df367..410f41e2 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -9,6 +9,7 @@ import logging
+ import ntpath
+ import os
+ import os.path as osp
++import shlex
+ import stat
+ import sys
+ import uuid
+@@ -360,6 +361,15 @@ class Submodule(IndexObject, TraversableIterableObj):
+ module_abspath = cls._module_abspath(repo, path, name)
+ module_checkout_path = module_abspath
+ if cls._need_gitfile_submodules(repo.git):
++ if not allow_unsafe_options:
++ Git.check_unsafe_options(Git._option_candidates([], kwargs), repo.unsafe_git_clone_options)
++ multi_options = kwargs.get("multi_options")
++ if multi_options:
++ Git.check_unsafe_options(
++ shlex.split(" ".join(cast("Sequence[str]", multi_options))),
++ repo.unsafe_git_clone_options,
++ )
++ allow_unsafe_options = True
+ kwargs["separate_git_dir"] = module_abspath
+ module_abspath_dir = osp.dirname(module_abspath)
+ if not osp.isdir(module_abspath_dir):
+diff --git a/git/repo/base.py b/git/repo/base.py
+index fd6d660d..56a19dc5 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -158,7 +158,9 @@ class Repo:
+ "-c",
+ # Can install hooks that execute during clone:
+ "--template",
++ # Redirects the repository metadata to a caller-controlled path:
++ "--separate-git-dir",
+ # Fetches from an additional caller-controlled URI:
+ "--bundle-uri",
+ ]
+ """Options to :manpage:`git-clone(1)` that permit unsafe command execution or I/O.
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index dc7694f593..fbb1553778 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -45,6 +45,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76222-regression.patch \
file://CVE-2026-76222_p2.patch \
file://CVE-2026-78678_CVE-2026-78679.patch \
+ file://CVE-2026-78677.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 22/27] python3-git: fix CVE-2026-78676
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (20 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 21/27] python3-git: fix CVE-2026-78677 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 23/27] python3-git: fix CVE-2026-78675 Yogita Urade
` (5 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/4b4e47fc1224e23b0c8ee7220a7192818f2e4abb
[2] https://security-tracker.debian.org/tracker/CVE-2026-78676
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
- Included the reader-side prerequisite from 47e5738074e7, which prevents
IndexError when reading serialized config values.
---
.../python/python3-git/CVE-2026-78676.patch | 67 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 68 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch
new file mode 100644
index 0000000000..8adee8140f
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch
@@ -0,0 +1,67 @@
+From 5095b034dc451f3ec0c4c77c69403c8fce7eb6d7 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Mon, 10 Aug 2026 12:22:31 +0200
+Subject: [PATCH] fix: preserve multiline config values when writing
+
+<!-- agent -->
+GitConfigParser decoded valid multiline values into embedded newlines, but
+_write() serialized those newlines as indented physical lines. Rewriting an
+otherwise unchanged config could therefore change its meaning to Git.
+
+Serialize resident multiline values with Git-compatible escapes inside a
+quoted continuation, preserving GitPython read compatibility while keeping
+each option structurally intact. This addresses GHSA-284h-m62q-gf8w.
+
+The regression starts with an inert multiline value, performs an unrelated
+write, and verifies with both GitPython and git config that it remains one
+value and does not create another option.
+
+Git baseline: config.c parse_value() and write_pair() at cf5497b14c5a escape
+embedded LF as \\n rather than emitting it as a physical config line.
+
+CVE: CVE-2026-78676
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/4b4e47fc1224e23b0c8ee7220a7192818f2e4abb]
+
+Backport Changes:
+- Commit 47e5738074e7 is an earlier prerequisite for this serialization
+ change. Its reader-side empty-string guard prevents IndexError when
+ reading serialized config values.
+- Omitted test/test_config.py changes from both upstream commits;
+ the recipe source archive excludes the test suite and the recipe
+ does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 4b4e47fc1224e23b0c8ee7220a7192818f2e4abb)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/config.py | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/git/config.py b/git/config.py
+index 30218dba..e8482a08 100644
+--- a/git/config.py
++++ b/git/config.py
+@@ -454,8 +454,8 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
+ def string_decode(v: str) -> str:
+- if v[-1] == "\\":
++ if v and v[-1] == "\\":
+ v = v[:-1]
+ # END cut trailing escapes to prevent decode error
+
+ return v.encode(defenc).decode("unicode_escape")
+
+ # END string_decode
+@@ -681,7 +681,11 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
+ continue
+
+ for v in values:
+- fp.write(("\t%s = %s\n" % (key, self._value_to_string(v).replace("\n", "\n\t"))).encode(defenc))
++ value = self._value_to_string(v)
++ if any(char in value for char in '\n\t\b\\"'):
++ value = value.replace("\\", "\\\\").replace('"', '\\"')
++ value = '"%s\\\n"' % value.replace("\n", "\\n").replace("\t", "\\t").replace("\b", "\\b")
++ fp.write(("\t%s = %s\n" % (key, value)).encode(defenc))
+ # END if key is not __name__
+
+ # END section writing
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index fbb1553778..badbf04415 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -46,6 +46,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-76222_p2.patch \
file://CVE-2026-78678_CVE-2026-78679.patch \
file://CVE-2026-78677.patch \
+ file://CVE-2026-78676.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 23/27] python3-git: fix CVE-2026-78675
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (21 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 22/27] python3-git: fix CVE-2026-78676 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 24/27] python3-git: fix CVE-2026-87817 Yogita Urade
` (4 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/ef7568e3b317ce617eacda39b8b54dcdff8c3b5c
[2] https://security-tracker.debian.org/tracker/CVE-2026-78675
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
---
.../python/python3-git/CVE-2026-78675.patch | 47 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 48 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch
new file mode 100644
index 0000000000..0cef9a19b0
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch
@@ -0,0 +1,47 @@
+From eaa63265a59f069bf13384481c48fa48a25ff087 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Mon, 10 Aug 2026 12:32:24 +0200
+Subject: [PATCH] fix: ignore includes in submodule configuration
+
+<!-- agent -->
+Submodule configuration is read from .gitmodules, whose contents may come
+from an untrusted repository. Its parser inherited merge_includes=True and
+could therefore open files named by include directives during ordinary
+submodule enumeration.
+
+Disable include merging at the SubmoduleConfigParser construction site. This
+matches Repo.config_writer() hardening from 41ecc6a4 and addresses
+GHSA-7833-fr7j-v32q without changing include behavior for trusted config
+parsers.
+
+The regression points .gitmodules at a non-config file and verifies the
+submodule entry remains readable without opening the included path.
+
+CVE: CVE-2026-78675
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/ef7568e3b317ce617eacda39b8b54dcdff8c3b5c]
+
+Backport Changes:
+- Omitted test/test_submodule.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit ef7568e3b317ce617eacda39b8b54dcdff8c3b5c)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
+index 410f41e2..e37f8fa9 100644
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -268,7 +268,7 @@ class Submodule(IndexObject, TraversableIterableObj):
+ raise ValueError("Cannot write blobs of 'historical' submodule configurations")
+ # END handle writes of historical submodules
+
+- return SubmoduleConfigParser(fp_module, read_only=read_only)
++ return SubmoduleConfigParser(fp_module, read_only=read_only, merge_includes=False)
+
+ def _clear_cache(self) -> None:
+ """Clear the possibly changed values."""
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index badbf04415..0dd42e1f04 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -47,6 +47,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-78678_CVE-2026-78679.patch \
file://CVE-2026-78677.patch \
file://CVE-2026-78676.patch \
+ file://CVE-2026-78675.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 24/27] python3-git: fix CVE-2026-87817
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (22 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 23/27] python3-git: fix CVE-2026-78675 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 25/27] python3-git: fix CVE-2026-87818 Yogita Urade
` (3 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/c7cf4d13b1ed0a2e70f2a1f3c6b4fc6c2652cf0b
[2] https://security-tracker.debian.org/tracker/CVE-2026-87817
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker and
corrected the embedded From hash to the cited upstream commit. Added the
missing re import. Updated alternates lookup to use self.odb.root_path();
moved Cygwin and relative-path handling in find_submodule_git_dir() and
return a path only when is_git_dir() validates it. Expanded Backport
Changes to describe the GitPython 3.1.43 adaptations and omitted
documentation/tests.
---
.../python/python3-git/CVE-2026-87817.patch | 443 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 444 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87817.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-87817.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-87817.patch
new file mode 100644
index 0000000000..fc604ca44f
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-87817.patch
@@ -0,0 +1,443 @@
+From c7cf4d13b1ed0a2e70f2a1f3c6b4fc6c2652cf0b Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 25 Aug 2026 04:57:29 +0200
+Subject: [PATCH] fix: prefer `.git` during repository discovery
+
+<!-- agent -->
+GitPython considered worktree administration and bare-repository signatures
+before a worktree's real .git entry. Align discovery with Git so .git files
+and directories win, malformed .git files stop discovery, and candidate git
+directories validate HEAD plus commondir-backed object and ref storage. This
+addresses GHSA-239g-whfq-7xj9.
+
+Regression coverage compares ambiguous layouts with git rev-parse and rejects
+invalid HEAD/.git metadata.
+
+Git baseline: 15c6308cf7ad276b306aa5b3ababfbdebfb1a917; setup.c
+setup_git_directory_gently_1(), is_git_directory(), and validate_headref().
+
+Repository validation can use GIT_COMMON_DIR for refs and objects. Preserve the
+same value on Repo so later config, ref, and object access uses the directory
+that made discovery succeed.
+
+Capture GIT_COMMON_DIR before the first repository config read so bare-state
+detection uses the same metadata location as discovery. Resolve relative
+environment values immediately so later working-directory changes cannot
+retarget the Repo.
+
+Review feedback: relative GIT_COMMON_DIR left Git subprocesses resolving GIT_DIR
+and GIT_COMMON_DIR from a different working directory; malformed commondir data,
+empty GIT_OBJECT_DIRECTORY, and the linked-worktree signature were also handled
+inconsistently.
+
+Pin the repository environment to resolved paths, reject invalid
+metadata without consulting the process working directory, and
+restore HEAD-based linked-worktree detection. Keep the loose HEAD
+and dangling .git behavior because both match Git setup.c at baseline
+15c6308cf7ad276b306aa5b3ababfbdebfb1a917.
+
+Review feedback identified that chained or self-referential .git pointers
+recurse, filesystem-encoded metadata can fail text decoding, and a relative
+GIT_DIR is not retained for later Git commands.
+
+Parse one regular, size-bounded Gitfile exactly once, decode Gitfile and
+commondir paths with the filesystem codec, and retain the resolved GIT_DIR
+for subprocesses. This rejects cycles like Git instead of recursing and keeps
+commands stable after working-directory changes.
+
+Review feedback noted that a dangling commondir symlink was treated as absent,
+allowing local objects and refs to validate the repository.
+
+Distinguish a truly missing commondir from a dangling symlink. This follows
+Git's get_common_dir_noenv(), whose file_exists check uses lstat before
+attempting to read the entry.
+
+Python 3.9 on Windows raised UnicodeDecodeError while the repository-discovery
+regression test parsed invalid commondir bytes, causing the Python package test
+(windows, 3.9) check to fail.
+
+Treat UnicodeError like an unreadable metadata file in both commondir and
+gitfile parsing. Invalid bytes now make discovery reject the candidate
+repository, matching Git's behavior.
+
+Review feedback noted that GIT_OBJECT_DIRECTORY made discovery succeed without
+becoming the Repo ODB root, while a relative value could later be resolved from
+the Git wrapper's different working directory.
+
+Resolve the environment value against the construction directory, use it as the
+ODB root, and preserve the absolute value for later Git commands. The regression
+moves the only object store outside the git directory and verifies access
+through both GitDB and git cat-file after the original environment and current
+directory are restored.
+
+Review feedback identified four setup mismatches: non-missing .git stat failures
+could fall through to another repository, explicit GIT_DIR could be redirected
+through a nested .git entry, Gitfile reads were not bounded to the stat-reported
+size, and alternates ignored GIT_OBJECT_DIRECTORY.
+
+Match Git setup.c by bypassing discovery for an environment-selected GIT_DIR,
+stopping discovery when Gitfile stat fails for reasons other than a missing
+path, and reading exactly the previously observed Gitfile size. Resolve
+alternates below the active ODB root so custom object stores remain internally
+consistent.
+
+The commit review noted that treating every present GIT_DIR as explicit broke
+two documented cases: an empty GIT_DIR must fall back to current-directory
+discovery, while an empty Repo path must still use a nonempty GIT_DIR.
+
+CVE: CVE-2026-87817
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/c7cf4d13b1ed0a2e70f2a1f3c6b4fc6c2652cf0b]
+
+Backport Changes:
+- Omitted doc/source/changes.rst because its upstream hunk is a
+ release-note entry; the file is present in the recipe PyPI archive.
+- Adapted the repository-discovery and environment-handling changes to
+ GitPython 3.1.43’s Repo.__init__ implementation. This includes its
+ linked-worktree and .git discovery flow, resolving and preserving
+ GIT_DIR/GIT_COMMON_DIR, and using GIT_OBJECT_DIRECTORY as the object
+ database root. These version-specific changes account for the difference
+ in git/repo/base.py from upstream; the alternates accessor changes are
+ part of that adaptation.
+- Added the standard-library re import in git/repo/fun.py because the
+ upstream re.match() call relies on an import from an earlier commit that
+ is absent from GitPython 3.1.43.
+- Omitted test/test_repo.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+ not run it.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit c7cf4d13b1ed0a2e70f2a1f3c6b4fc6c2652cf0b)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/repo/base.py | 91 +++++++++++++++++++++++++++++++--------------
+ git/repo/fun.py | 111 +++++++++++++++++++++++++++++++++++++-----------------
+ 2 files changed, 135 insertions(+), 67 deletions(-)
+
+diff --git a/git/repo/base.py b/git/repo/base.py
+index e3b10459..a5532ae5 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -45,7 +45,6 @@ Repo imports
+
+ from .fun import (
+ find_submodule_git_dir,
+- find_worktree_git_dir,
+ is_git_dir,
+ rev_parse,
+ touch,
+@@ -231,6 +230,10 @@ Repo.__init__ reftable note
+ ) -> None:
+ R"""Create a new :class:`Repo` instance.
+
++ .. note::
++ Repositories using reftable may be opened, but GitPython's direct reference
++ access does not support reftable.
++
+ :param path:
+ The path to either the root git directory or the bare git repo::
+
+@@ -265,7 +268,11 @@ Repo.__init__ environment paths
+ :class:`Repo`
+ """
+
+- epath = path or os.getenv("GIT_DIR")
++ git_dir_env = os.getenv("GIT_DIR")
++ object_dir_env = os.getenv("GIT_OBJECT_DIRECTORY")
++ if object_dir_env is not None:
++ object_dir_env = osp.abspath(object_dir_env)
++ epath = path or git_dir_env
+ if not epath:
+ epath = os.getcwd()
+ if Git.is_cygwin():
+@@ -289,15 +296,47 @@ Repo.__init__ repository discovery
+ raise NoSuchPathError(epath)
+
+ # Walk up the path to find the `.git` dir.
+- curpath = epath
+- git_dir = None
++ curpath = os.fspath(epath) if epath is not None else ""
++ git_dir: Optional[str] = None
++ explicit_git_dir = not path and bool(git_dir_env)
+ while curpath:
+ # ABOUT osp.NORMPATH
+ # It's important to normalize the paths, as submodules will otherwise
+ # initialize their repo instances with paths that depend on path-portions
+ # that will not exist after being removed. It's just cleaner.
++ if not explicit_git_dir:
++ dotgit = osp.join(curpath, ".git")
++ try:
++ sm_gitpath = find_submodule_git_dir(dotgit)
++ except OSError:
++ break
++ if sm_gitpath is not None:
++ # Worktrees can use relative paths as of Git 2.48, so join to curpath.
++ git_dir = osp.normpath(osp.join(curpath, os.fspath(sm_gitpath)))
++ self._working_tree_dir = curpath
++ break
++
++ # Like Git, do not fall back to a bare repository or parent directory when
++ # a non-directory .git entry exists but is not a valid gitfile.
++ if osp.exists(dotgit) and not osp.isdir(dotgit):
++ break
+ if is_git_dir(curpath):
+ git_dir = curpath
++ if osp.isfile(osp.join(curpath, "gitdir")) and osp.isfile(osp.join(curpath, "commondir")):
++ if "GIT_WORK_TREE" in os.environ:
++ self._working_tree_dir = os.getenv("GIT_WORK_TREE")
++ else:
++ # Linked worktree administrative directories store the path to
++ # the worktree's .git file in gitdir (without a "gitdir: " prefix).
++ with open(osp.join(git_dir, "gitdir")) as fp:
++ worktree_gitfile = fp.read().strip()
++
++ if not osp.isabs(worktree_gitfile):
++ worktree_gitfile = osp.normpath(osp.join(git_dir, worktree_gitfile))
++
++ self._working_tree_dir = osp.dirname(worktree_gitfile)
++ break
++
+ # from man git-config : core.worktree
+ # Set the path to the root of the working tree. If GIT_COMMON_DIR
+ # environment variable is set, core.worktree is ignored and not used for
+@@ -317,21 +356,7 @@ Repo.__init__ directory search
+ self._working_tree_dir = os.getenv("GIT_WORK_TREE")
+ break
+
+- dotgit = osp.join(curpath, ".git")
+- sm_gitpath = find_submodule_git_dir(dotgit)
+- if sm_gitpath is not None:
+- git_dir = osp.normpath(sm_gitpath)
+-
+- sm_gitpath = find_submodule_git_dir(dotgit)
+- if sm_gitpath is None:
+- sm_gitpath = find_worktree_git_dir(dotgit)
+-
+- if sm_gitpath is not None:
+- git_dir = expand_path(sm_gitpath, expand_vars)
+- self._working_tree_dir = curpath
+- break
+-
+- if not search_parent_directories:
++ if explicit_git_dir or not search_parent_directories:
+ break
+ curpath, tail = osp.split(curpath)
+ if not tail:
+@@ -342,6 +367,16 @@ Repo.__init__ common directory
+ raise InvalidGitRepositoryError(epath)
+ self.git_dir = git_dir
+
++ common_dir_env = os.getenv("GIT_COMMON_DIR")
++ if common_dir_env is not None:
++ self._common_dir = osp.abspath(common_dir_env)
++ else:
++ try:
++ common_dir = os.fsdecode((Path(self.git_dir) / "commondir").read_bytes()).rstrip("\r\n")
++ self._common_dir = osp.join(self.git_dir, common_dir)
++ except OSError:
++ self._common_dir = ""
++
+ self._bare = False
+ try:
+ self._bare = self.config_reader("repository").getboolean("core", "bare")
+@@ -349,12 +384,6 @@ Repo.__init__ bare-state detection
+ # Let's not assume the option exists, although it should.
+ pass
+
+- try:
+- common_dir = (Path(self.git_dir) / "commondir").read_text().splitlines()[0].strip()
+- self._common_dir = osp.join(self.git_dir, common_dir)
+- except OSError:
+- self._common_dir = ""
+-
+ # Adjust the working directory in case we are actually bare - we didn't know
+ # that in the first place.
+ if self._bare:
+@@ -363,9 +392,15 @@ Repo.__init__ Git environment and object database
+
+ self.working_dir: PathLike = self._working_tree_dir or self.common_dir
+ self.git = self.GitCommandWrapperType(self.working_dir)
++ if common_dir_env is not None:
++ self.git.update_environment(GIT_DIR=os.fspath(self.git_dir), GIT_COMMON_DIR=os.fspath(self.common_dir))
++ elif git_dir_env is not None:
++ self.git.update_environment(GIT_DIR=os.fspath(self.git_dir))
++ if object_dir_env is not None:
++ self.git.update_environment(GIT_OBJECT_DIRECTORY=object_dir_env)
+
+ # Special handling, in special times.
+- rootpath = osp.join(self.common_dir, "objects")
++ rootpath = object_dir_env if object_dir_env is not None else osp.join(self.common_dir, "objects")
+ if issubclass(odbt, GitCmdObjectDB):
+ self.odb = odbt(rootpath, self.git)
+ else:
+@@ -952,7 +987,7 @@ Repo._get_alternates
+ List of strings being pathnames of alternates
+ """
+ if self.git_dir:
+- alternates_path = osp.join(self.git_dir, "objects", "info", "alternates")
++ alternates_path = osp.join(self.odb.root_path(), "info", "alternates")
+
+ if osp.exists(alternates_path):
+ with open(alternates_path, "rb") as f:
+@@ -973,7 +1008,7 @@ Repo._set_alternates
+ The method does not check for the existence of the paths in `alts`, as the
+ caller is responsible.
+ """
+- alternates_path = osp.join(self.common_dir, "objects", "info", "alternates")
++ alternates_path = osp.join(self.odb.root_path(), "info", "alternates")
+ if not alts:
+ if osp.isfile(alternates_path):
+ os.remove(alternates_path)
+
+diff --git a/git/repo/fun.py b/git/repo/fun.py
+index e44d9c64..30c30ebb 100644
+--- a/git/repo/fun.py
++++ b/git/repo/fun.py
+@@ -20,5 +20,6 @@ standard-library imports
+ import os
+ import os.path as osp
++import re
+ from pathlib import Path
+ import stat
+ from string import digits
+@@ -57,22 +58,61 @@ is_git_dir repository validation
+ def is_git_dir(d: PathLike) -> bool:
+ """This is taken from the git setup.c:is_git_directory function.
+
++ .. note::
++ This function recognizes repositories using reftable through their
++ compatibility files, but GitPython's direct reference access does not support
++ reftable.
++
+ :raise git.exc.WorkTreeRepositoryUnsupported:
+ If it sees a worktree directory. It's quite hacky to do that here, but at least
+ clearly indicates that we don't support it. There is the unlikely danger to
+ throw if we see directories which just look like a worktree dir, but are none.
+ """
+ if osp.isdir(d):
+- if (osp.isdir(osp.join(d, "objects")) or "GIT_OBJECT_DIRECTORY" in os.environ) and osp.isdir(
+- osp.join(d, "refs")
+- ):
+- headref = osp.join(d, "HEAD")
+- return osp.isfile(headref) or (osp.islink(headref) and os.readlink(headref).startswith("refs"))
+- elif (
+- osp.isfile(osp.join(d, "gitdir"))
+- and osp.isfile(osp.join(d, "commondir"))
+- and osp.isfile(osp.join(d, "gitfile"))
+- ):
++ headref = osp.join(d, "HEAD")
++ if osp.islink(headref):
++ try:
++ valid_head = os.readlink(headref).startswith("refs/")
++ except OSError:
++ valid_head = False
++ else:
++ try:
++ with open(headref, "rb") as fp:
++ head = fp.read(256)
++ except OSError:
++ valid_head = False
++ else:
++ valid_head = (head.startswith(b"ref:") and head[4:].lstrip().startswith(b"refs/")) or bool(
++ re.match(rb"(?:[0-9A-Fa-f]{64}|[0-9A-Fa-f]{40})", head)
++ )
++
++ common_dir = os.getenv("GIT_COMMON_DIR")
++ if common_dir == "":
++ return False
++ if common_dir is None:
++ common_dir_file = Path(d) / "commondir"
++ try:
++ common_dir = os.fsdecode(common_dir_file.read_bytes()).rstrip("\r\n")
++ except FileNotFoundError:
++ if osp.lexists(common_dir_file):
++ return False
++ common_dir = os.fspath(d)
++ except (OSError, UnicodeError):
++ return False
++ else:
++ if not common_dir:
++ return False
++ try:
++ common_dir = osp.realpath(osp.join(d, common_dir))
++ except (OSError, ValueError):
++ return False
++
++ object_dir = os.getenv("GIT_OBJECT_DIRECTORY")
++ if object_dir is None:
++ object_dir = osp.join(common_dir, "objects")
++ if valid_head and osp.isdir(object_dir) and osp.isdir(osp.join(common_dir, "refs")):
++ return True
++ if osp.isfile(osp.join(d, "gitdir")) and osp.isfile(osp.join(d, "commondir")) and osp.isfile(headref):
+ raise WorkTreeRepositoryUnsupported(d)
+ return False
+
+@@ -81,19 +121,20 @@ find_worktree_git_dir bounded Gitfile parsing
+ """Search for a gitdir for this worktree."""
+ try:
+ statbuf = os.stat(dotgit)
+- except OSError:
++ except (FileNotFoundError, NotADirectoryError):
+ return None
+- if not stat.S_ISREG(statbuf.st_mode):
++ if not stat.S_ISREG(statbuf.st_mode) or statbuf.st_size > (1 << 20):
+ return None
+
+ try:
+- lines = Path(dotgit).read_text().splitlines()
+- for key, value in [line.strip().split(": ") for line in lines]:
+- if key == "gitdir":
+- return value
+- except ValueError:
+- pass
+- return None
++ with open(dotgit, "rb") as fp:
++ content_bytes = fp.read(statbuf.st_size)
++ if len(content_bytes) != statbuf.st_size:
++ return None
++ content = os.fsdecode(content_bytes).rstrip("\r\n")
++ except (OSError, UnicodeError):
++ return None
++ return content[8:] if len(content) >= 9 and content.startswith("gitdir: ") else None
+
+
+ def find_submodule_git_dir(d: PathLike) -> Optional[PathLike]:
+@@ -101,26 +142,18 @@ find_submodule_git_dir validated Gitfile resolution
+ if is_git_dir(d):
+ return d
+
+- try:
+- with open(d) as fp:
+- content = fp.read().rstrip()
+- except IOError:
+- # It's probably not a file.
+- pass
+- else:
+- if content.startswith("gitdir: "):
+- path = content[8:]
+-
+- if Git.is_cygwin():
+- # Cygwin creates submodules prefixed with `/cygdrive/...` suffixes.
+- # Cygwin git understands Cygwin paths much better than Windows ones.
+- # Also the Cygwin tests are assuming Cygwin paths.
+- path = cygpath(path)
+- if not osp.isabs(path):
+- path = osp.normpath(osp.join(osp.dirname(d), path))
+- return find_submodule_git_dir(path)
+- # END handle exception
+- return None
++ path = find_worktree_git_dir(d)
++ if path is None:
++ return None
++
++ if Git.is_cygwin():
++ # Cygwin creates submodules prefixed with `/cygdrive/...`.
++ # Cygwin git understands Cygwin paths much better than Windows ones.
++ # Also the Cygwin tests are assuming Cygwin paths.
++ path = cygpath(path)
++ if not osp.isabs(path):
++ path = osp.normpath(osp.join(osp.dirname(d), path))
++ return path if is_git_dir(path) else None
+
+
+ def short_to_long(odb: "GitCmdObjectDB", hexsha: str) -> Optional[bytes]:
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 0dd42e1f04..558846a950 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -48,6 +48,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-78677.patch \
file://CVE-2026-78676.patch \
file://CVE-2026-78675.patch \
+ file://CVE-2026-87817.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 25/27] python3-git: fix CVE-2026-87818
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (23 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 24/27] python3-git: fix CVE-2026-87817 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 26/27] python3-git: Fix CVE-2026-87819 Yogita Urade
` (2 subsequent siblings)
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/09f2cf383a992d1af697364569e9f384748c1bd8
[2] https://security-tracker.debian.org/tracker/CVE-2026-87818
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Added the omitted doc/source/changes.rst release-note change to
Backport Changes.
---
.../python/python3-git/CVE-2026-87818.patch | 55 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 56 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch
new file mode 100644
index 0000000000..0e78580651
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch
@@ -0,0 +1,55 @@
+From 6b83f54db287f190ae29c89b36ba6aba01f7c8d6 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Mon, 17 Aug 2026 06:15:12 +0200
+Subject: [PATCH] fix: require opt-in for no-index diffs
+
+<!-- agent -->
+Treat --no-index as an unsafe diff option because it changes path operands
+from repository pathspecs to arbitrary filesystem paths. This addresses
+GHSA-whh4-5q6c-9v3x without exposing advisory reproduction details.
+
+CVE: CVE-2026-87818
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/09f2cf383a992d1af697364569e9f384748c1bd8]
+
+Backport Changes:
+- Omitted test/test_diff.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does
+- Omitted doc/source/changes.rst file changes.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 09f2cf383a992d1af697364569e9f384748c1bd8)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/diff.py | 4 ++--
+ git/repo/base.py | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/git/diff.py b/git/diff.py
+index 032dfb25..08bd4410 100644
+--- a/git/diff.py
++++ b/git/diff.py
+@@ -216,8 +216,8 @@ class Diffable:
+ to be read and diffed.
+
+ :param allow_unsafe_options:
+- If ``True``, allow options such as ``--output`` and ``-O`` that can write to
+- or read from arbitrary filesystem paths.
++ If ``True``, allow options such as ``--output``, ``--no-index``, and ``-O``
++ that can write to or read from arbitrary filesystem paths.
+
+ :param kwargs:
+ Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to
+diff --git a/git/repo/base.py b/git/repo/base.py
+index 7543e3cc..f2dca3c7 100644
+--- a/git/repo/base.py
++++ b/git/repo/base.py
+@@ -203,6 +203,8 @@ class Repo:
+ ]
+
+ unsafe_git_diff_options = unsafe_git_revision_options + [
++ # Treats path operands as arbitrary filesystem paths.
++ "--no-index",
+ # Reads caller-controlled order patterns from an arbitrary file.
+ "-O",
+ "--orderfile",
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 558846a950..efd17b45c4 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -49,6 +49,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-78676.patch \
file://CVE-2026-78675.patch \
file://CVE-2026-87817.patch \
+ file://CVE-2026-87818.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 26/27] python3-git: Fix CVE-2026-87819
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (24 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 25/27] python3-git: fix CVE-2026-87818 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 27/27] python3-git: fix CVE-2026-100689 Yogita Urade
2026-11-14 0:16 ` [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yoann Congal
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [3],
using the commit shown in [1] and [2].
[1] https://github.com/gitpython-developers/GitPython/commit/751473a5f3221d6f989291cbebcc404353fd3ba8
[2] https://github.com/gitpython-developers/GitPython/commit/bc63b027e2fc737e2ec0222bfa764e1aa76a427f
[3] https://security-tracker.debian.org/tracker/CVE-2026-87819
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Added the omitted release-note change to p1. In p2, restored comments
identifying the Actor.from_string and review-follow-up changes, and
moved the Co-authored-by trailer into the commit-message trailer block.
---
.../python3-git/CVE-2026-87819_p1.patch | 78 ++++++++++
.../python3-git/CVE-2026-87819_p2.patch | 146 ++++++++++++++++++
.../python/python3-git_3.1.43.bb | 2 +
3 files changed, 226 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch
new file mode 100644
index 0000000000..8d5566c19c
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch
@@ -0,0 +1,78 @@
+From 47e0d430af6885ceeaa38a8c5517efac872b70b4 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 11 Aug 2026 14:18:25 +0200
+Subject: [PATCH] fix: parse actor identities without regular expressions
+
+<!-- agent -->
+GHSA-g5vv-9gxw-82hx reports quadratic backtracking when an actor
+identity contains a long unterminated email delimiter.
+
+Add a regression that exercises a 20,000-character malformed identity,
+then replace both actor regexes with direct delimiter scans following
+Git's first-opening, first-closing delimiter behavior. Keep GitPython's
+whole-string fallback when either delimiter is absent.
+
+Reference Git baseline cf5497b14c5a24f10c13f7e0ee85cb95
+ident.c::split_ident_line and its invalid-committer cases in
+t/t9300-fast-import.sh. Also reference gix-actor's signature decoder and
+lenient identity tests.
+
+CVE: CVE-2026-87819
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/751473a5f3221d6f989291cbebcc404353fd3ba8]
+
+Backport Changes:
+- Omitted test/test_actor.py because the current PyPI source
+ archive does not include the test suite and the python3-git
+ recipe does not run it.
+- Omitted doc/source/changes.rst file changes.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 751473a5f3221d6f989291cbebcc404353fd3ba8)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/util.py | 24 ++++++++----------------
+ 1 file changed, 8 insertions(+), 16 deletions(-)
+
+diff --git a/git/util.py b/git/util.py
+index 9619937c..9a698e6d 100644
+--- a/git/util.py
++++ b/git/util.py
+@@ -772,10 +772,6 @@ class Actor:
+ committers and authors or anything with a name and an email as mentioned in the git
+ log entries."""
+
+- # PRECOMPILED REGEX
+- name_only_regex = re.compile(r"<(.*)>")
+- name_email_regex = re.compile(r"(.*) <(.*?)>")
+-
+ # ENVIRONMENT VARIABLES
+ # These are read when creating new commits.
+ env_author_name = "GIT_AUTHOR_NAME"
+@@ -820,18 +816,14 @@ class Actor:
+ :return:
+ :class:`Actor`
+ """
+- m = cls.name_email_regex.search(string)
+- if m:
+- name, email = m.groups()
+- return Actor(name, email)
+- else:
+- m = cls.name_only_regex.search(string)
+- if m:
+- return Actor(m.group(1), None)
+- # Assume the best and use the whole string as name.
+- return Actor(string, None)
+- # END special case name
+- # END handle name/email matching
++ line = string.partition("\n")[0]
++ left_bracket = line.find("<")
++ right_bracket = line.find(">", left_bracket + 1)
++ if left_bracket >= 0 and right_bracket >= 0:
++ return Actor(line[:left_bracket].rstrip(), line[left_bracket + 1 : right_bracket])
++
++ # Assume the best and use the whole string as name.
++ return Actor(string, None)
+
+ @classmethod
+ def _main_actor(
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch
new file mode 100644
index 0000000000..cf5d931830
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch
@@ -0,0 +1,146 @@
+From 0d63f66a673cfcad25a1fd85f56177d19a1b6547 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Fri, 28 Aug 2026 08:37:50 +0200
+Subject: [PATCH] fix: restore Actor.name_email_regex (#2220)
+
+<!-- agent -->
+GitPython 3.1.60 removed the Actor.name_email_regex class attribute while
+replacing internal actor parsing, which broke downstream consumers such as
+python-semantic-release.
+
+Bring back the historical compiled pattern for downstream compatibility,
+but emit DeprecationWarning whenever the class member is accessed. The warning
+explains its quadratic behavior on long malformed strings and points callers to
+the public Actor(name, email) constructor when fields are separate, or direct
+string parsing when they are not.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+
+# 252a84ac Add public Actor.from_string constructor (#2220)
+
+Add public Actor.from_string constructor (#2220)
+
+Promote the existing actor identity parser to Actor.from_string while retaining _from_string as a compatibility alias. Point the name_email_regex deprecation warning to the new public constructor or Actor(name, email).
+
+Validation:
+- actor-related test/test_actor.py and test/test_util.py cases: 12 passed
+- ruff check and format checks passed
+- basedpyright git/util.py: no errors
+
+Co-authored-by: Codex GPT-5 <codex@openai.com>
+
+# dd2181d8 Address review feedback about Actor subclasses
+
+Address review feedback about Actor subclasses
+
+Review feedback: Actor.from_string() should preserve the class on which the public classmethod is called instead of always returning a base Actor.
+
+Construct through cls on both parsing paths and cover subclass construction directly.
+
+Validation:
+- actor-related test/test_actor.py and test/test_util.py cases: 13 passed
+- ruff check and format checks passed
+- basedpyright git/util.py: no errors
+
+# fcf1ecb1 Address review feedback about constructor typing
+
+Address review feedback about constructor typing
+
+Review feedback: Actor.from_string() constructs subclasses at runtime but its Actor return annotation prevents type checkers from preserving subclass-specific members.
+
+Use the project existing Python 3.7-compatible bound TypeVar pattern so the declared return type follows cls.
+
+Validation:
+- actor-related test/test_actor.py and test/test_util.py cases: 13 passed
+- ruff check and format checks passed
+- basedpyright git/util.py: no errors
+
+Co-authored-by: Codex GPT-5 <codex@openai.com>
+
+CVE: CVE-2026-87819
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/bc63b027e2fc737e2ec0222bfa764e1aa76a427f]
+
+Backport Changes:
+- Omitted test/test_actor.py because the current PyPI source archive
+ does not include the test suite and the python3-git recipe does not
+ run it.
+
+(cherry picked from commit bc63b027e2fc737e2ec0222bfa764e1aa76a427f)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/util.py | 26 +++++++++++++++++++++++---
+ 1 file changed, 23 insertions(+), 3 deletions(-)
+
+diff --git a/git/util.py b/git/util.py
+index 9a698e6d..16cd25ef 100644
+--- a/git/util.py
++++ b/git/util.py
+@@ -80,6 +80,7 @@ from typing import (
+ Sequence,
+ Tuple,
+ TYPE_CHECKING,
++ Type,
+ TypeVar,
+ Union,
+ cast,
+@@ -108,6 +109,7 @@ from git.types import (
+
+ T_IterableObj = TypeVar("T_IterableObj", bound=Union["IterableObj", "Has_id_attribute"], covariant=True)
+ # So IterableList[Head] is subtype of IterableList[IterableObj].
++T_Actor = TypeVar("T_Actor", bound="Actor")
+
+ _logger = logging.getLogger(__name__)
+
+@@ -767,11 +769,27 @@ class CallableRemoteProgress(RemoteProgress):
+ self._callable(*args, **kwargs)
+
+
++class _DeprecatedActorNameEmailRegex:
++ _pattern = re.compile(r"(.*) <(.*?)>")
++
++ def __get__(self, _instance: Any, _owner: Any) -> Pattern[str]:
++ warnings.warn(
++ "Actor.name_email_regex is deprecated and will be removed in GitPython 4.0.0 because searching long "
++ "malformed strings with it can take quadratic time. Use Actor.from_string() to parse actor identities, "
++ "or Actor(name, email) when the fields are already separate.",
++ DeprecationWarning,
++ stacklevel=2,
++ )
++ return self._pattern
++
++
+ class Actor:
+ """Actors hold information about a person acting on the repository. They can be
+ committers and authors or anything with a name and an email as mentioned in the git
+ log entries."""
+
++ name_email_regex = _DeprecatedActorNameEmailRegex()
++
+ # ENVIRONMENT VARIABLES
+ # These are read when creating new commits.
+ env_author_name = "GIT_AUTHOR_NAME"
+@@ -805,7 +823,7 @@ class Actor:
+ return '<git.Actor "%s <%s>">' % (self.name, self.email)
+
+ @classmethod
+- def _from_string(cls, string: str) -> "Actor":
++ def from_string(cls: Type[T_Actor], string: str) -> T_Actor:
+ """Create an :class:`Actor` from a string.
+
+ :param string:
+@@ -820,10 +838,12 @@ class Actor:
+ left_bracket = line.find("<")
+ right_bracket = line.find(">", left_bracket + 1)
+ if left_bracket >= 0 and right_bracket >= 0:
+- return Actor(line[:left_bracket].rstrip(), line[left_bracket + 1 : right_bracket])
++ return cls(line[:left_bracket].rstrip(), line[left_bracket + 1 : right_bracket])
+
+ # Assume the best and use the whole string as name.
+- return Actor(string, None)
++ return cls(string, None)
++
++ _from_string = from_string
+
+ @classmethod
+ def _main_actor(
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index efd17b45c4..1c77341132 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -50,6 +50,8 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-78675.patch \
file://CVE-2026-87817.patch \
file://CVE-2026-87818.patch \
+ file://CVE-2026-87819_p1.patch \
+ file://CVE-2026-87819_p2.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [OE-core][wrynose][v2 PATCH 27/27] python3-git: fix CVE-2026-100689
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (25 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 26/27] python3-git: Fix CVE-2026-87819 Yogita Urade
@ 2026-11-06 14:43 ` Yogita Urade
2026-11-14 0:16 ` [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yoann Congal
27 siblings, 0 replies; 29+ messages in thread
From: Yogita Urade @ 2026-11-06 14:43 UTC (permalink / raw)
To: openembedded-core
This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].
[1] https://github.com/gitpython-developers/GitPython/commit/1ed0ebc2f2e74d979cdc367a4864a7731fdcc093
[2] https://security-tracker.debian.org/tracker/CVE-2026-100689
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
Changes in v2:
- Changed the advisory reference from NVD to Debian Security Tracker.
Rewrote Backport Changes to explain that the GitPython 3.1.43
adaptation normalizes root and candidate paths and enforces containment
with commonpath.
---
.../python/python3-git/CVE-2026-100689.patch | 91 +++++++++++++++++++
.../python/python3-git_3.1.43.bb | 1 +
2 files changed, 92 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch
diff --git a/meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch b/meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch
new file mode 100644
index 0000000000..807d97dcfc
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch
@@ -0,0 +1,91 @@
+From 1ed0ebc2f2e74d979cdc367a4864a7731fdcc093 Mon Sep 17 00:00:00 2001
+From: Byron <sebastian.thiel@icloud.com>
+Date: Tue, 1 Sep 2026 11:33:19 +0200
+Subject: [PATCH] Reject submodule checkout paths outside the repository
+
+GHSA-59cr-6r3x-644w identifies that submodule update paths could reach
+filesystem operations without the containment check already used by add and
+move.
+
+Add a regression that proves update rejects a parent-directory checkout
+path before cloning, and override Submodule.abspath to apply the shared
+_to_relative_path guard for every filesystem consumer.
+
+Git baseline: git.git read-cache.c verify_path_internal() rejects invalid index
+paths, covered for parent traversal by t/t9300-fast-import.sh.
+
+CVE: CVE-2026-100689
+Upstream-Status: Backport [https://github.com/gitpython-developers/GitPython/commit/1ed0ebc2f2e74d979cdc367a4864a7731fdcc093]
+
+Backport Changes:
+- Adapted _to_relative_path for 3.1.43: normalize root and candidate paths
+ and enforce containment with commonpath, replacing the old prefix check
+ that allowed relative .. traversal. This extra validation is not in the
+ upstream hunk, which adds the Submodule.abspath override.
+- Omitted doc/source/changes.rst because it only records the release note.
+- Omitted test/test_submodule.py because the PyPI source archive does not
+ include the test suite.
+
+Assisted-by: GPT 5.6
+Co-authored-by: GPT 5.6 <codex@openai.com>
+(cherry picked from commit 1ed0ebc2f2e74d979cdc367a4864a7731fdcc093)
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ git/objects/submodule/base.py | 46 +++++++++++++++++++++++++++++------------
+ 1 file changed, 33 insertions(+), 13 deletions(-)
+
+--- a/git/objects/submodule/base.py
++++ b/git/objects/submodule/base.py
+@@ -400,19 +400,39 @@
+ path = path[:-1]
+ # END handle trailing slash
+
+- if osp.isabs(path) and parent_repo.working_tree_dir:
+- working_tree_linux = to_native_path_linux(parent_repo.working_tree_dir)
+- if not path.startswith(working_tree_linux):
+- raise ValueError(
+- "Submodule checkout path '%s' needs to be within the parents repository at '%s'"
+- % (working_tree_linux, path)
+- )
+- path = path[len(working_tree_linux.rstrip("/")) + 1 :]
+- if not path:
+- raise ValueError("Absolute submodule path '%s' didn't yield a valid relative path" % path)
+- # END verify converted relative path makes sense
+- # END convert to a relative path
+-
++ root = parent_repo.working_tree_dir
++ if root:
++ drive, tail = osp.splitdrive(path)
++ separators = (os.sep,) if os.altsep is None else (os.sep, os.altsep)
++ if drive and not tail.startswith(separators):
++ raise ValueError("Drive-relative path %r is not supported" % path)
++
++ root_abs = osp.abspath(to_native_path_linux(root))
++ path_abs = osp.abspath(osp.join(root_abs, path))
++ try:
++ common_path = osp.commonpath([root_abs, path_abs])
++ except ValueError as e:
++ raise ValueError("Submodule checkout path %r is not in repository at %r" % (path, root_abs)) from e
++ if osp.normcase(common_path) != osp.normcase(root_abs):
++ raise ValueError("Submodule checkout path %r is not in repository at %r" % (path, root_abs))
++
++ path = to_native_path_linux(osp.relpath(path_abs, root_abs))
++
++ if not path or path == ".":
++ raise ValueError("Submodule checkout path must not be the repository root")
++
++ return path
++
++ @property
++ def abspath(self) -> PathLike:
++ root = self.repo.working_tree_dir
++ if root is None:
++ return super().abspath
++ path = root
++ for component in self._to_relative_path(self.repo, self.path).split("/"):
++ path = join_path_native(path, component)
++ if osp.islink(path):
++ raise ValueError("Submodule checkout path %r contains a symbolic link" % self.path)
+ return path
+
+ @classmethod
diff --git a/meta/recipes-devtools/python/python3-git_3.1.43.bb b/meta/recipes-devtools/python/python3-git_3.1.43.bb
index 1c77341132..170fe989d9 100644
--- a/meta/recipes-devtools/python/python3-git_3.1.43.bb
+++ b/meta/recipes-devtools/python/python3-git_3.1.43.bb
@@ -52,6 +52,7 @@ SRC_URI += "file://CVE-2026-42284.patch \
file://CVE-2026-87818.patch \
file://CVE-2026-87819_p1.patch \
file://CVE-2026-87819_p2.patch \
+ file://CVE-2026-100689.patch \
"
SRC_URI[sha256sum] = "35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
` (26 preceding siblings ...)
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 27/27] python3-git: fix CVE-2026-100689 Yogita Urade
@ 2026-11-14 0:16 ` Yoann Congal
27 siblings, 0 replies; 29+ messages in thread
From: Yoann Congal @ 2026-11-14 0:16 UTC (permalink / raw)
To: yurade, openembedded-core
On Fri Nov 6, 2026 at 3:43 PM CET, Yogita Urade -X (yurade - E INFOCHIPS PRIVATE LIMITED at Cisco) via openembedded-core wrote:
> Backport 27 GitPython security fixes covering 28 CVEs to the python3-git
> 3.1.43 recipe on wrynose. The series adds the fixes as patches and updates
> the recipe to apply them.
>
> CVE-2026-78678 and CVE-2026-78679 are addressed together. The CVE-2026-76222
> fix includes a regression correction and follow-up patch, CVE-2026-73619
> and CVE-2026-87819 are each carried in two patches. The patches retain
> upstream references.
>
> Changes in v2:
> - Re-reviewed all patches and removed changes that were not needed for the backports.
> - Restored upstream commit metadata and corrected CVE references.
> - Updated Backport Changes notes to describe the differences from upstream.
Hello,
> - Removed trailing whitespace and regenerated the series diffstat.
I think you should not have done this last change. Some whitespaces at
end of line are actually meaningful in the patch format (e.g. an empty
context line) also, upstream patches will have these whitespace,
removing those will add noise when I take the diff.
To help you clean this, here is the script I use to check patch format:
https://gist.github.com/ycongal-smile/3692790a48269e59d602e5be1d667982
Here is its full log on your series:
❯ git diff --numstat 63484d666ac 802fb424a4e |cut -f3 | grep "\.patch$" |xargs check_patch.py
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch:42
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-100689.patch:90
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch:47
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73619_p1.patch:57
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch:41
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch:50
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73621.patch:54
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch:41
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73622.patch:45
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:40
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:49
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:65
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:92
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:132
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-73624.patch:136
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch:50
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76218.patch:73
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:48
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:71
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:74
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:78
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:88
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:91
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:96
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p1.patch:104
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-76222_p2.patch:36
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch:42
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-78675.patch:45
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch:51
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch:57
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-78676.patch:66
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch:34
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch:40
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87818.patch:49
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch:44
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p1.patch:76
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:88
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:92
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:94
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:97
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:98
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:117
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:125
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:130
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:138
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Error: Malformed patch line at meta/recipes-devtools/python/python3-git/CVE-2026-87819_p2.patch:144
Line content: '\n'
Context lines must start with exactly one space. This line is missing its prefix.
Regards,
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2026-11-14 0:16 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-06 14:43 [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 01/27] python3-git: fix CVE-2026-67326 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 02/27] python3-git: fix CVE-2026-67323 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 03/27] python3-git: Fix CVE-2026-67325 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 04/27] python3-git: fix CVE-2026-67324 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 05/27] python3-git: fix CVE-2026-67322 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 06/27] python3-git: fix CVE-2026-69097 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 07/27] python3-git: fix CVE-2026-73625 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 08/27] python3-git: fix CVE-2026-73623 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 09/27] python3-git: fix CVE-2026-73624 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 10/27] python3-git: fix CVE-2026-73622 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 11/27] python3-git: fix CVE-2026-73621 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 12/27] python3-git: fix CVE-2026-73620 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 13/27] python3-git: fix CVE-2026-73619 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 14/27] python3-git: fix CVE-2026-76221 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 15/27] python3-git: fix CVE-2026-76220 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 16/27] python3-git: fix CVE-2026-76219 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 17/27] python3-git: fix CVE-2026-76218 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 18/27] python3-git: fix CVE-2026-76217 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 19/27] python3-git: fix CVE-2026-76222 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 20/27] python3-git: fix CVE-2026-78678 CVE-2026-78679 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 21/27] python3-git: fix CVE-2026-78677 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 22/27] python3-git: fix CVE-2026-78676 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 23/27] python3-git: fix CVE-2026-78675 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 24/27] python3-git: fix CVE-2026-87817 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 25/27] python3-git: fix CVE-2026-87818 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 26/27] python3-git: Fix CVE-2026-87819 Yogita Urade
2026-11-06 14:43 ` [OE-core][wrynose][v2 PATCH 27/27] python3-git: fix CVE-2026-100689 Yogita Urade
2026-11-14 0:16 ` [OE-core][wrynose][v2 PATCH 00/27] python3-git: Security fixes Yoann Congal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox