From f6304949bb9937e798ecac8b414606dc01bc6d3c Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 25 Oct 2023 16:42:18 +0300 Subject: [PATCH] gh-111230: Fix errors checking in _ssl module init (#111232) Introduce ADD_INT_CONST macro wrapper for PyModule_AddIntConstant() --- ...-10-23-22-40-47.gh-issue-111230.k3Jm84.rst | 1 + Modules/_ssl.c | 151 ++++++++---------- 2 files changed, 71 insertions(+), 81 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-10-23-22-40-47.gh-issue-111230.k3Jm84.rst diff --git a/Misc/NEWS.d/next/Library/2023-10-23-22-40-47.gh-issue-111230.k3Jm84.rst b/Misc/NEWS.d/next/Library/2023-10-23-22-40-47.gh-issue-111230.k3Jm84.rst new file mode 100644 index 00000000000..61d035853db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-23-22-40-47.gh-issue-111230.k3Jm84.rst @@ -0,0 +1 @@ +Fix :mod:`ssl` not checking for errors when initializing. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 82b30da2f4e..7bc30cb3529 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5787,52 +5787,44 @@ sslmodule_add_option(PyObject *m, const char *name, uint64_t value) static int sslmodule_init_constants(PyObject *m) { - PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", - PY_SSL_DEFAULT_CIPHER_STRING); + if (PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", + PY_SSL_DEFAULT_CIPHER_STRING) < 0) + { + return -1; + } - PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - PY_SSL_ERROR_ZERO_RETURN); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - PY_SSL_ERROR_WANT_READ); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - PY_SSL_ERROR_WANT_WRITE); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", - PY_SSL_ERROR_WANT_X509_LOOKUP); - PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", - PY_SSL_ERROR_SYSCALL); - PyModule_AddIntConstant(m, "SSL_ERROR_SSL", - PY_SSL_ERROR_SSL); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", - PY_SSL_ERROR_WANT_CONNECT); +#define ADD_INT_CONST(NAME, VALUE) do { \ + if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ + return -1; \ + } \ +} while (0) + + ADD_INT_CONST("SSL_ERROR_ZERO_RETURN", PY_SSL_ERROR_ZERO_RETURN); + ADD_INT_CONST("SSL_ERROR_WANT_READ", PY_SSL_ERROR_WANT_READ); + ADD_INT_CONST("SSL_ERROR_WANT_WRITE", PY_SSL_ERROR_WANT_WRITE); + ADD_INT_CONST("SSL_ERROR_WANT_X509_LOOKUP", PY_SSL_ERROR_WANT_X509_LOOKUP); + ADD_INT_CONST("SSL_ERROR_SYSCALL", PY_SSL_ERROR_SYSCALL); + ADD_INT_CONST("SSL_ERROR_SSL", PY_SSL_ERROR_SSL); + ADD_INT_CONST("SSL_ERROR_WANT_CONNECT", PY_SSL_ERROR_WANT_CONNECT); /* non ssl.h errorcodes */ - PyModule_AddIntConstant(m, "SSL_ERROR_EOF", - PY_SSL_ERROR_EOF); - PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", - PY_SSL_ERROR_INVALID_ERROR_CODE); + ADD_INT_CONST("SSL_ERROR_EOF", PY_SSL_ERROR_EOF); + ADD_INT_CONST("SSL_ERROR_INVALID_ERROR_CODE", + PY_SSL_ERROR_INVALID_ERROR_CODE); /* cert requirements */ - PyModule_AddIntConstant(m, "CERT_NONE", - PY_SSL_CERT_NONE); - PyModule_AddIntConstant(m, "CERT_OPTIONAL", - PY_SSL_CERT_OPTIONAL); - PyModule_AddIntConstant(m, "CERT_REQUIRED", - PY_SSL_CERT_REQUIRED); + ADD_INT_CONST("CERT_NONE", PY_SSL_CERT_NONE); + ADD_INT_CONST("CERT_OPTIONAL", PY_SSL_CERT_OPTIONAL); + ADD_INT_CONST("CERT_REQUIRED", PY_SSL_CERT_REQUIRED); /* CRL verification for verification_flags */ - PyModule_AddIntConstant(m, "VERIFY_DEFAULT", - 0); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_LEAF", - X509_V_FLAG_CRL_CHECK); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_CHAIN", - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", - X509_V_FLAG_X509_STRICT); - PyModule_AddIntConstant(m, "VERIFY_ALLOW_PROXY_CERTS", - X509_V_FLAG_ALLOW_PROXY_CERTS); - PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", - X509_V_FLAG_TRUSTED_FIRST); + ADD_INT_CONST("VERIFY_DEFAULT", 0); + ADD_INT_CONST("VERIFY_CRL_CHECK_LEAF", X509_V_FLAG_CRL_CHECK); + ADD_INT_CONST("VERIFY_CRL_CHECK_CHAIN", + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + ADD_INT_CONST("VERIFY_X509_STRICT", X509_V_FLAG_X509_STRICT); + ADD_INT_CONST("VERIFY_ALLOW_PROXY_CERTS", X509_V_FLAG_ALLOW_PROXY_CERTS); + ADD_INT_CONST("VERIFY_X509_TRUSTED_FIRST", X509_V_FLAG_TRUSTED_FIRST); #ifdef X509_V_FLAG_PARTIAL_CHAIN - PyModule_AddIntConstant(m, "VERIFY_X509_PARTIAL_CHAIN", - X509_V_FLAG_PARTIAL_CHAIN); + ADD_INT_CONST("VERIFY_X509_PARTIAL_CHAIN", X509_V_FLAG_PARTIAL_CHAIN); #endif /* Alert Descriptions from ssl.h */ @@ -5840,7 +5832,7 @@ sslmodule_init_constants(PyObject *m) /* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 */ #define ADD_AD_CONSTANT(s) \ - PyModule_AddIntConstant(m, "ALERT_DESCRIPTION_"#s, \ + ADD_INT_CONST("ALERT_DESCRIPTION_"#s, \ SSL_AD_##s) ADD_AD_CONSTANT(CLOSE_NOTIFY); @@ -5888,23 +5880,15 @@ sslmodule_init_constants(PyObject *m) /* protocol versions */ #ifndef OPENSSL_NO_SSL3 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", - PY_SSL_VERSION_SSL3); + ADD_INT_CONST("PROTOCOL_SSLv3", PY_SSL_VERSION_SSL3); #endif - PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_CLIENT", - PY_SSL_VERSION_TLS_CLIENT); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_SERVER", - PY_SSL_VERSION_TLS_SERVER); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", - PY_SSL_VERSION_TLS1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1", - PY_SSL_VERSION_TLS1_1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", - PY_SSL_VERSION_TLS1_2); + ADD_INT_CONST("PROTOCOL_SSLv23", PY_SSL_VERSION_TLS); + ADD_INT_CONST("PROTOCOL_TLS", PY_SSL_VERSION_TLS); + ADD_INT_CONST("PROTOCOL_TLS_CLIENT", PY_SSL_VERSION_TLS_CLIENT); + ADD_INT_CONST("PROTOCOL_TLS_SERVER", PY_SSL_VERSION_TLS_SERVER); + ADD_INT_CONST("PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1); + ADD_INT_CONST("PROTOCOL_TLSv1_1", PY_SSL_VERSION_TLS1_1); + ADD_INT_CONST("PROTOCOL_TLSv1_2", PY_SSL_VERSION_TLS1_2); #define ADD_OPTION(NAME, VALUE) if (sslmodule_add_option(m, NAME, (VALUE)) < 0) return -1 @@ -5949,50 +5933,52 @@ sslmodule_init_constants(PyObject *m) ADD_OPTION("OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS); #endif +#undef ADD_OPTION + #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", - X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); + ADD_INT_CONST("HOSTFLAG_ALWAYS_CHECK_SUBJECT", + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); #endif #ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_NEVER_CHECK_SUBJECT", - X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); + ADD_INT_CONST("HOSTFLAG_NEVER_CHECK_SUBJECT", + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); #endif #ifdef X509_CHECK_FLAG_NO_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_WILDCARDS", - X509_CHECK_FLAG_NO_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_NO_WILDCARDS", + X509_CHECK_FLAG_NO_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_PARTIAL_WILDCARDS", - X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_NO_PARTIAL_WILDCARDS", + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_MULTI_LABEL_WILDCARDS", - X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_MULTI_LABEL_WILDCARDS", + X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - PyModule_AddIntConstant(m, "HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", - X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); + ADD_INT_CONST("HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", + X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); #endif /* file types */ - PyModule_AddIntConstant(m, "ENCODING_PEM", PY_SSL_ENCODING_PEM); - PyModule_AddIntConstant(m, "ENCODING_DER", PY_SSL_ENCODING_DER); + ADD_INT_CONST("ENCODING_PEM", PY_SSL_ENCODING_PEM); + ADD_INT_CONST("ENCODING_DER", PY_SSL_ENCODING_DER); /* protocol versions */ - PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", - PY_PROTO_MINIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_MAXIMUM_SUPPORTED", - PY_PROTO_MAXIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_SSLv3", PY_PROTO_SSLv3); - PyModule_AddIntConstant(m, "PROTO_TLSv1", PY_PROTO_TLSv1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_1", PY_PROTO_TLSv1_1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_2", PY_PROTO_TLSv1_2); - PyModule_AddIntConstant(m, "PROTO_TLSv1_3", PY_PROTO_TLSv1_3); + ADD_INT_CONST("PROTO_MINIMUM_SUPPORTED", PY_PROTO_MINIMUM_SUPPORTED); + ADD_INT_CONST("PROTO_MAXIMUM_SUPPORTED", PY_PROTO_MAXIMUM_SUPPORTED); + ADD_INT_CONST("PROTO_SSLv3", PY_PROTO_SSLv3); + ADD_INT_CONST("PROTO_TLSv1", PY_PROTO_TLSv1); + ADD_INT_CONST("PROTO_TLSv1_1", PY_PROTO_TLSv1_1); + ADD_INT_CONST("PROTO_TLSv1_2", PY_PROTO_TLSv1_2); + ADD_INT_CONST("PROTO_TLSv1_3", PY_PROTO_TLSv1_3); #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ - PyModule_AddObjectRef((m), (key), bool_obj); \ + if (PyModule_AddObjectRef((m), (key), bool_obj) < 0) { \ + return -1; \ + } \ } while (0) addbool(m, "HAS_SNI", 1); @@ -6033,6 +6019,9 @@ sslmodule_init_constants(PyObject *m) addbool(m, "HAS_TLSv1_3", 0); #endif +#undef addbool +#undef ADD_INT_CONST + return 0; }