From patchwork Sat Jun 13 10:11:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 90003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BE2ECD8CA8 for ; Sat, 13 Jun 2026 10:12:02 +0000 (UTC) Received: from rcdn-iport-9.cisco.com (rcdn-iport-9.cisco.com [173.37.86.80]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.88523.1781345511849188942 for ; Sat, 13 Jun 2026 03:11:52 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=idcsaqqC; spf=pass (domain: cisco.com, ip: 173.37.86.80, mailfrom: sudumbha@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=7866; q=dns/txt; s=iport01; t=1781345511; x=1782555111; h=from:to:subject:date:message-id:mime-version: content-transfer-encoding; bh=Qw1ygc1Ax8ChptdZifD6LzZCKoitMqP3o+rxW3eNXsE=; b=idcsaqqCNXKIbpS/4yoaD/bgqYp5ibJTEbRy+QOtoHMNzcm0MEKDXLqN UpfLkfgmaPPQrB5qZDzjqqxJkjt7EpwldxhTZpyCTmdM3t1p95YfsuYbh P0F0GRTkiunIYoLaH0nEfllg38cVffa79j5V2/Y0xI1nLv48LR3HpZWdD 5dh3pPhEmgF38hHnzDfjN+FhVvp+EfezlxK4a8ZeRwbOmIe4Wo89zC+Wg WzyrswBxTbmRm/sNhpRlw/+hFi4b3l6kZvaMB+6alnDtMBD30cMZBaWHf SOZ91xr0+9xgyOxW3WCqRgNc1LC1Rw+xwSUymXa3H3v6m5KJAsGXw6bBU g==; X-CSE-ConnectionGUID: Q8hLzV+aR3yxrAPdLH1jmw== X-CSE-MsgGUID: xfguodTKQqyw31chLykR7Q== X-IPAS-Result: A0BGAgBaKy1q/5D/Ja1aglmCV3RfQkkDlCeCIYtnkjeBfg8BAQEPRA0EAQGEQI4LAiY0CQ4BAgQDAgMBAQEBAQEBAQEBAQsBAQUBAQECAQcFgQ4Thk8NhloBLQsBGAFZAwECTwsjIQkRgmgBgjoDNgIBEbNegXkzgQGDKAExBQkCQ1DYSQ2CVgELDQIFAYE4gyCCH4J8hSNbGAGEfCcbG4FygRWDaYEFgRpCAQGBN4ZuBIINFYEMgV0ehDmKZEiBHgNZLAFVEw0KCwcFgWYDNRIqFW4yHYEjPheBDBsHBYFKgStqgQSFDSMfAzl/gXOBKGdnFTA1gQIRHwocAwsYDUgRLDcUGwQ+bgeMXRcPgUxyPSYrASoBFwkvMIEtEQ2lWKAecQoog3WMIY8+hXwaM4QEgVelEZkIglmLMYQJkkeEaIFoPIFHCwdwFYMiCUoZD444g2uBf4MUUcEqJDUCCQMvAQEHAgcOAwuBaJAAAiYHgU4BAQ IronPort-Data: A9a23:4I+xpquLWirYKTmnu99m/zyutOfnVAdfMUV32f8akzHdYApBsoF/q tZmKWrXaKqDZWL1f9B0OY3jp0tU7MLdnNZnHgI9+y1mFn9HgMeUXt7xwmUckM+xwmwvaGo9s q3yv/GZdJhcokf0/0nrav666yEgiclkf5KkYMbcICd9WAR4fykojBNnioYRj5Vh6TSDK1vlV eja/YuFZDdJ5xYuajhKs/za80s21BjPkGpwUmIWNKgjUGD2zxH5PLpHTYmtIn3xRJVjH+LSb 47r0LGj82rFyAwmA9Wjn6yTWhVirmn6ZFXmZtJ+AsBOszAazsAA+v9T2Mk0NS+7vw60c+VZk 72hg3AfpTABZcUgkMxFO/VR/roX0aduoNcrKlDn2SCfItGvn3bEm51T4E8K0YIww7Z3JXNwt vUicyEddDm7i8aWmbC+Vbw57igjBJGD0II3oHpsy3TdSP0hW52GG/qM7t5D1zB2jcdLdRrcT 5NGMnw0M1KaPkAJYwtLYH49tL/Aan3XaCBUtVefpaMf6GnIxws327/oWDbQUoDbHpwNzxjI+ goq+UzpDB4HM9Cj6gOc42333+TPuTL4Yt0rQejQGvlCxQf7KnYoIBoOWF22pPO0hkKzV5dUL FYZ0i4vtrQpskuzQ9/wWhe1rHKJslgbQdU4LgEhwBuGxqyR50OSAXIJC2YeLtcnr8QxAzct0 zdlgu/UONCmi5XNIVr1y1tehWra1fQ9RYPaWRI5cA== IronPort-HdrOrdr: A9a23:SkR1Jqu0QrsnVwgVCflrQgjS7skDRtV00zEX/kB9WHVpm6uj5q KTdZsguyMc5Ax9ZJhCo6HiBED/exLhHPdOiOF7V4tKNzOIhILHFu1fBPPZowHIKmnZ6vNX07 tmfuxVDd39CkU/sOPBiTPIdurJBLK8gceVbSC09QYIcT1X X-Talos-CUID: 9a23:CEswtmjxw+e16pDQmNDL06s1KzJuSy3d6GXuYEaCUnd5UpStRXuwoaFhjJ87 X-Talos-MUID: 9a23:vF101giWBmOXj5oVG5lgG8MpJMln/qOiNGM0iIQZ4JCPNQhhOA3CtWHi X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.24,202,1774310400"; d="scan'208";a="493109684" Received: from rcdn-l-core-07.cisco.com ([173.37.255.144]) by rcdn-iport-9.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 13 Jun 2026 10:11:50 +0000 Received: from sjc-ads-12007.cisco.com (sjc-ads-12007.cisco.com [171.70.97.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by rcdn-l-core-07.cisco.com (Postfix) with ESMTPS id A4D7A18000229 for ; Sat, 13 Jun 2026 10:11:50 +0000 (GMT) Received: by sjc-ads-12007.cisco.com (Postfix, from userid 1840713) id 4B5E3CB6A93; Sat, 13 Jun 2026 03:11:50 -0700 (PDT) From: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-core@lists.openembedded.org Subject: [OE-core][scarthgap][PATCH 1/4] python3: Fix CVE-2026-3644 and CVE-2026-0672 Date: Sat, 13 Jun 2026 03:11:35 -0700 Message-Id: <20260613101137.3690080-1-sudumbha@cisco.com> X-Mailer: git-send-email 2.35.6 MIME-Version: 1.0 X-Outbound-Client-TLS: VERIFIED;sjc-ads-12007.cisco.com [171.70.97.7];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 171.70.97.7, sjc-ads-12007.cisco.com X-Outbound-Node: rcdn-l-core-07.cisco.com List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 13 Jun 2026 10:12:02 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/238667 From: Sudhir Dumbhare Apply the upstream v3.13 fix [1], as referenced in [2], to address CVE-2026-3644 by rejecting control characters in http.cookies.Morsel.update(), the |= operator, and unpickling paths. CVE-2026-3644 [2] revealed the CVE-2026-0672 fix was incomplete, as Morsel.update(), |=, and unpickling could bypass input validation. The fix also adds output validation to BaseCookie.js_output(), matching the control-character safeguards already present in BaseCookie.output(). [1] https://github.com/python/cpython/commit/d16ecc6c3626f0e2cc8f08c309c83934e8a979dd [2] https://security-tracker.debian.org/tracker/CVE-2026-3644 References: https://security-tracker.debian.org/tracker/CVE-2026-3644 https://security-tracker.debian.org/tracker/CVE-2026-0672 https://nvd.nist.gov/vuln/detail/CVE-2026-3644 https://nvd.nist.gov/vuln/detail/CVE-2026-0672 Signed-off-by: Sudhir Dumbhare --- .../python3/CVE-2026-3644_CVE-2026-0672.patch | 154 ++++++++++++++++++ .../python/python3_3.12.13.bb | 1 + 2 files changed, 155 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-3644_CVE-2026-0672.patch diff --git a/meta/recipes-devtools/python/python3/CVE-2026-3644_CVE-2026-0672.patch b/meta/recipes-devtools/python/python3/CVE-2026-3644_CVE-2026-0672.patch new file mode 100644 index 0000000000..42d8133a18 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-3644_CVE-2026-0672.patch @@ -0,0 +1,154 @@ +From 6e291d2eba0b6820bc924e68f1db750328bf6c75 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 16 Mar 2026 15:05:13 +0100 +Subject: [PATCH] [3.13] gh-145599, CVE 2026-3644: Reject control + characters in `http.cookies.Morsel.update()` (GH-145600) (#146024) + +gh-145599, CVE 2026-3644: Reject control characters in `http.cookies.Morsel.update()` (GH-145600) + +Reject control characters in `http.cookies.Morsel.update()` and `http.cookies.BaseCookie.js_output`. + +CVE: CVE-2026-3644 CVE-2026-0672 +Upstream-Status: Backport [https://github.com/python/cpython/commit/d16ecc6c3626f0e2cc8f08c309c83934e8a979dd] + +Backport Changes: +- This file is not present in the current version and is therefore omitted + Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst + +(cherry picked from commit 57e88c1cf95e1481b94ae57abe1010469d47a6b4) + +Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> +Co-authored-by: Victor Stinner +Co-authored-by: Victor Stinner +(cherry picked from commit d16ecc6c3626f0e2cc8f08c309c83934e8a979dd) +Signed-off-by: Sudhir Dumbhare +--- + Lib/http/cookies.py | 24 ++++++++++++++++++---- + Lib/test/test_http_cookies.py | 38 +++++++++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+), 4 deletions(-) + +diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py +index d0a69cbe191..63d119ad46c 100644 +--- a/Lib/http/cookies.py ++++ b/Lib/http/cookies.py +@@ -335,9 +335,16 @@ class Morsel(dict): + key = key.lower() + if key not in self._reserved: + raise CookieError("Invalid attribute %r" % (key,)) ++ if _has_control_character(key, val): ++ raise CookieError("Control characters are not allowed in " ++ f"cookies {key!r} {val!r}") + data[key] = val + dict.update(self, data) + ++ def __ior__(self, values): ++ self.update(values) ++ return self ++ + def isReservedKey(self, K): + return K.lower() in self._reserved + +@@ -363,9 +370,15 @@ class Morsel(dict): + } + + def __setstate__(self, state): +- self._key = state['key'] +- self._value = state['value'] +- self._coded_value = state['coded_value'] ++ key = state['key'] ++ value = state['value'] ++ coded_value = state['coded_value'] ++ if _has_control_character(key, value, coded_value): ++ raise CookieError("Control characters are not allowed in cookies " ++ f"{key!r} {value!r} {coded_value!r}") ++ self._key = key ++ self._value = value ++ self._coded_value = coded_value + + def output(self, attrs=None, header="Set-Cookie:"): + return "%s %s" % (header, self.OutputString(attrs)) +@@ -377,13 +390,16 @@ class Morsel(dict): + + def js_output(self, attrs=None): + # Print javascript ++ output_string = self.OutputString(attrs) ++ if _has_control_character(output_string): ++ raise CookieError("Control characters are not allowed in cookies") + return """ + +- """ % (self.OutputString(attrs).replace('"', r'\"')) ++ """ % (output_string.replace('"', r'\"')) + + def OutputString(self, attrs=None): + # Build up our result +diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py +index f196bcc48e3..2478a6c630f 100644 +--- a/Lib/test/test_http_cookies.py ++++ b/Lib/test/test_http_cookies.py +@@ -573,6 +573,14 @@ class MorselTests(unittest.TestCase): + with self.assertRaises(cookies.CookieError): + morsel["path"] = c0 + ++ # .__setstate__() ++ with self.assertRaises(cookies.CookieError): ++ morsel.__setstate__({'key': c0, 'value': 'val', 'coded_value': 'coded'}) ++ with self.assertRaises(cookies.CookieError): ++ morsel.__setstate__({'key': 'key', 'value': c0, 'coded_value': 'coded'}) ++ with self.assertRaises(cookies.CookieError): ++ morsel.__setstate__({'key': 'key', 'value': 'val', 'coded_value': c0}) ++ + # .setdefault() + with self.assertRaises(cookies.CookieError): + morsel.setdefault("path", c0) +@@ -587,6 +595,18 @@ class MorselTests(unittest.TestCase): + with self.assertRaises(cookies.CookieError): + morsel.set("path", "val", c0) + ++ # .update() ++ with self.assertRaises(cookies.CookieError): ++ morsel.update({"path": c0}) ++ with self.assertRaises(cookies.CookieError): ++ morsel.update({c0: "val"}) ++ ++ # .__ior__() ++ with self.assertRaises(cookies.CookieError): ++ morsel |= {"path": c0} ++ with self.assertRaises(cookies.CookieError): ++ morsel |= {c0: "val"} ++ + def test_control_characters_output(self): + # Tests that even if the internals of Morsel are modified + # that a call to .output() has control character safeguards. +@@ -607,6 +627,24 @@ class MorselTests(unittest.TestCase): + with self.assertRaises(cookies.CookieError): + cookie.output() + ++ # Tests that .js_output() also has control character safeguards. ++ for c0 in support.control_characters_c0(): ++ morsel = cookies.Morsel() ++ morsel.set("key", "value", "coded-value") ++ morsel._key = c0 # Override private variable. ++ cookie = cookies.SimpleCookie() ++ cookie["cookie"] = morsel ++ with self.assertRaises(cookies.CookieError): ++ cookie.js_output() ++ ++ morsel = cookies.Morsel() ++ morsel.set("key", "value", "coded-value") ++ morsel._coded_value = c0 # Override private variable. ++ cookie = cookies.SimpleCookie() ++ cookie["cookie"] = morsel ++ with self.assertRaises(cookies.CookieError): ++ cookie.js_output() ++ + + def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite(cookies)) +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3_3.12.13.bb b/meta/recipes-devtools/python/python3_3.12.13.bb index 5fa25235fe..41d2efbd28 100644 --- a/meta/recipes-devtools/python/python3_3.12.13.bb +++ b/meta/recipes-devtools/python/python3_3.12.13.bb @@ -34,6 +34,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \ file://0001-test_deadlock-skip-problematic-test.patch \ file://0001-test_active_children-skip-problematic-test.patch \ file://0001-test_readline-skip-limited-history-test.patch \ + file://CVE-2026-3644_CVE-2026-0672.patch \ " SRC_URI:append:class-native = " \ From patchwork Sat Jun 13 10:11:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 90004 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27CC7CD8CA8 for ; Sat, 13 Jun 2026 10:12:32 +0000 (UTC) Received: from rcdn-iport-9.cisco.com (rcdn-iport-9.cisco.com [173.37.86.80]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.88529.1781345545004113823 for ; Sat, 13 Jun 2026 03:12:25 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=GHmpTdU8; spf=pass (domain: cisco.com, ip: 173.37.86.80, mailfrom: sudumbha@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=14894; q=dns/txt; s=iport01; t=1781345545; x=1782555145; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=OWkLW1Sjq1LO4/ViICcIgeeSE+L2ZKglEMb02IllhGM=; b=GHmpTdU8WbCpnqsnOBPsikvVMu0dGI2wlsatvoFj6rfzcXUAA4TQoDkT 213Xolb6gPbCQ2v/ynf4QeyxYf3OAmaYTfx538Zw+Yh1bBMA69+DPYmub SOiYHldw5eMKdElAbOH2gzUBl1BRpH7lDSfN++qDHAXjBE1SzgNC4vI2i 0rcRRyQpFGYuERjLIrWckAY93Pe94NFcmKVEWNl+pxS2IOzmE8hZzHcbA se0j6X/hRthPIqX45N2VknQwoRonGhxWGe3xFS+60iIpcBer9niOh6iwV o1xlvoRrnv3J5RmPhczRPqLWi7OFzTXOsujkdoqBzK71c8q43EGhpGnww A==; X-CSE-ConnectionGUID: ZlQ6uxMTRqyYB13/mQyGFg== X-CSE-MsgGUID: 8ZKzBoVjTYS41iA2/frB7g== X-IPAS-Result: A0BNAgBhLC1q/5T/Ja1aglmCV3RfQkkDhFSPU4IhA4tkkjeBfg8BAQEPRA0EAQGEQEYCjUMCJjQJDgECBAMCAwEBAQEBAQEBAQEBCwEBBQEBAQIBBwWBDhOGTw2GWgECAQMjDwEYAT0cAwECAwImAgIgCyMIEAkJEQSCZAGCOgM2AgERs1h6gTKBAYMoATEFAwEFAkNQ2EgNglYBCxQBgQouhT+CfCABhQJbGAFEhDgnGxuBcoEVg2mBBYEaQgEBAoE1hASCagSCIoEMgV0ejx1IgQIcA1ksAVUTDQoLBwWBZgM1EioVbjIdgSM+FzRYGwcFgUqBK2qBBIUNIx8DOX+Bc4EoZ2cVMDWBAhEfChwDCxgNSBEsNxQbBD0BbgeMXRcPgUIKcgE8NwcTAQcjAQkOCQItMBIHCCMdTBENKwWjB4IhoB5xCiiDdYwhjz6FfBozhVulEZkIjgqECZJHhGiBaDyBRwsHcBWDIglKGQ+OOINrgX+CUUNRwSokNQIJAy8BAQcCBwIMAwuBaJAAAiYBgVQBAQ IronPort-Data: A9a23:DZLZr6975Z64l/L0sPRADrUD0X+TJUtcMsCJ2f8bNWPcYEJGY0x3z GAfCGmGOfvfYGPzfY9zboXl8UgC6sTWz9dmGQI+rXhEQiMRo6IpJzg2wmQcns+2BpeeJK6yx 5xGMrEsFOhtEDmE4EzrauS9xZVF/fngbqLmD+LZMTxGSwZhSSMw4TpugOdRbrRA2bBVOCvT/ 4muyyHjEAX9gWAsbDtPs/vrRC5H5ZwehhtJ5jTSWtgT1LPuvyF9JI4SI6i3M0z5TuF8dsamR /zOxa2O5WjQ+REgELuNyt4XpWVTH9Y+lSDX4pZnc/DKbipq/0Te4Y5nXBYoUnq7vh3S9zxHJ HqhgrTrIeshFvWkdO3wyHC0GQkmVUFN0OevzXRSLaV/wmWeG0YAzcmCA2kEObRG5/ZSPVtX5 M0ycWtKaymSqMy5lefTpulE3qzPLeHxN48Z/3UlxjbDALN/GNbIQr7B4plT2zJYasJmRKmFI ZFGL2AyMVKZP00n1lQ/UPrSmM+zm3XidjdYoXqepLE85C7YywkZPL3FbIuOI4TbGpQP9qqej jL03HbTBS8YCO2klWOE2yjriPXlwiyuDer+E5X9rJaGmma7wXQeDhATX1a3rfS1z0W5Qd93L 00P5jFoqrA/8kGuRNTxUxC05nmesXYht8F4CeY27kSJj6HT+QvcXzFCRT9aY9tgv8gzLdA36 mK0cxrSLWQHmNWopbi1r994cRva1fApEFI/ IronPort-HdrOrdr: A9a23:Qn5PuaBjgaGnTDDlHemO55DYdb4zR+YMi2TDsHoBLiC9E/bo8/ xG88506faZslsssTQb6LO90cq7MBbhHOBOgLX5VI3KNGKNhILrFvAB0WKI+VLd8kPFmtK1rZ 0BT4FOTPvtEFN9kcH2pCO8E9om3Z271ZrAv5a585+oJjsaE52JKGxCe3+mLnE= X-Talos-CUID: 9a23:jo4BOm0hAczUHujQLh1nxLxfKMQcLGDN6UvqOl6JIz8yD7isWHC+9/Yx X-Talos-MUID: 9a23:EnQm9gjYwoxm0x2M1/UfAcMpZPVL8Y6pNkIxoK5a4sitb2t+IR3Cg2Hi X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.24,202,1774310400"; d="scan'208";a="493109792" Received: from rcdn-l-core-11.cisco.com ([173.37.255.148]) by rcdn-iport-9.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 13 Jun 2026 10:12:22 +0000 Received: from sjc-ads-12007.cisco.com (sjc-ads-12007.cisco.com [171.70.97.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by rcdn-l-core-11.cisco.com (Postfix) with ESMTPS id 26A501800027E for ; Sat, 13 Jun 2026 10:12:22 +0000 (GMT) Received: by sjc-ads-12007.cisco.com (Postfix, from userid 1840713) id C8247CB6A93; Sat, 13 Jun 2026 03:12:21 -0700 (PDT) From: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-core@lists.openembedded.org Subject: [OE-core][scarthgap][PATCH 2/4] python3: Fix CVE-2026-4519 and CVE-2026-4786 Date: Sat, 13 Jun 2026 03:11:37 -0700 Message-Id: <20260613101137.3690080-2-sudumbha@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260613101137.3690080-1-sudumbha@cisco.com> References: <20260613101137.3690080-1-sudumbha@cisco.com> MIME-Version: 1.0 X-Outbound-Client-TLS: VERIFIED;sjc-ads-12007.cisco.com [171.70.97.7];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 171.70.97.7, sjc-ads-12007.cisco.com X-Outbound-Node: rcdn-l-core-11.cisco.com List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 13 Jun 2026 10:12:32 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/238668 From: Sudhir Dumbhare Apply the upstream v3.12 fix [1], aligned with the original v3.11 fix [2], and follow-up fix [3] to address CVE-2026-4519 by disallowing URLs with leading dashes when invoking browser commands, as referenced in [5]. CVE-2026-4786 [6] revealed the CVE-2026-4519 fix was incomplete, as %action in URLs could bypass dash-prefix checks. Apply follow-up fix [4], noted in [5], to revalidate the URL after %action expansion. [1] https://github.com/python/cpython/commit/cbba6119391112aba9c5aebf7b94aea447922c48 [2] https://github.com/python/cpython/commit/ceac1efc66516ac387eef2c9a0ce671895b44f03 [3] https://github.com/python/cpython/commit/96fc5048605863c7b6fd6289643feb0e97edd96c [4] https://github.com/python/cpython/commit/f4654824ae0850ac87227fb270f9057477946769 [5] https://security-tracker.debian.org/tracker/CVE-2026-4519 [6] https://security-tracker.debian.org/tracker/CVE-2026-4786 References: https://nvd.nist.gov/vuln/detail/CVE-2026-4519 https://nvd.nist.gov/vuln/detail/CVE-2026-4786 Signed-off-by: Sudhir Dumbhare --- .../python3/CVE-2026-4519_CVE-2026-4786.patch | 66 ++++++++ .../python/python3/CVE-2026-4519_p1.patch | 107 ++++++++++++ .../python/python3/CVE-2026-4519_p2.patch | 159 ++++++++++++++++++ .../python/python3_3.12.13.bb | 3 + 4 files changed, 335 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-4519_CVE-2026-4786.patch create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-4519_p1.patch create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-4519_p2.patch diff --git a/meta/recipes-devtools/python/python3/CVE-2026-4519_CVE-2026-4786.patch b/meta/recipes-devtools/python/python3/CVE-2026-4519_CVE-2026-4786.patch new file mode 100644 index 0000000000..6a4714f25a --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-4519_CVE-2026-4786.patch @@ -0,0 +1,66 @@ +From b9af29b9f2f880cdcdc49a1460743680f59dcb4e Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych +Date: Mon, 13 Apr 2026 22:41:51 +0100 +Subject: [PATCH] [3.11] gh-148169: Fix webbrowser `%action` substitution + bypass of dash-prefix check (GH-148170) (#148520) + +CVE: CVE-2026-4519 CVE-2026-4786 +Upstream-Status: Backport [https://github.com/python/cpython/commit/f4654824ae0850ac87227fb270f9057477946769] + +Backport Changes: +- This file is not present in the current version and is therefore omitted. + Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst + +(cherry picked from commit d22922c8a7958353689dc4763dd72da2dea03fff) +(cherry picked from commit f4654824ae0850ac87227fb270f9057477946769) +Signed-off-by: Sudhir Dumbhare +--- + Lib/test/test_webbrowser.py | 8 ++++++++ + Lib/webbrowser.py | 5 +++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index c9bf525360d..1d21f133725 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -103,6 +103,14 @@ class ChromeCommandTest(CommandTestMixin, unittest.TestCase): + options=[], + arguments=[URL]) + ++ def test_reject_action_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaises(ValueError): ++ browser.open('%action--incognito') ++ # new=1: action is "--new-window", so "%action" itself expands to ++ # a dash-prefixed flag even with no dash in the original URL. ++ with self.assertRaises(ValueError): ++ browser.open('%action', new=1) + + class EdgeCommandTest(CommandTestMixin, unittest.TestCase): + +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index 000e89275b7..97c4eec9080 100755 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -268,7 +268,6 @@ class UnixBrowser(BaseBrowser): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) +- self._check_url(url) + if new == 0: + action = self.remote_action + elif new == 1: +@@ -282,7 +281,9 @@ class UnixBrowser(BaseBrowser): + raise Error("Bad 'new' parameter to open(); " + + "expected 0, 1, or 2, got %s" % new) + +- args = [arg.replace("%s", url).replace("%action", action) ++ self._check_url(url.replace("%action", action)) ++ ++ args = [arg.replace("%action", action).replace("%s", url) + for arg in self.remote_args] + args = [arg for arg in args if arg] + success = self._invoke(args, True, autoraise, url) +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3/CVE-2026-4519_p1.patch b/meta/recipes-devtools/python/python3/CVE-2026-4519_p1.patch new file mode 100644 index 0000000000..1514d2c541 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-4519_p1.patch @@ -0,0 +1,107 @@ +From 7df48dd3c6330611a04d85a5159c0ea424dc1e62 Mon Sep 17 00:00:00 2001 +From: Pinky +Date: Wed, 25 Mar 2026 01:02:37 +0530 +Subject: [PATCH] [3.12] gh-143930: Reject leading dashes in webbrowser + URLs (GH-146360) + +CVE: CVE-2026-4519 +Upstream-Status: Backport [https://github.com/python/cpython/commit/cbba6119391112aba9c5aebf7b94aea447922c48] + +Backport Changes: +- This file is not present in the current version and is therefore omitted + Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst + +(cherry picked from commit 82a24a4442312bdcfc4c799885e8b3e00990f02b) + +Co-authored-by: Seth Michael Larson +(cherry picked from commit cbba6119391112aba9c5aebf7b94aea447922c48) +Signed-off-by: Sudhir Dumbhare +--- + Lib/test/test_webbrowser.py | 5 +++++ + Lib/webbrowser.py | 12 ++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index 2d695bc8831..60f094fd6a1 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -59,6 +59,11 @@ class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase): + options=[], + arguments=[URL]) + ++ def test_reject_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaises(ValueError): ++ browser.open(f"--key=val {URL}") ++ + + class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): + +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index 13b9e85f9e1..0bdb644d7db 100755 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -158,6 +158,12 @@ class BaseBrowser(object): + def open_new_tab(self, url): + return self.open(url, 2) + ++ @staticmethod ++ def _check_url(url): ++ """Ensures that the URL is safe to pass to subprocesses as a parameter""" ++ if url and url.lstrip().startswith("-"): ++ raise ValueError(f"Invalid URL: {url}") ++ + + class GenericBrowser(BaseBrowser): + """Class for all browsers started with a command +@@ -175,6 +181,7 @@ class GenericBrowser(BaseBrowser): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + cmdline = [self.name] + [arg.replace("%s", url) + for arg in self.args] + try: +@@ -195,6 +202,7 @@ class BackgroundBrowser(GenericBrowser): + cmdline = [self.name] + [arg.replace("%s", url) + for arg in self.args] + sys.audit("webbrowser.open", url) ++ self._check_url(url) + try: + if sys.platform[:3] == 'win': + p = subprocess.Popen(cmdline) +@@ -260,6 +268,7 @@ class UnixBrowser(BaseBrowser): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + if new == 0: + action = self.remote_action + elif new == 1: +@@ -350,6 +359,7 @@ class Konqueror(BaseBrowser): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + # XXX Currently I know no way to prevent KFM from opening a new win. + if new == 2: + action = "newTab" +@@ -554,6 +564,7 @@ if sys.platform[:3] == "win": + class WindowsDefault(BaseBrowser): + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + try: + os.startfile(url) + except OSError: +@@ -638,6 +649,7 @@ if sys.platform == 'darwin': + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) ++ self._check_url(url) + if self.name == 'default': + script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser + else: +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3/CVE-2026-4519_p2.patch b/meta/recipes-devtools/python/python3/CVE-2026-4519_p2.patch new file mode 100644 index 0000000000..7ee145e5e8 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-4519_p2.patch @@ -0,0 +1,159 @@ +From 3ca64ff1722d2410a4e50e760de70f6279fa99fa Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Sat, 4 Apr 2026 00:53:49 +0200 +Subject: [PATCH] [3.11] gh-143930: Tweak the exception message and + increase test coverage (GH-146476) (GH-148045) (GH-148051) (GH-148052) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE: CVE-2026-4519 +Upstream-Status: Backport [https://github.com/python/cpython/commit/96fc5048605863c7b6fd6289643feb0e97edd96c] + +Backport Changes: +- This file is not present in the current version and is therefore omitted. + Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst +- The file introduced in v3.12 by this commit; + https://github.com/python/cpython/commit/cbba6119391112aba9c5aebf7b94aea447922c48 + +(cherry picked from commit cc023511238ad93ecc8796157c6f9139a2bb2932) +(cherry picked from commit 89bfb8e5ed3c7caa241028f1a4eac5f6275a46a4) +(cherry picked from commit 3681d47a440865aead912a054d4599087b4270dd) + +Co-authored-by: Łukasz Langa +(cherry picked from commit 96fc5048605863c7b6fd6289643feb0e97edd96c) +Signed-off-by: Sudhir Dumbhare +--- + Lib/test/test_webbrowser.py | 81 ++++++++++++++++++++++++++++++++++--- + Lib/webbrowser.py | 2 +- + 2 files changed, 76 insertions(+), 7 deletions(-) + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index 60f094fd6a1..c9bf525360d 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -1,6 +1,7 @@ ++import io ++import os + import webbrowser + import unittest +-import os + import sys + import subprocess + from unittest import mock +@@ -49,6 +50,14 @@ class CommandTestMixin: + popen_args.pop(popen_args.index(option)) + self.assertEqual(popen_args, arguments) + ++ def test_reject_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaisesRegex( ++ ValueError, ++ r"^Invalid URL \(leading dash disallowed\): '--key=val http.*'$" ++ ): ++ browser.open(f"--key=val {URL}") ++ + + class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase): + +@@ -59,11 +68,6 @@ class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase): + options=[], + arguments=[URL]) + +- def test_reject_dash_prefixes(self): +- browser = self.browser_class(name=CMD_NAME) +- with self.assertRaises(ValueError): +- browser.open(f"--key=val {URL}") +- + + class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): + +@@ -224,6 +228,71 @@ class ELinksCommandTest(CommandTestMixin, unittest.TestCase): + arguments=['openURL({},new-tab)'.format(URL)]) + + ++class MockPopenPipe: ++ def __init__(self, cmd, mode): ++ self.cmd = cmd ++ self.mode = mode ++ self.pipe = io.StringIO() ++ self._closed = False ++ ++ def write(self, buf): ++ self.pipe.write(buf) ++ ++ def close(self): ++ self._closed = True ++ return None ++ ++ ++@unittest.skipUnless(sys.platform == "darwin", "macOS specific test") ++class MacOSXOSAScriptTest(unittest.TestCase): ++ def setUp(self): ++ # Ensure that 'BROWSER' is not set to 'open' or something else. ++ # See: https://github.com/python/cpython/issues/131254. ++ env = self.enterContext(os_helper.EnvironmentVarGuard()) ++ env.unset("BROWSER") ++ ++ support.patch(self, os, "popen", self.mock_popen) ++ self.browser = webbrowser.MacOSXOSAScript("default") ++ ++ def mock_popen(self, cmd, mode): ++ self.popen_pipe = MockPopenPipe(cmd, mode) ++ return self.popen_pipe ++ ++ def test_default(self): ++ browser = webbrowser.get() ++ assert isinstance(browser, webbrowser.MacOSXOSAScript) ++ self.assertEqual(browser.name, "default") ++ ++ def test_default_open(self): ++ url = "https://python.org" ++ self.browser.open(url) ++ self.assertTrue(self.popen_pipe._closed) ++ self.assertEqual(self.popen_pipe.cmd, "osascript") ++ script = self.popen_pipe.pipe.getvalue() ++ self.assertEqual(script.strip(), f'open location "{url}"') ++ ++ def test_url_quote(self): ++ self.browser.open('https://python.org/"quote"') ++ script = self.popen_pipe.pipe.getvalue() ++ self.assertEqual( ++ script.strip(), 'open location "https://python.org/%22quote%22"' ++ ) ++ ++ def test_explicit_browser(self): ++ browser = webbrowser.MacOSXOSAScript("safari") ++ browser.open("https://python.org") ++ script = self.popen_pipe.pipe.getvalue() ++ self.assertIn('tell application "safari"', script) ++ self.assertIn('open location "https://python.org"', script) ++ ++ def test_reject_dash_prefixes(self): ++ with self.assertRaisesRegex( ++ ValueError, ++ r"^Invalid URL \(leading dash disallowed\): '--key=val http.*'$" ++ ): ++ self.browser.open(f"--key=val {URL}") ++ ++ + class BrowserRegistrationTest(unittest.TestCase): + + def setUp(self): +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index 0bdb644d7db..000e89275b7 100755 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -162,7 +162,7 @@ class BaseBrowser(object): + def _check_url(url): + """Ensures that the URL is safe to pass to subprocesses as a parameter""" + if url and url.lstrip().startswith("-"): +- raise ValueError(f"Invalid URL: {url}") ++ raise ValueError(f"Invalid URL (leading dash disallowed): {url!r}") + + + class GenericBrowser(BaseBrowser): +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3_3.12.13.bb b/meta/recipes-devtools/python/python3_3.12.13.bb index 41d2efbd28..6ef67e8117 100644 --- a/meta/recipes-devtools/python/python3_3.12.13.bb +++ b/meta/recipes-devtools/python/python3_3.12.13.bb @@ -35,6 +35,9 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \ file://0001-test_active_children-skip-problematic-test.patch \ file://0001-test_readline-skip-limited-history-test.patch \ file://CVE-2026-3644_CVE-2026-0672.patch \ + file://CVE-2026-4519_p1.patch \ + file://CVE-2026-4519_p2.patch \ + file://CVE-2026-4519_CVE-2026-4786.patch \ " SRC_URI:append:class-native = " \ From patchwork Sat Jun 13 10:11:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 90005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35DAFCD98C5 for ; Sat, 13 Jun 2026 10:13:02 +0000 (UTC) Received: from rcdn-iport-4.cisco.com (rcdn-iport-4.cisco.com [173.37.86.75]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.88533.1781345570240289582 for ; Sat, 13 Jun 2026 03:12:50 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=XShu7+Xf; spf=pass (domain: cisco.com, ip: 173.37.86.75, mailfrom: sudumbha@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=12397; q=dns/txt; s=iport01; t=1781345570; x=1782555170; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=8t6Jc2q7GS4lUhovSbaFSatNjXUHFkWZ3u1IobMglrk=; b=XShu7+Xf12K7aCnVjLrAOt/gH+xqsoOvtfIQw7Ypvf9ed3bbo3GSHTY+ aIR5+9ClaUhY4xLbV4IQlCAn8fLXm5t7W6xxmsqFftEpWsFn4WyLQIzKk WBxjmzyANwZb2UHNWb8kNZKQ/HJe9m6WfThK+Dfix2pjIeVuHUUDS5Fah cB2qvKpWlJNazSVvMHSpRESEU4+/RSisd3DeZth8oHO4KRlCFo/rxo6Ik Vq2LTkLCs2xYJClO75cTiC7R5J03r2I+vT6gjA9vtLHNpykPw2ugkjjYT BY+6MacMdkCMNiDEwh7Ib7JwWWpAowxGRb6WinVnw8p+uyth1f9zg1SEQ w==; X-CSE-ConnectionGUID: Qu/Ndn3ERWuSjuPNf21Avw== X-CSE-MsgGUID: VSYXcAikTCS0wpo7u95i2Q== X-IPAS-Result: A0A8AwBhLC1q/4z/Ja1aglmCV3RfQkkDlCeCIQOgGQ8BAQEPRA0EAQGEQEYCjUMCJjcGDgECBAMCAwEBAQEBAQEBAQEBCwEBBQEBAQIBBwWBDhOGTw2GWgECAQMnCwEYAT0cAwECLysjCBkJEYJoAYJzAgERs1iBeTOBAYMoATEFAwEFAkNQ2ysBCw0CBQGBOIMggh+IH1sYAYR8JxsbgXKBFYNpgQWBXAEBiCUEgg0VgQyBXR5SjktIgR4DWSwBVRMNCgsHBYFmAzUSKhVuMh2BIz4XgQwbBwWBSoEraoEEhQ0jHwM5f4FzgShnZxUwNYECER8KHAMLGA1IESw3FBsEPm4HjF0XD4FMRS0xDAIkKwEHIgEBIAJdYUwRDZJzLpI3oQ8KKIN1jCGVOhozhVulEZkIjgqWUIRogX4mgUcLB3AVgyIJShkPji0LC4NggX+DFFHBKiQ1AgkDLwEBBwIHDgMLgWiRfQEB IronPort-Data: A9a23:fx4qza0/hFaHTfTb+/bD5YJwkn2cJEfYwER7XKvMYLTBsI5bpzxWy DQaCG/VbPeLamXxeo92bdy39xsA6sDdzdY1GgI93Hw8FHgiRegpqji6wuYcGwvIc6UvmWo+t 512huHodZ5yFjmH4E/xbtANlFEkvYmQXL3wFeXYDS54QA5gWU8JhAlq8wIDqtYAbeORXUXX5 bsen+WFYAX7g2AtaTpNg06+gEoHUMra6WtwUmMWPZinjHeG/1EJAZQWI72GLneQauF8Au6gS u/f+6qy92Xf8g1FIovNfmHTKxBirhb6ZGBiu1IOM0SQqkEqSh8ajs7XAMEhhXJ/0F1lqTzeJ OJl7vRcQS9xVkHFdX90vxNwS0mSNoUekFPLzOTWXcG7lyX7n3XQL/pGNVxxG4EeoctNPnx19 +EgDj5XNzmdmLfjqF67YrEEasULNsLnOsYb/3pn1zycVa1gSpHYSKKM7thdtNsyrpkRRrCFO IxDNGcpNUiYC/FMEg9/5JYWh/qkm3z1czRwo1OOrq1x6G/WpOB0+OS8bIKLJ4fSHK25mG6mn VP29E34AS0xD4SA0T3a7yPxh7X2yHaTtIU6UefQGuRRqFqLy2oeDRcbWVe2rbyyjVSzc9ZeM FAPvC02oK4/8UamQtXwU1u/unHsg/IHc8BbH+t/7ESGzbDZpl7CQGMFVTVGLtchsafaWAAX6 7NApPuxbRQHjVFfYSv1Gmu8xd9qBRUoEA== IronPort-HdrOrdr: A9a23:znLBF6FdaBA0RTgnpLqExMeALOsnbusQ8zAXPidKOHhom6Oj+f xG8M536fawskdzZJhCo6HkBED/exLhHPdOiOF7V4tKHjOW2ldAR7sM0WKN+VHd8lXFltJ15O NHb7V0DsH2ABxRiMb35xT9LvMbqeP3l5xBQYzlvg5QpcYAUdAH0ztE X-Talos-CUID: 9a23:5iRia2oXH0u0+SZzy8iHMgXmUfk4NVvRyiz9GXClMmR0cJubEwa55rwxxg== X-Talos-MUID: 9a23:U+H7fAV6biYxnhHq/AHXtQFpHcZr34+VUF8Vlsob6pSFbxUlbg== X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.24,202,1774310400"; d="scan'208";a="494065301" Received: from rcdn-l-core-03.cisco.com ([173.37.255.140]) by rcdn-iport-4.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 13 Jun 2026 10:12:49 +0000 Received: from sjc-ads-12007.cisco.com (sjc-ads-12007.cisco.com [171.70.97.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by rcdn-l-core-03.cisco.com (Postfix) with ESMTPS id 0457118000587 for ; Sat, 13 Jun 2026 10:12:49 +0000 (GMT) Received: by sjc-ads-12007.cisco.com (Postfix, from userid 1840713) id A6265CB6A93; Sat, 13 Jun 2026 03:12:48 -0700 (PDT) From: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-core@lists.openembedded.org Subject: [OE-core][scarthgap][PATCH 3/4] python3: Fix CVE-2026-6019 Date: Sat, 13 Jun 2026 03:11:39 -0700 Message-Id: <20260613101137.3690080-3-sudumbha@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260613101137.3690080-1-sudumbha@cisco.com> References: <20260613101137.3690080-1-sudumbha@cisco.com> MIME-Version: 1.0 X-Outbound-Client-TLS: VERIFIED;sjc-ads-12007.cisco.com [171.70.97.7];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 171.70.97.7, sjc-ads-12007.cisco.com X-Outbound-Node: rcdn-l-core-03.cisco.com List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 13 Jun 2026 10:13:02 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/238669 From: Sudhir Dumbhare This patch applies the upstream fix [1] and follow-up fix [2], as referenced in [3] and [4], to address an http.cookies.Morsel.js_output() flaw where inline JavaScript output escaped quotes but did not neutralize the HTML parser-sensitive sequence. [1] https://github.com/python/cpython/commit/3c59b8b53fc75c7f9578d16fb8201ceb43e8f76c [2] https://github.com/python/cpython/commit/e7d4c3ff421916986223690a8425d2383f6f3802 [3] https://github.com/python/cpython/issues/149144 [4] https://security-tracker.debian.org/tracker/CVE-2026-6019 Reference: https://nvd.nist.gov/vuln/detail/CVE-2026-6019 Signed-off-by: Sudhir Dumbhare --- .../python/python3/CVE-2026-6019_p1.patch | 133 ++++++++++++++++++ .../python/python3/CVE-2026-6019_p2.patch | 129 +++++++++++++++++ .../python/python3_3.12.13.bb | 2 + 3 files changed, 264 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-6019_p1.patch create mode 100644 meta/recipes-devtools/python/python3/CVE-2026-6019_p2.patch diff --git a/meta/recipes-devtools/python/python3/CVE-2026-6019_p1.patch b/meta/recipes-devtools/python/python3/CVE-2026-6019_p1.patch new file mode 100644 index 0000000000..27a4160942 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-6019_p1.patch @@ -0,0 +1,133 @@ +From be751c3f3a11d40c2133bee5fb6ab6931df31936 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Thu, 23 Apr 2026 15:05:17 +0200 +Subject: [PATCH] [3.13] gh-90309: Base64-encode cookie values embedded in + JS (GH-148888) + +CVE: CVE-2026-6019 +Upstream-Status: Backport [https://github.com/python/cpython/commit/3c59b8b53fc75c7f9578d16fb8201ceb43e8f76c] + +Backport Changes: +- This file is not present in the current version and is therefore omitted. + Misc/NEWS.d/next/Security/2026-04-21-13-46-30.gh-issue-90309.srvj9q.rst + +(cherry picked from commit 76b3923d688c0efc580658476c5f525ec8735104) + +Co-authored-by: Seth Larson +(cherry picked from commit 3c59b8b53fc75c7f9578d16fb8201ceb43e8f76c) +Signed-off-by: Sudhir Dumbhare +--- + Lib/http/cookies.py | 8 ++++++-- + Lib/test/test_http_cookies.py | 29 ++++++++++++++++++----------- + 2 files changed, 24 insertions(+), 13 deletions(-) + +diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py +index 63d119ad46c..aebc2a163e4 100644 +--- a/Lib/http/cookies.py ++++ b/Lib/http/cookies.py +@@ -389,17 +389,21 @@ class Morsel(dict): + return '<%s: %s>' % (self.__class__.__name__, self.OutputString()) + + def js_output(self, attrs=None): ++ import base64 + # Print javascript + output_string = self.OutputString(attrs) + if _has_control_character(output_string): + raise CookieError("Control characters are not allowed in cookies") ++ # Base64-encode value to avoid template ++ # injection in cookie values. ++ output_encoded = base64.b64encode(output_string.encode('utf-8')).decode("ascii") + return """ + +- """ % (output_string.replace('"', r'\"')) ++ """ % (output_encoded,) + + def OutputString(self, attrs=None): + # Build up our result +diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py +index 2478a6c630f..6aa5df068f9 100644 +--- a/Lib/test/test_http_cookies.py ++++ b/Lib/test/test_http_cookies.py +@@ -1,5 +1,5 @@ + # Simple test suite for http/cookies.py +- ++import base64 + import copy + import unittest + import doctest +@@ -152,17 +152,19 @@ class CookieTests(unittest.TestCase): + + self.assertEqual(C.output(['path']), + 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') +- self.assertEqual(C.js_output(), r""" ++ cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii') ++ self.assertEqual(C.js_output(), fr""" + + """) +- self.assertEqual(C.js_output(['path']), r""" ++ cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii') ++ self.assertEqual(C.js_output(['path']), fr""" + + """) +@@ -259,17 +261,19 @@ class CookieTests(unittest.TestCase): + + self.assertEqual(C.output(['path']), + 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') +- self.assertEqual(C.js_output(), r""" ++ expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii') ++ self.assertEqual(C.js_output(), fr""" + + """) +- self.assertEqual(C.js_output(['path']), r""" ++ expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii') ++ self.assertEqual(C.js_output(['path']), fr""" + + """) +@@ -360,13 +364,16 @@ class MorselTests(unittest.TestCase): + self.assertEqual( + M.output(), + "Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i)) ++ expected_encoded_cookie = base64.b64encode( ++ ("%s=%s; Path=/foo" % (i, "%s_coded_val" % i)).encode("ascii") ++ ).decode('ascii') + expected_js_output = """ + +- """ % (i, "%s_coded_val" % i) ++ """ % (expected_encoded_cookie,) + self.assertEqual(M.js_output(), expected_js_output) + for i in ["foo bar", "foo@bar"]: + # Try some illegal characters +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3/CVE-2026-6019_p2.patch b/meta/recipes-devtools/python/python3/CVE-2026-6019_p2.patch new file mode 100644 index 0000000000..0646bd2133 --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2026-6019_p2.patch @@ -0,0 +1,129 @@ +From de449bbc6ff4ce869c17fb551dacc69de25d73a9 Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych +Date: Mon, 8 Jun 2026 20:15:21 +0100 +Subject: [PATCH] [3.13] gh-149144: Use `decodeURIComponent()` for UTF-8 + support in `js_output()` (GH-149157) (#150949) + +CVE: CVE-2026-6019 +Upstream-Status: Backport [https://github.com/python/cpython/commit/e7d4c3ff421916986223690a8425d2383f6f3802] + +Co-authored-by: Seth Larson +(cherry picked from commit e7d4c3ff421916986223690a8425d2383f6f3802) +Signed-off-by: Sudhir Dumbhare +--- + Lib/http/cookies.py | 6 +++--- + Lib/test/test_http_cookies.py | 27 ++++++++++++++------------- + 2 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py +index aebc2a163e4..2cffa2a9ad6 100644 +--- a/Lib/http/cookies.py ++++ b/Lib/http/cookies.py +@@ -389,18 +389,18 @@ class Morsel(dict): + return '<%s: %s>' % (self.__class__.__name__, self.OutputString()) + + def js_output(self, attrs=None): +- import base64 ++ import urllib.parse + # Print javascript + output_string = self.OutputString(attrs) + if _has_control_character(output_string): + raise CookieError("Control characters are not allowed in cookies") + # Base64-encode value to avoid template + # injection in cookie values. +- output_encoded = base64.b64encode(output_string.encode('utf-8')).decode("ascii") ++ output_encoded = urllib.parse.quote(output_string, safe='', encoding='utf-8') + return """ + + """ % (output_encoded,) +diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py +index 6aa5df068f9..b9cc59cd1db 100644 +--- a/Lib/test/test_http_cookies.py ++++ b/Lib/test/test_http_cookies.py +@@ -1,10 +1,10 @@ + # Simple test suite for http/cookies.py +-import base64 + import copy + import unittest + import doctest + from http import cookies + import pickle ++import urllib.parse + from test import support + + +@@ -152,19 +152,19 @@ class CookieTests(unittest.TestCase): + + self.assertEqual(C.output(['path']), + 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') +- cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii') ++ cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme; Version=1', safe='', encoding='utf-8') + self.assertEqual(C.js_output(), fr""" + + """) +- cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii') ++ cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme', safe='', encoding='utf-8') + self.assertEqual(C.js_output(['path']), fr""" + + """) +@@ -261,19 +261,19 @@ class CookieTests(unittest.TestCase): + + self.assertEqual(C.output(['path']), + 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') +- expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii') ++ expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1', safe='', encoding='utf-8') + self.assertEqual(C.js_output(), fr""" + + """) +- expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii') ++ expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme', safe='', encoding='utf-8') + self.assertEqual(C.js_output(['path']), fr""" + + """) +@@ -364,13 +364,14 @@ class MorselTests(unittest.TestCase): + self.assertEqual( + M.output(), + "Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i)) +- expected_encoded_cookie = base64.b64encode( +- ("%s=%s; Path=/foo" % (i, "%s_coded_val" % i)).encode("ascii") +- ).decode('ascii') ++ expected_encoded_cookie = urllib.parse.quote( ++ "%s=%s; Path=/foo" % (i, "%s_coded_val" % i), ++ safe='', encoding='utf-8', ++ ) + expected_js_output = """ + + """ % (expected_encoded_cookie,) +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3_3.12.13.bb b/meta/recipes-devtools/python/python3_3.12.13.bb index 6ef67e8117..da23093285 100644 --- a/meta/recipes-devtools/python/python3_3.12.13.bb +++ b/meta/recipes-devtools/python/python3_3.12.13.bb @@ -38,6 +38,8 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \ file://CVE-2026-4519_p1.patch \ file://CVE-2026-4519_p2.patch \ file://CVE-2026-4519_CVE-2026-4786.patch \ + file://CVE-2026-6019_p1.patch \ + file://CVE-2026-6019_p2.patch \ " SRC_URI:append:class-native = " \ From patchwork Sat Jun 13 10:11:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 90006 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27489CD8CA8 for ; Sat, 13 Jun 2026 10:13:22 +0000 (UTC) Received: from rcdn-iport-8.cisco.com (rcdn-iport-8.cisco.com [173.37.86.79]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.88537.1781345595590297340 for ; Sat, 13 Jun 2026 03:13:15 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=Y4Ph2jtG; spf=pass (domain: cisco.com, ip: 173.37.86.79, mailfrom: sudumbha@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=6629; q=dns/txt; s=iport01; t=1781345595; x=1782555195; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=W3qADNf/iZ8KkULOkkqNj4E6GWU/EFfnOuhSiCxU6e8=; b=Y4Ph2jtG+SnCBRJnYfkguxbH0rYBEd3Ng7yO5ZmjzzbiYks5oH1VBhPM PI+DXu7gNjPN1UojVv2RAvBKUv8pu55jvJnSaHD7+TS2DMYhvG3zNjE4s FOXnOOIdr0HfSIf5bBOlXgMqGfh33/sNBfNtbyEHyfHE+0meHMMRzYxNC 3ae1SVmWIQj60LGFo5ftJGkUzowyCTAdEJti8aulkTuzgoQSJleCizleF AvSA3j9io/PkyL6bEmVwDCLKhV7No2GJQFluPpi/MWAg2UgyHgdWCzyuI ijdYI4Rw9UYmIcwTiLZNN8vpwndkwhAG92YIALmyQzpDSAaQCyN4B5Ucc g==; X-CSE-ConnectionGUID: 9s2i/J2GSGObCTjcvKL5Bg== X-CSE-MsgGUID: umcE4WtUSra94u1DJTPj3g== X-IPAS-Result: A0AEAwBaKy1q/5T/Ja1aHgEBCxIMggULgld0X0JJA4RUj1OCIQOeG4F+DwEBAQ9EDQQBAYRARgKNQwImNgcOAQIEAwIDAQEBAQEBAQEBAQELAQEFAQEBAgEHBYEOE4ZPDYZaAQIBAyMPARgBPRwDAQIDAiYCAisjCBkJEYJoAYJzAgERs156gTKBAYMoAT8CQ1DbLAELFAGBCi6FP4McAYUCWxgBRIQ4JxsbgXKBFYNpgQWBXAEBhTuCagSCIoEMgV0ejx1IgQIcA1ksAVUTDQoLBwWBZgM1EioVbjIdgSM+FzRYGwcFgUqBK2qBBIUNIx8DOX+Bc4EoZ2cVMDWBAhEfChwDCxgNSBEsNxQbBD0BbgeMXRcPgUxyPTcaAQcjASBfEgc1XxENkxiQH4IhoQ8KKIN1jCGVOhozhASBV5JAklELmH2OCokPjFhphGiBbwYvgUcLB3AVgyIJShkPjioOC4NggX+CUUNRwSokNQIJAy8BAQcCBwEMAQMLgWiRfQEB IronPort-Data: A9a23:nuyYfa7oVaNUyRjLUMwl/gxRtGnGchMFZxGqfqrLsTDasY5as4F+v mJMXWiEafuNa2ryKNskYYS38xwF7cPXyoVkQVQ+/C8yZn8b8sCt6fZ1gavT04J+CuWZESqLO u1HMoGowPgcFyGa/lH2dOC98RGQ7InQLpLkEunIJyttcgFtTSYlmHpLlvUw6mJSqYDR7zil5 5Wo/6UzBHf/g2QqajxNsPrawP9SlK2aVA0w7wRWic9j5Dcyp1FNZLoDKKe4KWfPQ4U8NoaSW +bZwbilyXjS9hErB8nNuu6TnpoiG+O60aCm0xK6aoD66vRwjnVaPpUTaJLwXXxqZwChxLid/ jniWauYEm/FNoWU8AgUvoIx/ytWZcWq85efSZSzXFD6I0DuKxPRL/tS4E4ebJZC+6FVW0512 tsSAwwPZQ6go7+cz+fuIgVsrpxLwMjDJogTvDRkiDreF/tjGMmFSKTR7tge1zA17ixMNa+BP IxCNnw1MUmGOkEfUrsUIMpWcOOAnWTzbjhSqFu9rqss6G+Vxwt0uFToGIaFJ4DRFZ0NxC50o Erb+m/UXi4GCeeFwGvZ7yuApNP3n3j0Ddd6+LqQs6QCbEeo7msLBRsbUFG2rfW0hgu1XMhSA 0gV4TY1668q+UqmS9PwUxG1rDiDpBF0ZjZLO/cx5AfIzu/f5ByUQzFdCDVAc9ch8sQxQFTGy 2O0oj8gPhQ32JX9dJ5X3u78Qe+aUcTNEVI/WA== IronPort-HdrOrdr: A9a23:DfR5P6EECrj3+6XNpLqEyseALOsnbusQ8zAXPidKOHtom62j5q STdZsguyMc5Ax9ZJhko6HiBEDiewK4yXcK2+gs1N6ZNWGM0ldAbrsSj7cKqAeOJ8SRzIJgPN 9bE5RWOZnXEUVwi9r87U2TFtYtx8TCzYWT7N2uqUuEiWpRGtldB8ATMHfjLnFL X-Talos-CUID: 9a23:Deua3Wobz6oU2HuG6FWo6I3mUZE+KHya7i3/GGCfA01VSraLanvN0qwxxg== X-Talos-MUID: 9a23:/oFzkg8LIQoQHhKzo7+MD7qQf9pt6InyN1wwqo8P6pWZbABSBw+f1zviFw== X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.24,202,1774310400"; d="scan'208";a="485438002" Received: from rcdn-l-core-11.cisco.com ([173.37.255.148]) by rcdn-iport-8.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 13 Jun 2026 10:13:14 +0000 Received: from sjc-ads-12007.cisco.com (sjc-ads-12007.cisco.com [171.70.97.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by rcdn-l-core-11.cisco.com (Postfix) with ESMTPS id 729A2180002CA for ; Sat, 13 Jun 2026 10:13:14 +0000 (GMT) Received: by sjc-ads-12007.cisco.com (Postfix, from userid 1840713) id 20A95CB6A93; Sat, 13 Jun 2026 03:13:14 -0700 (PDT) From: "Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-core@lists.openembedded.org Subject: [OE-core][scarthgap][PATCH 4/4] python3: Fix CVE-2025-13462 Date: Sat, 13 Jun 2026 03:11:41 -0700 Message-Id: <20260613101137.3690080-4-sudumbha@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260613101137.3690080-1-sudumbha@cisco.com> References: <20260613101137.3690080-1-sudumbha@cisco.com> MIME-Version: 1.0 X-Outbound-Client-TLS: VERIFIED;sjc-ads-12007.cisco.com [171.70.97.7];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 171.70.97.7, sjc-ads-12007.cisco.com X-Outbound-Node: rcdn-l-core-11.cisco.com List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 13 Jun 2026 10:13:22 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/238670 From: Sudhir Dumbhare Apply the upstream v3.12 fix [1], aligned with the original v3.13 fix [2], to address incorrect tarfile handling where GNU long name follow-up headers could be normalized as directories, as referenced in [3]. [1] https://github.com/python/cpython/commit/d10950739a78f54d0718d88fb5a868374603c084 [2] https://github.com/python/cpython/commit/ae99fe3a33b43e303a05f012815cef60b611a9c7 [3] https://security-tracker.debian.org/tracker/CVE-2025-13462 Reference: https://nvd.nist.gov/vuln/detail/CVE-2025-13462 Signed-off-by: Sudhir Dumbhare --- .../python/python3/CVE-2025-13462.patch | 142 ++++++++++++++++++ .../python/python3_3.12.13.bb | 1 + 2 files changed, 143 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/CVE-2025-13462.patch diff --git a/meta/recipes-devtools/python/python3/CVE-2025-13462.patch b/meta/recipes-devtools/python/python3/CVE-2025-13462.patch new file mode 100644 index 0000000000..36d492338b --- /dev/null +++ b/meta/recipes-devtools/python/python3/CVE-2025-13462.patch @@ -0,0 +1,142 @@ +From 14d7d2e8f51a17c23c98f13f33743253a0b7a18a Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Mon, 18 May 2026 19:43:51 +0200 +Subject: [PATCH] [3.12] gh-141707: Skip TarInfo DIRTYPE normalization during + GNU long name handling (#145817) + +gh-141707: Skip TarInfo DIRTYPE normalization during GNU long name handling + +CVE: CVE-2025-13462 +Upstream-Status: Backport [https://github.com/python/cpython/commit/d10950739a78f54d0718d88fb5a868374603c084] + +Backport Changes: +- This file is not present in the current version and is therefore omitted + Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst + +(cherry picked from commit 42d754e34c06e57ad6b8e7f92f32af679912d8ab) + +Co-authored-by: Seth Michael Larson +Co-authored-by: Eashwar Ranganathan +(cherry picked from commit d10950739a78f54d0718d88fb5a868374603c084) +Signed-off-by: Sudhir Dumbhare +--- + Lib/tarfile.py | 29 +++++++++++++++++++++++++---- + Lib/test/test_tarfile.py | 19 +++++++++++++++++++ + Misc/ACKS | 1 + + 3 files changed, 45 insertions(+), 4 deletions(-) + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 99451aa765..70fdbe85b0 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -1246,6 +1246,20 @@ class TarInfo(object): + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. ++ ++ To support the old v7 tar format AREGTYPE headers are ++ transformed to DIRTYPE headers if their name ends in '/'. ++ """ ++ return cls._frombuf(buf, encoding, errors) ++ ++ @classmethod ++ def _frombuf(cls, buf, encoding, errors, *, dircheck=True): ++ """Construct a TarInfo object from a 512 byte bytes object. ++ ++ If ``dircheck`` is set to ``True`` then ``AREGTYPE`` headers will ++ be normalized to ``DIRTYPE`` if the name ends in a trailing slash. ++ ``dircheck`` must be set to ``False`` if this function is called ++ on a follow-up header such as ``GNUTYPE_LONGNAME``. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") +@@ -1276,7 +1290,7 @@ class TarInfo(object): + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. +- if obj.type == AREGTYPE and obj.name.endswith("/"): ++ if dircheck and obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused +@@ -1311,8 +1325,15 @@ class TarInfo(object): + """Return the next TarInfo object from TarFile object + tarfile. + """ ++ return cls._fromtarfile(tarfile) ++ ++ @classmethod ++ def _fromtarfile(cls, tarfile, *, dircheck=True): ++ """ ++ See dircheck documentation in _frombuf(). ++ """ + buf = tarfile.fileobj.read(BLOCKSIZE) +- obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) ++ obj = cls._frombuf(buf, tarfile.encoding, tarfile.errors, dircheck=dircheck) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + +@@ -1370,7 +1391,7 @@ class TarInfo(object): + + # Fetch the next header and process it. + try: +- next = self.fromtarfile(tarfile) ++ next = self._fromtarfile(tarfile, dircheck=False) + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None + +@@ -1505,7 +1526,7 @@ class TarInfo(object): + + # Fetch the next header. + try: +- next = self.fromtarfile(tarfile) ++ next = self._fromtarfile(tarfile, dircheck=False) + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None + +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 759fa03ead..82637841ed 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -1134,6 +1134,25 @@ class LongnameTest: + self.assertIsNotNone(tar.getmember(longdir)) + self.assertIsNotNone(tar.getmember(longdir.removesuffix('/'))) + ++ def test_longname_file_not_directory(self): ++ # Test reading a longname file and ensure it is not handled as a directory ++ # Issue #141707 ++ buf = io.BytesIO() ++ with tarfile.open(mode='w', fileobj=buf, format=self.format) as tar: ++ ti = tarfile.TarInfo() ++ ti.type = tarfile.AREGTYPE ++ ti.name = ('a' * 99) + '/' + ('b' * 3) ++ tar.addfile(ti) ++ ++ expected = {t.name: t.type for t in tar.getmembers()} ++ ++ buf.seek(0) ++ with tarfile.open(mode='r', fileobj=buf) as tar: ++ actual = {t.name: t.type for t in tar.getmembers()} ++ ++ self.assertEqual(expected, actual) ++ ++ + class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase): + + subdir = "gnu" +diff --git a/Misc/ACKS b/Misc/ACKS +index a6e63a991f..30d5f99ebb 100644 +--- a/Misc/ACKS ++++ b/Misc/ACKS +@@ -1492,6 +1492,7 @@ Dhushyanth Ramasamy + Ashwin Ramaswami + Jeff Ramnani + Bayard Randel ++Eashwar Ranganathan + Varpu Rantala + Brodie Rao + Rémi Rampin +-- +2.35.6 + diff --git a/meta/recipes-devtools/python/python3_3.12.13.bb b/meta/recipes-devtools/python/python3_3.12.13.bb index da23093285..ed9c210bf6 100644 --- a/meta/recipes-devtools/python/python3_3.12.13.bb +++ b/meta/recipes-devtools/python/python3_3.12.13.bb @@ -40,6 +40,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \ file://CVE-2026-4519_CVE-2026-4786.patch \ file://CVE-2026-6019_p1.patch \ file://CVE-2026-6019_p2.patch \ + file://CVE-2025-13462.patch \ " SRC_URI:append:class-native = " \