Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d2e1590

Browse files
committed
Add option to enable mimalloc secure mode
1 parent c06b9e4 commit d2e1590

File tree

8 files changed

+122
-39
lines changed

8 files changed

+122
-39
lines changed

Doc/using/configure.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,23 @@ also be used to improve performance.
268268

269269
See also :envvar:`PYTHONMALLOC` environment variable.
270270

271+
.. versionadded:: 3.11
272+
273+
.. cmdoption:: --enable-mimalloc-secure[=yes|no|1|2|3|4]
274+
275+
Enable mimalloc's secure mode and various mitigations against exploits.
276+
Secure mode comes with small performance penalty and uses additional
277+
memory for guard pages. Each level includes the previous levels. *yes*
278+
enables the highest security level.
279+
280+
* *1* enables guard pages around metadata
281+
* *2* enables guard pages around mimalloc page
282+
* *3* enables encoded free lists and detects corrupted free lists as
283+
well as invalid pointer frees.
284+
* *4* enables expensive checks for double free.
285+
286+
.. versionadded:: 3.11
287+
271288
.. cmdoption:: --without-doc-strings
272289

273290
Disable static documentation strings to reduce the memory footprint (enabled

Include/internal/pycore_mimalloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
# define MI_DEBUG 2
2121
// check for double free, buffer overflows and invalid pointer free
2222
# define MI_SECURE 4
23+
#elif defined(PY_MIMALLOC_SECURE)
24+
# define MI_SECURE PY_MIMALLOC_SECURE
2325
#endif
2426

2527
/* Prefix all non-static symbols with "_Py_"

Lib/test/test_sys.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -933,11 +933,12 @@ def test_debugmallocstats(self):
933933
@test.support.cpython_only
934934
def test_malloc_info(self):
935935
info = sys._malloc_info
936-
self.assertEqual(len(info), 4)
936+
self.assertEqual(len(info), 5)
937937
self.assertIsInstance(info.allocator, str)
938-
self.assertIsInstance(info.with_freelists, bool)
939938
self.assertIsInstance(info.with_pymalloc, bool)
940939
self.assertIsInstance(info.with_mimalloc, bool)
940+
self.assertIsInstance(info.mimalloc_secure, int)
941+
self.assertIsInstance(info.mimalloc_debug, int)
941942

942943
@unittest.skipUnless(hasattr(sys, "getallocatedblocks"),
943944
"sys.getallocatedblocks unavailable on this build")

Makefile.pre.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,8 +1308,9 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile
13081308
-DSHLIB_EXT='"$(EXT_SUFFIX)"' \
13091309
-o $@ $(srcdir)/Python/dynload_hpux.c
13101310

1311-
Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h
1311+
Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h @MIMALLOC_INCLUDES@
13121312
$(CC) -c $(PY_CORE_CFLAGS) \
1313+
-I$(srcdir)/Include/mimalloc \
13131314
-DABIFLAGS='"$(ABIFLAGS)"' \
13141315
$(MULTIARCH_CPPFLAGS) \
13151316
-o $@ $(srcdir)/Python/sysmodule.c

Python/sysmodule.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Data members:
2020
#include "pycore_code.h" // _Py_QuickenedCount
2121
#include "pycore_frame.h" // _PyInterpreterFrame
2222
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
23+
#include "pycore_mimalloc.h" // MI_SECURE, MI_DEBUG
2324
#include "pycore_namespace.h" // _PyNamespace_New()
2425
#include "pycore_object.h" // _PyObject_IS_GC()
2526
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
@@ -1945,17 +1946,18 @@ static PyTypeObject MallocInfoType;
19451946

19461947
static PyStructSequence_Field malloc_info_fields[] = {
19471948
{"allocator", "current memory allocator"},
1948-
{"with_freelists", "uses freelists"},
19491949
{"with_pymalloc", "supports pymalloc (aka obmalloc)"},
19501950
{"with_mimalloc", "supports mimalloc"},
1951+
{"mimalloc_secure", "mimalloc security level"},
1952+
{"mimalloc_debug", "mimalloc debug level"},
19511953
{0}
19521954
};
19531955

19541956
static PyStructSequence_Desc malloc_info_desc = {
19551957
"sys._malloc_info", /* name */
19561958
malloc_info__doc__ , /* doc */
19571959
malloc_info_fields, /* fields */
1958-
4
1960+
5
19591961
};
19601962

19611963
static PyObject *
@@ -1971,6 +1973,9 @@ make_malloc_info(void)
19711973
return NULL;
19721974
}
19731975

1976+
#define SetIntItem(flag) \
1977+
PyStructSequence_SET_ITEM(malloc_info, pos++, PyLong_FromLong(flag))
1978+
19741979
name = _PyMem_GetCurrentAllocatorName();
19751980
if (name == NULL) {
19761981
name = "unknown";
@@ -1983,13 +1988,6 @@ make_malloc_info(void)
19831988

19841989
PyStructSequence_SET_ITEM(malloc_info, pos++, v);
19851990

1986-
#ifdef WITH_FREELISTS
1987-
v = Py_True;
1988-
#else
1989-
v = Py_False;
1990-
#endif
1991-
PyStructSequence_SET_ITEM(malloc_info, pos++, _Py_NewRef(v));
1992-
19931991
#ifdef WITH_PYMALLOC
19941992
v = Py_True;
19951993
#else
@@ -2004,6 +2002,11 @@ make_malloc_info(void)
20042002
#endif
20052003
PyStructSequence_SET_ITEM(malloc_info, pos++, _Py_NewRef(v));
20062004

2005+
SetIntItem(MI_SECURE);
2006+
SetIntItem(MI_DEBUG);
2007+
2008+
#undef SetIntItem
2009+
20072010
if (PyErr_Occurred()) {
20082011
Py_CLEAR(malloc_info);
20092012
return NULL;

configure

Lines changed: 46 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4598,27 +4598,47 @@ fi
45984598
AC_MSG_RESULT($with_doc_strings)
45994599

46004600
# --with-mimalloc
4601-
AC_MSG_CHECKING(for --with-mimalloc)
4602-
AC_ARG_WITH(mimalloc,
4603-
AS_HELP_STRING([--with-mimalloc],
4604-
[build with mimalloc memory allocator (default is yes)]),
4601+
AC_MSG_CHECKING([for --with-mimalloc])
4602+
AC_ARG_WITH([mimalloc],
4603+
[AS_HELP_STRING([--with-mimalloc],
4604+
[build with mimalloc memory allocator (default is yes)])],
46054605
[],
46064606
[with_mimalloc="yes"]
46074607
)
46084608

46094609
if test "$with_mimalloc" != no; then
4610-
AC_MSG_RESULT(yes)
4611-
# disable pymalloc with mimalloc
4612-
# with_pymalloc="no"
4613-
# with_freelists="no"
4614-
AC_DEFINE(WITH_MIMALLOC, 1, Define Python uses mimalloc memory allocator.)
4615-
AC_SUBST(WITH_MIMALLOC, 1)
4616-
AC_SUBST(MIMALLOC_HEADERS, '$(MIMALLOC_HEADERS)')
4617-
AC_SUBST(MIMALLOC_INCLUDES, '$(MIMALLOC_INCLUDES)')
4618-
else
4619-
AC_MSG_RESULT(no)
4610+
with_mimalloc=yes
4611+
AC_DEFINE([WITH_MIMALLOC], [1], [Define if you want to compile in mimalloc memory allocator.])
4612+
AC_SUBST([MIMALLOC_HEADERS], ['$(MIMALLOC_HEADERS)'])
4613+
AC_SUBST([MIMALLOC_INCLUDES], ['$(MIMALLOC_INCLUDES)'])
46204614
fi
4615+
AC_MSG_RESULT([$with_mimalloc])
46214616

4617+
AC_MSG_CHECKING([for --enable-mimalloc-secure])
4618+
AC_ARG_ENABLE([mimalloc-secure],
4619+
[AS_HELP_STRING([--enable-mimalloc-secure@<:@=yes|no|1|2|3|4@:>@],
4620+
[enable mimalloc security mitigations (default is no), 1: guard metadata, 2: guard pages, 3: encode freelists, 4/yes: detect double free])],
4621+
[
4622+
AS_CASE([$enable_mimalloc_secure],
4623+
[yes], [enable_mimalloc_secure=4],
4624+
[1|2|3|4], [],
4625+
[no], [],
4626+
[enable_mimalloc_secure=invalid]
4627+
)
4628+
AS_VAR_IF([enable_mimalloc_secure], [invalid], [AC_MSG_ERROR([bad value $enable_mimalloc_secure for --enable-mimalloc-secure])])
4629+
],
4630+
[enable_mimalloc_secure="no"]
4631+
)
4632+
4633+
if test "$enable_mimalloc_secure" != "no"; then
4634+
AS_VAR_IF([with_mimalloc], [no], [AC_MSG_ERROR([--with-mimalloc-secure requires --with-mimalloc])])
4635+
AC_DEFINE_UNQUOTED(
4636+
[PY_MIMALLOC_SECURE],
4637+
[$enable_mimalloc_secure],
4638+
[Define to 1, 2, 3, or 4 to enable mimalloc's security mitigations (Py_DEBUG forces 4)]
4639+
)
4640+
fi
4641+
AC_MSG_RESULT([$enable_mimalloc_secure])
46224642

46234643
# Check for Python-specific malloc support
46244644
AC_MSG_CHECKING(for --with-pymalloc)
@@ -6754,7 +6774,7 @@ AS_VAR_IF([ac_cv_header_stdatomic_h], [yes], [
67546774

67556775
if test "$ac_cv_header_stdatomic_h" != yes -a "$with_mimalloc" != no; then
67566776
# mimalloc-atomic.h wants C11 stdatomic.h on POSIX
6757-
AC_MSG_ERROR([--with-mimalloc requires stdatomic.h on your platform])
6777+
AC_MSG_ERROR([mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc. A future version of Python will require stdatomic.h.])
67586778
fi
67596779

67606780
# Check for GCC >= 4.7 and clang __atomic builtin functions

pyconfig.h.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,10 @@
15711571
/* Define to 1 if you have the perf trampoline. */
15721572
#undef PY_HAVE_PERF_TRAMPOLINE
15731573

1574+
/* Define to 1, 2, 3, or 4 to enable mimalloc's security mitigations (Py_DEBUG
1575+
forces 4) */
1576+
#undef PY_MIMALLOC_SECURE
1577+
15741578
/* Define to 1 to build the sqlite module with loadable extensions support. */
15751579
#undef PY_SQLITE_ENABLE_LOAD_EXTENSION
15761580

@@ -1737,7 +1741,7 @@
17371741
/* Define to 1 if libintl is needed for locale functions. */
17381742
#undef WITH_LIBINTL
17391743

1740-
/* Define Python uses mimalloc memory allocator. */
1744+
/* Define if you want to compile in mimalloc memory allocator. */
17411745
#undef WITH_MIMALLOC
17421746

17431747
/* Define if you want to produce an OpenStep/Rhapsody framework (shared

0 commit comments

Comments
 (0)