Skip to content

Commit 18d11b8

Browse files
gh-156228: Use PyMem_Raw* allocators for OpenSSL in _ssl and _hashlib
Install OpenSSL memory hooks with CRYPTO_set_mem_functions() when _ssl or _hashlib is loaded, routing OpenSSL allocations through the raw memory allocators so they are visible to tracemalloc and custom allocators. Installation fails benignly if another libcrypto user allocated first.
1 parent 999a046 commit 18d11b8

9 files changed

Lines changed: 88 additions & 2 deletions

File tree

Makefile.pre.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3461,7 +3461,7 @@ MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h
34613461
MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h
34623462
MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@
34633463
MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@
3464-
MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h
3464+
MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h $(srcdir)/Modules/_openssl_mem.h
34653465
MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h
34663466
MODULE__REMOTE_DEBUGGING_DEPS=$(srcdir)/Modules/_remote_debugging/_remote_debugging.h $(srcdir)/Modules/_remote_debugging/gc_stats.h
34673467

@@ -3480,7 +3480,7 @@ MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_
34803480
MODULE__HMAC_LDEPS=$(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@)
34813481

34823482
MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c
3483-
MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h
3483+
MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_openssl_mem.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h
34843484
MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/util.h
34853485
MODULE__TESTLIMITEDCAPI_DEPS=$(srcdir)/Modules/_testlimitedcapi/testcapi_long.h $(srcdir)/Modules/_testlimitedcapi/parts.h $(srcdir)/Modules/_testlimitedcapi/util.h
34863486
MODULE__TESTINTERNALCAPI_DEPS=$(srcdir)/Modules/_testinternalcapi/parts.h $(srcdir)/Python/ceval.h $(srcdir)/Modules/_testinternalcapi/test_targets.h $(srcdir)/Modules/_testinternalcapi/test_cases.c.h
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The :mod:`ssl` and :mod:`hashlib` modules now route OpenSSL memory
2+
allocations through the Python raw memory allocators, making OpenSSL memory
3+
usage visible to :mod:`tracemalloc` and to custom allocators installed with
4+
:c:func:`PyMem_SetAllocator`.

Modules/_hashopenssl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "pycore_strhex.h" // _Py_strhex()
2828
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_RELAXED
2929
#include "hashlib.h"
30+
#include "_openssl_mem.h"
3031

3132
/* EVP is the preferred interface to hashing in OpenSSL */
3233
#include <openssl/evp.h>
@@ -2933,5 +2934,6 @@ static struct PyModuleDef _hashlibmodule = {
29332934
PyMODINIT_FUNC
29342935
PyInit__hashlib(void)
29352936
{
2937+
_PyOpenSSL_SetupMemFunctions();
29362938
return PyModuleDef_Init(&_hashlibmodule);
29372939
}

Modules/_openssl_mem.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Route OpenSSL allocations through the raw memory allocators.
2+
// Shared by the _ssl and _hashlib modules.
3+
4+
#ifndef Py_OPENSSL_MEM_H
5+
#define Py_OPENSSL_MEM_H
6+
7+
#include "Python.h"
8+
9+
#include <openssl/crypto.h> // CRYPTO_set_mem_functions()
10+
11+
// LibreSSL stubs out CRYPTO_set_mem_functions() and BoringSSL lacks it.
12+
// AWS-LC has it, but unlike OpenSSL it does not refuse to install hooks
13+
// after the first allocation, so earlier size-prefixed allocations would
14+
// be freed with the wrong allocator.
15+
#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) \
16+
&& !defined(OPENSSL_IS_AWSLC)
17+
# define _Py_OPENSSL_CAN_SET_MEM_FUNCTIONS
18+
#endif
19+
20+
#ifdef _Py_OPENSSL_CAN_SET_MEM_FUNCTIONS
21+
22+
static void *
23+
_PyOpenSSL_Malloc(size_t size, const char *Py_UNUSED(file),
24+
int Py_UNUSED(line))
25+
{
26+
return PyMem_RawMalloc(size);
27+
}
28+
29+
static void *
30+
_PyOpenSSL_Realloc(void *ptr, size_t size, const char *Py_UNUSED(file),
31+
int Py_UNUSED(line))
32+
{
33+
return PyMem_RawRealloc(ptr, size);
34+
}
35+
36+
static void
37+
_PyOpenSSL_Free(void *ptr, const char *Py_UNUSED(file),
38+
int Py_UNUSED(line))
39+
{
40+
PyMem_RawFree(ptr);
41+
}
42+
43+
#endif // _Py_OPENSSL_CAN_SET_MEM_FUNCTIONS
44+
45+
static void
46+
_PyOpenSSL_SetupMemFunctions(void)
47+
{
48+
#ifdef _Py_OPENSSL_CAN_SET_MEM_FUNCTIONS
49+
// Fails if OpenSSL has already allocated memory (e.g. another
50+
// libcrypto user in the process); it then keeps its current allocator.
51+
(void)CRYPTO_set_mem_functions(_PyOpenSSL_Malloc, _PyOpenSSL_Realloc,
52+
_PyOpenSSL_Free);
53+
#endif
54+
}
55+
56+
#endif // !Py_OPENSSL_MEM_H

Modules/_ssl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#endif
4242

4343
#include "_ssl.h"
44+
#include "_openssl_mem.h"
4445

4546
/* Redefined below for Windows debug builds after important #includes */
4647
#define _PySSL_FIX_ERRNO
@@ -7475,5 +7476,6 @@ static struct PyModuleDef _sslmodule_def = {
74757476
PyMODINIT_FUNC
74767477
PyInit__ssl(void)
74777478
{
7479+
_PyOpenSSL_SetupMemFunctions();
74787480
return PyModuleDef_Init(&_sslmodule_def);
74797481
}

PCbuild/_hashlib.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@
9797
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
9898
</Link>
9999
</ItemDefinitionGroup>
100+
<ItemGroup>
101+
<ClInclude Include="..\Modules\_openssl_mem.h" />
102+
</ItemGroup>
100103
<ItemGroup>
101104
<ClCompile Include="..\Modules\_hashopenssl.c" />
102105
</ItemGroup>

PCbuild/_hashlib.vcxproj.filters

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<Filter Include="Source Files">
55
<UniqueIdentifier>{cc45963d-bd25-4eb8-bdba-a5507090bca4}</UniqueIdentifier>
66
</Filter>
7+
<Filter Include="Header Files">
8+
<UniqueIdentifier>{5abcdd3e-a8bc-4833-949c-9477609092b9}</UniqueIdentifier>
9+
</Filter>
710
<Filter Include="Resource Files">
811
<UniqueIdentifier>{67630fa4-76e4-4035-bced-043a6df1e2e0}</UniqueIdentifier>
912
</Filter>
@@ -13,6 +16,11 @@
1316
<Filter>Source Files</Filter>
1417
</ClCompile>
1518
</ItemGroup>
19+
<ItemGroup>
20+
<ClInclude Include="..\Modules\_openssl_mem.h">
21+
<Filter>Header Files</Filter>
22+
</ClInclude>
23+
</ItemGroup>
1624
<ItemGroup>
1725
<ResourceCompile Include="..\PC\python_nt.rc">
1826
<Filter>Resource Files</Filter>

PCbuild/_ssl.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@
9797
<AdditionalDependencies>ws2_32.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
9898
</Link>
9999
</ItemDefinitionGroup>
100+
<ItemGroup>
101+
<ClInclude Include="..\Modules\_openssl_mem.h" />
102+
</ItemGroup>
100103
<ItemGroup>
101104
<ClCompile Include="..\Modules\_ssl.c" />
102105
</ItemGroup>

PCbuild/_ssl.vcxproj.filters

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<Filter Include="Source Files">
55
<UniqueIdentifier>{695348f7-e9f6-4fe1-bc03-5f08ffc8095b}</UniqueIdentifier>
66
</Filter>
7+
<Filter Include="Header Files">
8+
<UniqueIdentifier>{7c1bd5da-8912-4107-b6ac-f3930f2d90c7}</UniqueIdentifier>
9+
</Filter>
710
<Filter Include="Resource Files">
811
<UniqueIdentifier>{1b18a2e6-040d-46c7-a9ac-ac2ec64fb5d6}</UniqueIdentifier>
912
</Filter>
@@ -13,6 +16,11 @@
1316
<Filter>Source Files</Filter>
1417
</ClCompile>
1518
</ItemGroup>
19+
<ItemGroup>
20+
<ClInclude Include="..\Modules\_openssl_mem.h">
21+
<Filter>Header Files</Filter>
22+
</ClInclude>
23+
</ItemGroup>
1624
<ItemGroup>
1725
<ResourceCompile Include="..\PC\python_nt.rc">
1826
<Filter>Resource Files</Filter>

0 commit comments

Comments
 (0)