package/python-pyopenssl: patch CVE-2026-274{48, 59}

- CVE-2026-27448:
    pyOpenSSL is a Python wrapper around the OpenSSL library. Starting in
    version 0.14.0 and prior to version 26.0.0, if a user provided
    callback to `set_tlsext_servername_callback` raised an unhandled
    exception, this would result in a connection being accepted. If a user
    was relying on this callback for any security-sensitive behavior, this
    could allow bypassing it. Starting in version 26.0.0, unhandled
    exceptions now result in rejecting the connection.

For more information, see:
 - https://www.cve.org/CVERecord?id=CVE-2026-27448
 - d41a814759

- CVE-2026-27459:
    pyOpenSSL is a Python wrapper around the OpenSSL library. Starting in
    version 22.0.0 and prior to version 26.0.0, if a user provided
    callback to `set_cookie_generate_callback` returned a cookie value
    greater than 256 bytes, pyOpenSSL would overflow an OpenSSL provided
    buffer. Starting in version 26.0.0, cookie values that are too long
    are now rejected.

For more information, see:
 - https://www.cve.org/CVERecord?id=CVE-2026-27459
 - 57f09bb4bb

(cherry picked from commit 7bcba8498b)
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
This commit is contained in:
Thomas Perale
2026-05-13 12:39:09 +02:00
parent d0f4287127
commit aebe1b2054
3 changed files with 102 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
From d41a814759a9fb49584ca8ab3f7295de49a85aa0 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Mon, 16 Feb 2026 21:04:37 -0500
Subject: [PATCH] Handle exceptions in set_tlsext_servername_callback callbacks
(#1478)
When the servername callback raises an exception, call sys.excepthook
with the exception info and return SSL_TLSEXT_ERR_ALERT_FATAL to abort
the handshake. Previously, exceptions would propagate uncaught through
the CFFI callback boundary.
https://claude.ai/code/session_01P7y1XmWkdtC5UcmZwGDvGi
Co-authored-by: Claude <noreply@anthropic.com>
Upstream: https://github.com/pyca/pyopenssl/commit/d41a814759a9fb49584ca8ab3f7295de49a85aa0
CVE: CVE-2026-27448
[thomas: backported, stripped tests and changelog]
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
src/OpenSSL/SSL.py | 7 ++++++-
1 files changed, 7 insertions(+)
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index 4db5240..a6263c4 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -2,6 +2,7 @@
import os
import socket
+import sys
import typing
import warnings
from collections.abc import Sequence
@@ -1686,7 +1687,11 @@ class Context:
@wraps(callback)
def wrapper(ssl, alert, arg): # type: ignore[no-untyped-def]
- callback(Connection._reverse_mapping[ssl])
+ try:
+ callback(Connection._reverse_mapping[ssl])
+ except Exception:
+ sys.excepthook(*sys.exc_info())
+ return _lib.SSL_TLSEXT_ERR_ALERT_FATAL
return 0
self._tlsext_servername_callback = _ffi.callback(
--
2.43.0

View File

@@ -0,0 +1,46 @@
From 57f09bb4bb051d3bc2a1abd36e9525313d5cd408 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Wed, 18 Feb 2026 07:46:15 -0500
Subject: [PATCH] Fix buffer overflow in DTLS cookie generation callback
(#1479)
The cookie generate callback copied user-returned bytes into a
fixed-size native buffer without enforcing a maximum length. A
callback returning more than DTLS1_COOKIE_LENGTH bytes would overflow
the OpenSSL-provided buffer, corrupting adjacent memory.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Upstream: https://github.com/pyca/pyopenssl/commit/57f09bb4bb051d3bc2a1abd36e9525313d5cd408
CVE: CVE-2026-27459
[thomas: backported, stripped tests and changelog]
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
src/OpenSSL/SSL.py | 7 +++++++
1 files changed, 7 insertions(+)
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index a6263c4..2e4da78 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -716,11 +716,18 @@ class _CookieGenerateCallbackHelper(_CallbackExceptionHelper):
def __init__(self, callback: _CookieGenerateCallback) -> None:
_CallbackExceptionHelper.__init__(self)
+ max_cookie_len = getattr(_lib, "DTLS1_COOKIE_LENGTH", 255)
+
@wraps(callback)
def wrapper(ssl, out, outlen): # type: ignore[no-untyped-def]
try:
conn = Connection._reverse_mapping[ssl]
cookie = callback(conn)
+ if len(cookie) > max_cookie_len:
+ raise ValueError(
+ f"Cookie too long (got {len(cookie)} bytes, "
+ f"max {max_cookie_len})"
+ )
out[0 : len(cookie)] = cookie
outlen[0] = len(cookie)
return 1
--
2.43.0

View File

@@ -13,4 +13,10 @@ PYTHON_PYOPENSSL_CPE_ID_VENDOR = pyopenssl
PYTHON_PYOPENSSL_CPE_ID_PRODUCT = pyopenssl
PYTHON_PYOPENSSL_SETUP_TYPE = setuptools
# 0001-CVE-2026-27448.patch
PYTHON_PYOPENSSL_IGNORE_CVES += CVE-2026-27448
# 0002-CVE-2026-27459.patch
PYTHON_PYOPENSSL_IGNORE_CVES += CVE-2026-27459
$(eval $(python-package))