- Update to 3.13.7:

- gh-137583: Fix a deadlock introduced in 3.13.6 when a call
    to ssl.SSLSocket.recv was blocked in one thread, and then
    another method on the object (such as ssl.SSLSocket.send) was
    subsequently called in another thread.
  - gh-137044: Return large limit values as positive integers
    instead of negative integers in resource.getrlimit().
    Accept large values and reject negative values (except
    RLIM_INFINITY) for limits in resource.setrlimit().
  - gh-136914: Fix retrieval of doctest.DocTest.lineno
    for objects decorated with functools.cache() or
    functools.cached_property.
  - gh-131788: Make ResourceTracker.send from multiprocessing
    re-entrant safe
  - gh-136155: We are now checking for fatal errors in EPUB
    builds in CI.
  - gh-137400: Fix a crash in the free threading build when
    disabling profiling or tracing across all threads with
    PyEval_SetProfileAllThreads() or PyEval_SetTraceAllThreads()
    or their Python equivalents threading.settrace_all_threads()
    and threading.setprofile_all_threads().
- Remove upstreamed patch:
  - gh137583-only-lock-SSL-context.patch

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=119
This commit is contained in:
2025-08-15 12:33:36 +00:00
committed by Git OBS Bridge
parent 6ca12749fe
commit f819c56b57
7 changed files with 32 additions and 195 deletions

BIN
Python-3.13.6.tar.xz (Stored with Git LFS)

Binary file not shown.

File diff suppressed because one or more lines are too long

BIN
Python-3.13.7.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyTCCAlCgAwIBAgIUZMI+1qoqVltZwoOEGQ4+re/SlS4wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwODE0MTM0OTQyWhcNMjUwODE0MTM1OTQyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkKFnh1U6aDYKiIU0p7mtDbbxTezpcJrivGvrwtuUviVav74GRKEp/vcRZnlnVn6olDcrk33qi78husSHeD1VN6OCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUaes5BWscCJHaWxt5BY13fiF+sb8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGYqNf2TAAABAMARzBFAiB3VC3ZdiYFvHtFHxRfU4vdiUZjC+VM/cY0nUHpRZ+aqQIhALglsfszSnn7LZNgw3no+XTnlO+mzMAdCLArnFKuyQo0MAoGCCqGSM49BAMDA2cAMGQCME73khzLHp2xLGwh1g0U5yt9CZu0YfQ52BJ0gL3J2adJsuCvmr76YbDnGWOM2IJLYwIwbWuLaywCs9V1hHqx4IewPWU6kGTDL2p3t7RMb7OK9etOkF4xHxV9IaGZZSFwDmSC"}, "tlogEntries": [{"logIndex": "394375946", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1755179382", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDofYinceCg3x7ldRHdwLc7aoB6pX2+kukjFdQXFflKdwIhAK7YnONsVnbwsSZpLex8Q7tSMHHglIEQaqavuKAD5taI"}, "inclusionProof": {"logIndex": "272471684", "rootHash": "D6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=", "treeSize": "272471685", "hashes": ["12rv4cU8JBEnhl8jcQleuU0gXnRpH2B6oGsUtKoIBHQ=", "PXscKvmfKyXbaxsj99FlqImW6Bg1k3WBNWtHTzgtSVk=", "BaDXQZRZZLXILekCZ5e2TyrtJiYKeNUb2BW6hgybhG0=", "IQvrVF5nsAhxYBjFEIIqcy67H9HEwRdM5XEvXGMlcSc=", "I/JNRoCea85lOiusHIKoAblvRmo6NwnDAtfOV/JiSvQ=", "CjR2KouFHnbUwdf0xk9/f1IcsYFdo4/LMKPy9TV0keM=", "uSQzyFvNic+ZM0goS8qbxn95hvb1YCdWvV0/TnqHDEg=", "LM7bDk+koNXHbb9JB2IH+truLnDDC6WfDzp12zjdFkQ=", "4k9InE/ch3n4a/TapEK+nqfXhlMZEcbvL849wNGtBuo=", "6QfFjG3kfyjFx5PdzVrWBdbNza9Mf4ldecvoXhR3Ip8=", "RllwumeGwAfTxo/zlW3B2deC36+2Lu0FY/hP+QL2aT8=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n272471685\nD6O1d0rPsmFUhblg+N/WsWhcTQVKMGbTlauX5huq8Q0=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBr7yQXNBvCAOgKzReWm4ERI79K22ifVZFn9VUxx5nSxQIgWIPYVrO1E+vP3VRWPptUMs1arlLguTIMkT1tX5WCRoM=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NDYyZjkwOTlkZmQzMGUyMzhkZWY4M2M3MWQ5MTg5N2Q4Y2FhNWZmNmViYzdhNTBmMTRkNDgwMmNkYWFhNzlhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUR4RjM5Z0VUZDgvUWMwbHd5Sk5Mbk5NK3RrTmozaEYyWE1DelZDdjZXOEJBSWdkQUxIWTl3MU14bVNKYUNKMlNtL1p5QWRrL1gwSVF4THFENHA3TSt5UzZRPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVWRU5EUVd4RFowRjNTVUpCWjBsVldrMUpLekZ4YjNGV2JIUmFkMjlQUlVkUk5DdHlaUzlUYkZNMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUlRCTlZFMHdUMVJSZVZkb1kwNU5hbFYzVDBSRk1FMVVUVEZQVkZGNVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZyUzBadWFERlZObUZFV1V0cFNWVXdjRGR0ZEVSaVluaFVaWHB3WTBweWFYWkhkbklLZDNSMVZYWnBWbUYyTnpSSFVrdEZjQzkyWTFKYWJteHVWbTQyYjJ4RVkzSnJNek54YVRjNGFIVnpVMGhsUkRGV1RqWlBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZoWlhNMUNrSlhjMk5EU2toaFYzaDBOVUpaTVRObWFVWXJjMkk0ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV1hGT1pqSlVRVUZCUWtGTlFRcFNla0pHUVdsQ00xWkRNMXBrYVZsR2RraDBSa2g0VW1aVk5IWmthVlZhYWtNclZrMHZZMWt3YmxWSWNGSmFLMkZ4VVVsb1FVeG5iSE5tYzNwVGJtNDNDa3hhVG1kM00yNXZLMWhVYm14UEsyMTZUVUZrUTB4QmNtNUdTM1Y1VVc4d1RVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVkwRk5SMUZEVFVVM00ydG9la3dLU0hBeWVFeEhkMmd4WnpCVk5YbDBPVU5hZFRCWlpsRTFNa0pLTUdkTU0wb3lZV1JLYzNWRGRtMXlOelpaWWtSdVIxZFBUVEpKU2t4WmQwbDNZbGQxVEFwaGVYZERjemxXTVdoSWNYZzBTV1YzVUZkVk5tdEhWRVJNTW5BemREZFNUV0kzVDBzNVpYUlBhMFkwZUVoNFZqbEpZVWRhV2xOR2QwUnRVME1LTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "VGL5CZ39MOI43vg8cdkYl9jKpf9uvHpQ8U1IAs2qp5o="}, "signature": "MEUCIQDxF39gETd8/Qc0lwyJNLnNM+tkNj3hF2XMCzVCv6W8BAIgdALHY9w1MxmSJaCJ2Sm/ZyAdk/X0IQxLqD4p7M+yS6Q="}}

View File

@@ -1,187 +0,0 @@
---
Lib/test/test_ssl.py | 36 ++++++++++
Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst | 4 +
Modules/_ssl.c | 33 ++++-----
Modules/_ssl/debughelpers.c | 1
4 files changed, 57 insertions(+), 17 deletions(-)
Index: Python-3.13.6/Lib/test/test_ssl.py
===================================================================
--- Python-3.13.6.orig/Lib/test/test_ssl.py 2025-08-06 15:05:20.000000000 +0200
+++ Python-3.13.6/Lib/test/test_ssl.py 2025-08-12 21:19:23.884259654 +0200
@@ -4584,6 +4584,42 @@
with client_context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
+ def test_thread_recv_while_main_thread_sends(self):
+ # GH-137583: Locking was added to calls to send() and recv() on SSL
+ # socket objects. This seemed fine at the surface level because those
+ # calls weren't re-entrant, but recv() calls would implicitly mimick
+ # holding a lock by blocking until it received data. This means that
+ # if a thread started to infinitely block until data was received, calls
+ # to send() would deadlock, because it would wait forever on the lock
+ # that the recv() call held.
+ data = b"1" * 1024
+ event = threading.Event()
+ def background(sock):
+ event.set()
+ received = sock.recv(len(data))
+ self.assertEqual(received, data)
+
+ client_context, server_context, hostname = testing_context()
+ server = ThreadedEchoServer(context=server_context)
+ with server:
+ with client_context.wrap_socket(socket.socket(),
+ server_hostname=hostname) as sock:
+ sock.connect((HOST, server.port))
+ sock.settimeout(1)
+ sock.setblocking(1)
+ # Ensure that the server is ready to accept requests
+ sock.sendall(b"123")
+ self.assertEqual(sock.recv(3), b"123")
+ with threading_helper.catch_threading_exception() as cm:
+ thread = threading.Thread(target=background,
+ args=(sock,), daemon=True)
+ thread.start()
+ event.wait()
+ sock.sendall(data)
+ thread.join()
+ if cm.exc_value is not None:
+ raise cm.exc_value
+
@unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3")
class TestPostHandshakeAuth(unittest.TestCase):
Index: Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ Python-3.13.6/Misc/NEWS.d/next/Library/2025-08-09-08-53-32.gh-issue-137583.s6OZud.rst 2025-08-12 21:19:23.885093243 +0200
@@ -0,0 +1,4 @@
+Fix a deadlock introduced in 3.13.6 when a call to
+:meth:`ssl.SSLSocket.recv <socket.socket.recv>` was blocked in one thread,
+and then another method on the object (such as :meth:`ssl.SSLSocket.send <socket.socket.send>`)
+was subsequently called in another thread.
Index: Python-3.13.6/Modules/_ssl.c
===================================================================
--- Python-3.13.6.orig/Modules/_ssl.c 2025-08-06 15:05:20.000000000 +0200
+++ Python-3.13.6/Modules/_ssl.c 2025-08-12 21:19:23.886222384 +0200
@@ -332,9 +332,6 @@
* and shutdown methods check for chained exceptions.
*/
PyObject *exc;
- /* Lock to synchronize calls when the thread state is detached.
- See also gh-134698. */
- PyMutex tstate_mutex;
} PySSLSocket;
typedef struct {
@@ -846,7 +843,6 @@
self->server_hostname = NULL;
self->err = err;
self->exc = NULL;
- self->tstate_mutex = (PyMutex){0};
/* Make sure the SSL error state is initialized */
ERR_clear_error();
@@ -919,12 +915,12 @@
BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
}
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS;
if (socket_type == PY_SSL_CLIENT)
SSL_set_connect_state(self->ssl);
else
SSL_set_accept_state(self->ssl);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
self->socket_type = socket_type;
if (sock != NULL) {
@@ -993,10 +989,11 @@
/* Actually negotiate SSL connection */
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
do {
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS
ret = SSL_do_handshake(self->ssl);
err = _PySSL_errno(ret < 1, self->ssl, ret);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
+ _PySSL_FIX_ERRNO;
self->err = err;
if (PyErr_CheckSignals())
@@ -2462,10 +2459,11 @@
}
do {
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS;
retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count);
err = _PySSL_errno(retval == 0, self->ssl, retval);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
+ _PySSL_FIX_ERRNO;
self->err = err;
if (PyErr_CheckSignals())
@@ -2523,10 +2521,11 @@
int count = 0;
_PySSLError err;
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS;
count = SSL_pending(self->ssl);
err = _PySSL_errno(count < 0, self->ssl, count);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
+ _PySSL_FIX_ERRNO;
self->err = err;
if (count < 0)
@@ -2617,10 +2616,11 @@
deadline = _PyDeadline_Init(timeout);
do {
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS;
retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count);
err = _PySSL_errno(retval == 0, self->ssl, retval);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
+ _PySSL_FIX_ERRNO;
self->err = err;
if (PyErr_CheckSignals())
@@ -2719,7 +2719,7 @@
}
while (1) {
- PySSL_BEGIN_ALLOW_THREADS(self)
+ Py_BEGIN_ALLOW_THREADS;
/* Disable read-ahead so that unwrap can work correctly.
* Otherwise OpenSSL might read in too much data,
* eating clear text data that happens to be
@@ -2732,7 +2732,8 @@
SSL_set_read_ahead(self->ssl, 0);
ret = SSL_shutdown(self->ssl);
err = _PySSL_errno(ret < 0, self->ssl, ret);
- PySSL_END_ALLOW_THREADS(self)
+ Py_END_ALLOW_THREADS;
+ _PySSL_FIX_ERRNO;
self->err = err;
/* If err == 1, a secure shutdown with SSL_shutdown() is complete */
Index: Python-3.13.6/Modules/_ssl/debughelpers.c
===================================================================
--- Python-3.13.6.orig/Modules/_ssl/debughelpers.c 2025-08-06 15:05:20.000000000 +0200
+++ Python-3.13.6/Modules/_ssl/debughelpers.c 2025-08-12 21:19:23.886886469 +0200
@@ -135,7 +135,6 @@
* critical debug helper.
*/
- assert(PyMutex_IsLocked(&ssl_obj->tstate_mutex));
Py_BEGIN_ALLOW_THREADS
PyThread_acquire_lock(lock, 1);
res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line);

View File

@@ -1,3 +1,30 @@
-------------------------------------------------------------------
Fri Aug 15 12:31:08 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Update to 3.13.7:
- gh-137583: Fix a deadlock introduced in 3.13.6 when a call
to ssl.SSLSocket.recv was blocked in one thread, and then
another method on the object (such as ssl.SSLSocket.send) was
subsequently called in another thread.
- gh-137044: Return large limit values as positive integers
instead of negative integers in resource.getrlimit().
Accept large values and reject negative values (except
RLIM_INFINITY) for limits in resource.setrlimit().
- gh-136914: Fix retrieval of doctest.DocTest.lineno
for objects decorated with functools.cache() or
functools.cached_property.
- gh-131788: Make ResourceTracker.send from multiprocessing
re-entrant safe
- gh-136155: We are now checking for fatal errors in EPUB
builds in CI.
- gh-137400: Fix a crash in the free threading build when
disabling profiling or tracing across all threads with
PyEval_SetProfileAllThreads() or PyEval_SetTraceAllThreads()
or their Python equivalents threading.settrace_all_threads()
and threading.setprofile_all_threads().
- Remove upstreamed patch:
- gh137583-only-lock-SSL-context.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Aug 12 09:16:40 UTC 2025 - Matej Cepl <mcepl@cepl.eu> Tue Aug 12 09:16:40 UTC 2025 - Matej Cepl <mcepl@cepl.eu>

View File

@@ -167,7 +167,7 @@
# _md5.cpython-38m-x86_64-linux-gnu.so # _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so %define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix} Name: %{python_pkg_name}%{psuffix}
Version: 3.13.6 Version: 3.13.7
%define tarversion %{version} %define tarversion %{version}
%define tarname Python-%{tarversion} %define tarname Python-%{tarversion}
Release: 0 Release: 0
@@ -231,9 +231,6 @@ Patch42: gh126985-mv-pyvenv.cfg2getpath.patch
# PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com # PATCH-FIX-UPSTREAM bsc1243155-sphinx-non-determinism.patch bsc#1243155 mcepl@suse.com
# Doc: Generate ids for audit_events using docname # Doc: Generate ids for audit_events using docname
Patch43: bsc1243155-sphinx-non-determinism.patch Patch43: bsc1243155-sphinx-non-determinism.patch
# PATCH-FIX-UPSTREAM gh137583-only-lock-SSL-context.patch gh#python/cpython#137583 mcepl@suse.com
# Only lock the SSL context, not the SSL socket
Patch44: gh137583-only-lock-SSL-context.patch
BuildRequires: autoconf-archive BuildRequires: autoconf-archive
BuildRequires: automake BuildRequires: automake
BuildRequires: fdupes BuildRequires: fdupes