From 85ba67cd14cfbaa556a448d4d3f0226c0bc3e90b Mon Sep 17 00:00:00 2001 From: icanhasmath Date: Wed, 28 Oct 2026 12:27:39 -0500 Subject: [PATCH 1/2] Review follow-ups for 2.7.18.16: _socket debug link, SNI None ref, sddl.h Three small fixes raised in the reviews of #106 and #108: - socketmodule.c: remove socket_parse_timeout(). It came in with the CVE-2023-40217 getblocking() backport (47374069a24, first released in 2.7.18.10), has no callers, and calls _PyTime_FromSecondsObject(), which 2.7 never builds (Python/pytime.c is not compiled). Optimized builds drop the unused static function, but an -O0 or --with-pydebug build leaves an undefined symbol in _socket, so _socket (and ssl) fail to import. - _ssl.c: _servername_callback() set ssl_socket to Py_None without a reference when the SSL object has no Python socket, and the error path then did Py_DECREF(ssl_socket). Take the reference. This predates #106; it is not reachable through ssl.SSLSocket, which always sets ssl_sock. - posixmodule.c: include under MS_WINDOWS, as upstream does, instead of inside the _MSC_VER block, so it matches the MS_WINDOWS helpers that call ConvertStringSecurityDescriptorToSecurityDescriptorW (#108). Correction to the #108 commit message (386508c6c1d): it cites upstream's gh-118486 commit as eb29e2f590. The original main commit is 81939dad77 (GH-118488, 2024-05-02), followed by 8ed5466795 (OWNER RIGHTS) and 8af84b503d (gh-118773, the SDDL string the port uses). Co-Authored-By: Claude Opus 5.5 --- Modules/_ssl.c | 2 ++ Modules/posixmodule.c | 5 ++++- Modules/socketmodule.c | 41 ----------------------------------------- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index c8f07f92b2622e3..232fff61af61e63 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3472,7 +3472,9 @@ _servername_callback(SSL *s, int *al, void *args) Py_INCREF(sni_cb); if (ssl->ssl_sock == NULL) { + /* The error path below releases ssl_socket. */ ssl_socket = Py_None; + Py_INCREF(ssl_socket); } else { ssl_socket = PyWeakref_GetObject(ssl->ssl_sock); Py_INCREF(ssl_socket); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b26e87b99b107ec..4ad7de27c6206ec 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -278,11 +278,14 @@ extern int lstat(const char *, struct stat *); #include #include #include /* for ShellExecute() */ -#include /* for ConvertStringSecurityDescriptorToSecurityDescriptorW() */ #define popen _popen #define pclose _pclose #endif /* _MSC_VER */ +#ifdef MS_WINDOWS +#include /* for ConvertStringSecurityDescriptorToSecurityDescriptorW() */ +#endif + #if defined(PYCC_VACPP) && defined(PYOS_OS2) #include #endif /* OS2 */ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b145daf5c88b6df..69472cf2d95e9c4 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1836,47 +1836,6 @@ PyDoc_STRVAR(getblocking_doc, Returns True if socket is in blocking mode, or False if it\n\ is in non-blocking mode."); -static int -socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj) -{ -#ifdef MS_WINDOWS - struct timeval tv; -#endif -#ifndef HAVE_POLL - _PyTime_t ms; -#endif - int overflow = 0; - - if (timeout_obj == Py_None) { - *timeout = _PyTime_FromSeconds(-1); - return 0; - } - - if (_PyTime_FromSecondsObject(timeout, - timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) - return -1; - - if (*timeout < 0) { - PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); - return -1; - } - -#ifdef MS_WINDOWS - overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_TIMEOUT) < 0); -#endif -#ifndef HAVE_POLL - ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_TIMEOUT); - overflow |= (ms > INT_MAX); -#endif - if (overflow) { - PyErr_SetString(PyExc_OverflowError, - "timeout doesn't fit into C timeval"); - return -1; - } - - return 0; -} - /* s.settimeout(timeout) method. Argument: None -- no timeout, blocking mode; same as setblocking(True) 0.0 -- non-blocking mode; same as setblocking(False) From b9b77dbe0f98c1aa2082d6f1ee418f2848025668 Mon Sep 17 00:00:00 2001 From: icanhasmath Date: Wed, 28 Oct 2026 12:41:29 -0500 Subject: [PATCH 2/2] test_ssl: drop the third-party mock import Review follow-up (#111). test_ssl.py imported "from mock import Mock" (added with an earlier ssl backport, 37df9f76475, and in 2.7.18.14), but mock is not part of the 2.7 standard library, so on a plain build the whole module failed with "ImportError: No module named mock" and none of test_ssl ran. Mock itself was unused; the only mock use, mock.patch.dict(os.environ) in test_keylog_env, referred to a name the file never imported. Use support.EnvironmentVarGuard there instead and remove the import. (test_keylog_env is skipped on 2.7, whose _ssl has no keylog callback.) Co-Authored-By: Claude Opus 5.5 --- Lib/test/test_ssl.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 57ee6c37f0ce7e9..8c689f7aaa32768 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -6,8 +6,6 @@ from test import test_support as support from test.script_helper import assert_python_ok import asyncore -# import unittest.mock -from mock import Mock from test import support import re import socket @@ -3577,8 +3575,8 @@ def test_keylog_filename(self): "test is not compatible with ignore_environment") def test_keylog_env(self): self.addCleanup(support.unlink, support.TESTFN) - with mock.patch.dict(os.environ): - os.environ['SSLKEYLOGFILE'] = support.TESTFN + with support.EnvironmentVarGuard() as env: + env['SSLKEYLOGFILE'] = support.TESTFN self.assertEqual(os.environ['SSLKEYLOGFILE'], support.TESTFN) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS)