[oe][meta-python][wrynose][PATCH 05/10] python3-aiohttp: fix CVE-2026-54275
"Darsh Kelaiya -X (dkelaiya - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]>
| Newsgroups | org.openembedded.lists.openembedded-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Darsh Kelaiya <[email protected]> This patch applies the upstream fix as referenced in [2], using the commit shown in [1]. [1] https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0 [2] https://github.com/advisories/GHSA-4m7w-qmgq-4wj5 Signed-off-by: Darsh Kelaiya <[email protected]> --- .../python3-aiohttp/CVE-2026-54275.patch | 115 ++++++++++++++++++ .../python/python3-aiohttp_3.13.5.bb | 1 + 2 files changed, 116 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch diff --git a/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch new file mode 100644 index 0000000000..f6e748b2f6 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch @@ -0,0 +1,115 @@ +From 23328dc1950071dd1e05ac6aeb631874ef94afe3 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" <[email protected]> +Date: Sun, 7 Jun 2026 00:30:30 -0500 +Subject: [PATCH] [PR #12835/1e94b3e8 backport][3.14] Tls server hostname pool + key (#12847) + +CVE: CVE-2026-54275 +Upstream-Status: Backport [https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0] + +(cherry picked from commit 0ca2b6c28a25726527a8b60f25960262a91ed0e0) +Signed-off-by: Darsh Kelaiya <[email protected]> +--- + CHANGES/12835.bugfix.rst | 1 + + aiohttp/client_reqrep.py | 2 ++ + tests/test_client_functional.py | 31 +++++++++++++++++++++++++++++++ + tests/test_client_request.py | 16 ++++++++++++++++ + 4 files changed, 50 insertions(+) + create mode 100644 CHANGES/12835.bugfix.rst + +diff --git a/CHANGES/12835.bugfix.rst b/CHANGES/12835.bugfix.rst +new file mode 100644 +index 000000000..84a8ae006 +--- /dev/null ++++ b/CHANGES/12835.bugfix.rst +@@ -0,0 +1 @@ ++Included the per-request ``server_hostname`` override in the :class:`~aiohttp.TCPConnector` connection pool key, so a pooled TLS connection is no longer reused for a request that sets ``server_hostname`` to a different value -- by :user:`bdraco`. +diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py +index a9e079589..5fe83fa88 100644 +--- a/aiohttp/client_reqrep.py ++++ b/aiohttp/client_reqrep.py +@@ -255,6 +255,7 @@ class ConnectionKey(NamedTuple): + proxy: Optional[URL] + proxy_auth: Optional[BasicAuth] + proxy_headers_hash: Optional[int] # hash(CIMultiDict) ++ server_hostname: str | None = None + + + def _is_expected_content_type( +@@ -964,6 +965,7 @@ class ClientRequest: + self.proxy, + self.proxy_auth, + h, ++ self.server_hostname, + ), + ) + +diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py +index ea31567c4..60caf6e2a 100644 +--- a/tests/test_client_functional.py ++++ b/tests/test_client_functional.py +@@ -720,6 +720,37 @@ async def test_ssl_client( + assert txt == "Test message" + + ++async def test_server_hostname_override_not_reused( ++ aiohttp_server: AiohttpServer, ++) -> None: ++ """A pooled TLS connection must not be reused for a different server_hostname.""" ++ trustme = pytest.importorskip("trustme") ++ ++ ca = trustme.CA() ++ cert = ca.issue_cert("first.example") ++ server_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ++ cert.configure_cert(server_ctx) ++ client_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) ++ ca.configure_trust(client_ctx) ++ ++ async def handler(request: web.Request) -> web.Response: ++ return web.Response(text="ok") ++ ++ app = web.Application() ++ app.router.add_route("GET", "/", handler) ++ server = await aiohttp_server(app, ssl=server_ctx) ++ url = server.make_url("/") ++ ++ connector = aiohttp.TCPConnector(ssl=client_ctx, limit=1, limit_per_host=1) ++ async with aiohttp.ClientSession(connector=connector) as session: ++ async with session.get(url, server_hostname="first.example") as resp: ++ assert resp.status == 200 ++ await resp.read() ++ ++ with pytest.raises(aiohttp.ClientConnectorCertificateError): ++ await session.get(url, server_hostname="second.example") ++ ++ + @pytest.mark.skipif( + sys.version_info < (3, 11), reason="ssl_shutdown_timeout requires Python 3.11+" + ) +diff --git a/tests/test_client_request.py b/tests/test_client_request.py +index e3cdc1c62..4c91245a5 100644 +--- a/tests/test_client_request.py ++++ b/tests/test_client_request.py +@@ -1611,6 +1611,22 @@ async def test_connection_key_without_proxy() -> None: + await req.close() + + ++async def test_connection_key_includes_server_hostname( ++ make_request: _RequestMaker, ++) -> None: ++ """A server_hostname override must be part of the connection reuse key.""" ++ url = URL("https://127.0.0.1:8443/") ++ none_req = make_request("GET", url) ++ first = make_request("GET", url, server_hostname="first.example") ++ first_again = make_request("GET", url, server_hostname="first.example") ++ second = make_request("GET", url, server_hostname="second.example") ++ ++ assert first.connection_key.server_hostname == "first.example" ++ assert first.connection_key != none_req.connection_key ++ assert first.connection_key != second.connection_key ++ assert first.connection_key == first_again.connection_key ++ ++ + def test_request_info_back_compat() -> None: + """Test RequestInfo can be created without real_url.""" + url = URL("http://example.com") diff --git a/meta-python/recipes-devtools/python/python3-aiohttp_3.13.5.bb b/meta-python/recipes-devtools/python/python3-aiohttp_3.13.5.bb index a40f522e4d..c70e4d025f 100644 --- a/meta-python/recipes-devtools/python/python3-aiohttp_3.13.5.bb +++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.13.5.bb @@ -11,6 +11,7 @@ SRC_URI += " \ file://CVE-2026-47265.patch \ file://CVE-2026-50269.patch \ file://CVE-2026-54274.patch \ + file://CVE-2026-54275.patch \ " CVE_PRODUCT = "aiohttp" -- 2.35.6