!92 fix the issue failed to build with address sanitizer

From: @willwolf
Reviewed-by: @hanxinke
Signed-off-by: @hanxinke
This commit is contained in:
openeuler-ci-bot 2021-08-20 07:32:05 +00:00 committed by Gitee
commit f3aa015cb0
6 changed files with 384 additions and 1 deletions

View File

@ -0,0 +1,31 @@
From 9932fdc4d7daadcc38e78717d1a538b594a0731d Mon Sep 17 00:00:00 2001
From: Ben Harper <btharper1221@gmail.com>
Date: Tue, 10 Sep 2019 11:20:15 -0400
Subject: [PATCH] bpo-36253: Remove use after free reference in ctypes test
suite (GH-12257)
Reference:https://github.com/python/cpython/commit/a9b6033179b64b985394ad351501089a6a94fc9d
Conflict:NA
---
Lib/ctypes/test/test_stringptr.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/ctypes/test/test_stringptr.py
index 95cd161..c20951f 100644
--- a/Lib/ctypes/test/test_stringptr.py
+++ b/Lib/ctypes/test/test_stringptr.py
@@ -70,8 +70,8 @@ class StringPtrTestCase(unittest.TestCase):
x = r[0], r[1], r[2], r[3], r[4]
self.assertEqual(x, (b"c", b"d", b"e", b"f", b"\000"))
del buf
- # x1 will NOT be the same as x, usually:
- x1 = r[0], r[1], r[2], r[3], r[4]
+ # Because r is a pointer to memory that is freed after deleting buf,
+ # the pointer is hanging and using it would reference freed memory.
if __name__ == '__main__':
unittest.main()
--
2.27.0

View File

@ -0,0 +1,52 @@
From 95f99563eaa77447e67f18427fde142ea1b7f4ac Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@redhat.com>
Date: Tue, 19 Mar 2019 14:19:38 +0100
Subject: [PATCH] bpo-36333, bpo-36356: Fix _PyEval_FiniThreads() (GH-12432)
_PyEval_FiniThreads() now free the pending lock.
Reference:https://github.com/python/cpython/commit/a712679a2bffffefaacdc05f788d6ea50f72a561
Conflict:NA
---
Python/ceval.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Python/ceval.c b/Python/ceval.c
index 634edba..c0256d1 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -154,8 +154,10 @@ PyEval_ThreadsInitialized(void)
void
PyEval_InitThreads(void)
{
- if (gil_created())
+ if (gil_created()) {
return;
+ }
+
create_gil();
take_gil(PyThreadState_GET());
_PyRuntime.ceval.pending.main_thread = PyThread_get_thread_ident();
@@ -166,10 +168,17 @@ PyEval_InitThreads(void)
void
_PyEval_FiniThreads(void)
{
- if (!gil_created())
+ if (!gil_created()) {
return;
+ }
+
destroy_gil();
assert(!gil_created());
+
+ if (_PyRuntime.ceval.pending.lock != NULL) {
+ PyThread_free_lock(_PyRuntime.ceval.pending.lock);
+ _PyRuntime.ceval.pending.lock = NULL;
+ }
}
void
--
2.27.0

View File

@ -0,0 +1,45 @@
From 46bd8737ab2ea15d644bfde42f1c24504259442e Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 7 Oct 2019 09:38:00 -0700
Subject: [PATCH] bpo-36356: Fix memory leak in _asynciomodule.c (GH-16598)
(cherry picked from commit 321def805abc5b7c92c7e90ca90cb2434fdab855)
Co-authored-by: Ben Harper <btharper1221@gmail.com>
Reference:https://github.com/python/cpython/commit/13915a3100608f011b29da2f3716c990f523b631
Conflict:NA
---
Modules/_asynciomodule.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 6986802..4828e1c 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -33,6 +33,7 @@ static PyObject *asyncio_task_repr_info_func;
static PyObject *asyncio_InvalidStateError;
static PyObject *asyncio_CancelledError;
static PyObject *context_kwname;
+static int module_initialized;
static PyObject *cached_running_holder;
static volatile uint64_t cached_running_holder_tsid;
@@ -3244,6 +3245,12 @@ module_init(void)
if (asyncio_mod == NULL) {
goto fail;
}
+ if (module_initialized != 0) {
+ return 0;
+ }
+ else {
+ module_initialized = 1;
+ }
current_tasks = PyDict_New();
if (current_tasks == NULL) {
--
2.27.0

View File

@ -0,0 +1,156 @@
From 2131750c2bd6ae9d3e294ec14bfc2cbb9e7b497d Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@redhat.com>
Date: Fri, 7 Jun 2019 16:22:21 +0200
Subject: [PATCH] bpo-37169: Rewrite _PyObject_IsFreed() unit tests (GH-13888)
Replace two Python function calls with a single one to ensure that no
memory allocation is done between the invalid object is created and
when _PyObject_IsFreed() is called.
Reference:https://github.com/python/cpython/commit/3bf0f3ad2046ac674d8e8a2c074a5a8b3327797d
Conflict:NA
---
Lib/test/test_capi.py | 29 ++++++++++---------
.../2019-06-07-12-23-15.bpo-37169.yfXTFg.rst | 1 +
Modules/_testcapimodule.c | 27 ++++++++---------
3 files changed, 30 insertions(+), 27 deletions(-)
create mode 100644 Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index ebcb692..097bbde 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -522,28 +522,29 @@ class PyMemDebugTests(unittest.TestCase):
code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()'
self.check_malloc_without_gil(code)
- def check_pyobject_is_freed(self, func):
- code = textwrap.dedent('''
+ def check_pyobject_is_freed(self, func_name):
+ code = textwrap.dedent(f'''
import gc, os, sys, _testcapi
# Disable the GC to avoid crash on GC collection
gc.disable()
- obj = _testcapi.{func}()
- error = (_testcapi.pyobject_is_freed(obj) == False)
- # Exit immediately to avoid a crash while deallocating
- # the invalid object
- os._exit(int(error))
+ try:
+ _testcapi.{func_name}()
+ # Exit immediately to avoid a crash while deallocating
+ # the invalid object
+ os._exit(0)
+ except _testcapi.error:
+ os._exit(1)
''')
- code = code.format(func=func)
assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC)
- def test_pyobject_is_freed_uninitialized(self):
- self.check_pyobject_is_freed('pyobject_uninitialized')
+ def test_pyobject_uninitialized_is_freed(self):
+ self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed')
- def test_pyobject_is_freed_forbidden_bytes(self):
- self.check_pyobject_is_freed('pyobject_forbidden_bytes')
+ def test_pyobject_forbidden_bytes_is_freed(self):
+ self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed')
- def test_pyobject_is_freed_free(self):
- self.check_pyobject_is_freed('pyobject_freed')
+ def test_pyobject_freed_is_freed(self):
+ self.check_pyobject_is_freed('check_pyobject_freed_is_freed')
class PyMemMallocDebugTests(PyMemDebugTests):
diff --git a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst
new file mode 100644
index 0000000..f2f0a8b
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst
@@ -0,0 +1 @@
+Rewrite ``_PyObject_IsFreed()`` unit tests.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 6996d22..55cfdb8 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -4248,15 +4248,17 @@ test_pymem_getallocatorsname(PyObject *self, PyObject *args)
static PyObject*
-pyobject_is_freed(PyObject *self, PyObject *op)
+test_pyobject_is_freed(const char *test_name, PyObject *op)
{
- int res = _PyObject_IsFreed(op);
- return PyBool_FromLong(res);
+ if (!_PyObject_IsFreed(op)) {
+ return raiseTestError(test_name, "object is not seen as freed");
+ }
+ Py_RETURN_NONE;
}
static PyObject*
-pyobject_uninitialized(PyObject *self, PyObject *args)
+check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
{
PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject));
if (op == NULL) {
@@ -4265,12 +4267,12 @@ pyobject_uninitialized(PyObject *self, PyObject *args)
/* Initialize reference count to avoid early crash in ceval or GC */
Py_REFCNT(op) = 1;
/* object fields like ob_type are uninitialized! */
- return op;
+ return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op);
}
static PyObject*
-pyobject_forbidden_bytes(PyObject *self, PyObject *args)
+check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
{
/* Allocate an incomplete PyObject structure: truncate 'ob_type' field */
PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type));
@@ -4281,12 +4283,12 @@ pyobject_forbidden_bytes(PyObject *self, PyObject *args)
Py_REFCNT(op) = 1;
/* ob_type field is after the memory block: part of "forbidden bytes"
when using debug hooks on memory allocatrs! */
- return op;
+ return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op);
}
static PyObject*
-pyobject_freed(PyObject *self, PyObject *args)
+check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
{
PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type);
if (op == NULL) {
@@ -4296,7 +4298,7 @@ pyobject_freed(PyObject *self, PyObject *args)
/* Reset reference count to avoid early crash in ceval or GC */
Py_REFCNT(op) = 1;
/* object memory is freed! */
- return op;
+ return test_pyobject_is_freed("check_pyobject_freed_is_freed", op);
}
@@ -4876,10 +4878,9 @@ static PyMethodDef TestMethods[] = {
{"pymem_api_misuse", pymem_api_misuse, METH_NOARGS},
{"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS},
{"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS},
- {"pyobject_is_freed", (PyCFunction)(void(*)(void))pyobject_is_freed, METH_O},
- {"pyobject_uninitialized", pyobject_uninitialized, METH_NOARGS},
- {"pyobject_forbidden_bytes", pyobject_forbidden_bytes, METH_NOARGS},
- {"pyobject_freed", pyobject_freed, METH_NOARGS},
+ {"check_pyobject_uninitialized_is_freed", check_pyobject_uninitialized_is_freed, METH_NOARGS},
+ {"check_pyobject_forbidden_bytes_is_freed", check_pyobject_forbidden_bytes_is_freed, METH_NOARGS},
+ {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS},
{"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS},
{"tracemalloc_track", tracemalloc_track, METH_VARARGS},
{"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS},
--
2.27.0

View File

@ -0,0 +1,78 @@
From aa4008139816278d5eec823669fdaa50ae9a16b0 Mon Sep 17 00:00:00 2001
From: Mark Shannon <mark@hotpy.org>
Date: Thu, 10 Jun 2021 12:37:22 +0100
Subject: [PATCH] bpo-44363: Get test_capi passing with address sanitizer
(GH-26639)
Reference:https://github.com/python/cpython/commit/31aa0dbff4c1d39c9d77c6c8f4a61d0e46c1268b
Conflict:NA
---
Include/Python.h | 11 ++++++++++-
.../Tests/2021-06-10-11-19-43.bpo-44363.-K9jD0.rst | 2 ++
Modules/_testcapimodule.c | 5 +++++
3 files changed, 17 insertions(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Tests/2021-06-10-11-19-43.bpo-44363.-K9jD0.rst
diff --git a/Include/Python.h b/Include/Python.h
index 54ea321..2ebddb9 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -63,13 +63,22 @@
#include "pyport.h"
#include "pymacro.h"
-/* A convenient way for code to know if clang's memory sanitizer is enabled. */
+/* A convenient way for code to know if sanitizers are enabled. */
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# if !defined(_Py_MEMORY_SANITIZER)
# define _Py_MEMORY_SANITIZER
# endif
# endif
+# if __has_feature(address_sanitizer)
+# if !defined(_Py_ADDRESS_SANITIZER)
+# define _Py_ADDRESS_SANITIZER
+# endif
+# endif
+#elif defined(__GNUC__)
+# if defined(__SANITIZE_ADDRESS__)
+# define _Py_ADDRESS_SANITIZER
+# endif
#endif
#include "pyatomic.h"
diff --git a/Misc/NEWS.d/next/Tests/2021-06-10-11-19-43.bpo-44363.-K9jD0.rst b/Misc/NEWS.d/next/Tests/2021-06-10-11-19-43.bpo-44363.-K9jD0.rst
new file mode 100644
index 0000000..28468cb
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2021-06-10-11-19-43.bpo-44363.-K9jD0.rst
@@ -0,0 +1,2 @@
+Account for address sanitizer in test_capi. test_capi now passes when run
+GCC address sanitizer.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 55cfdb8..a43143a 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -4290,6 +4290,10 @@ check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args
static PyObject*
check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
{
+ /* This test would fail if run with the address sanitizer */
+#ifdef _Py_ADDRESS_SANITIZER
+ Py_RETURN_NONE;
+#else
PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type);
if (op == NULL) {
return NULL;
@@ -4299,6 +4303,7 @@ check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
Py_REFCNT(op) = 1;
/* object memory is freed! */
return test_pyobject_is_freed("check_pyobject_freed_is_freed", op);
+#endif
}
--
2.27.0

View File

@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language
URL: https://www.python.org/ URL: https://www.python.org/
Version: 3.7.9 Version: 3.7.9
Release: 15 Release: 16
License: Python License: Python
%global branchversion 3.7 %global branchversion 3.7
@ -144,6 +144,12 @@ patch6035: backport-Remove-thread-objects-which-finished-process-its-request.pa
patch6036: backport-CVE-2021-3426.patch patch6036: backport-CVE-2021-3426.patch
patch6037: backport-32494-Use-gdbm_count-for-dbm_length-if-possible.patch patch6037: backport-32494-Use-gdbm_count-for-dbm_length-if-possible.patch
Patch6038: backport-36333-36356-Fix-_PyEval_FiniThreads-GH-12432.patch
Patch6039: backport-37169-Rewrite-_PyObject_IsFreed-unit-tests-GH-13.patch
Patch6040: backport-44363-Get-test_capi-passing-with-address-sanitiz.patch
Patch6041: backport-36253-Remove-use-after-free-reference-in-ctypes-.patch
Patch6042: backport-36356-Fix-memory-leak-in-_asynciomodule.c-GH-165.patch
patch9000: Don-t-override-PYTHONPATH-which-is-already-set.patch patch9000: Don-t-override-PYTHONPATH-which-is-already-set.patch
Recommends: %{name}-help = %{version}-%{release} Recommends: %{name}-help = %{version}-%{release}
@ -274,6 +280,11 @@ rm Lib/ensurepip/_bundled/*.whl
%patch6035 -p1 %patch6035 -p1
%patch6036 -p1 %patch6036 -p1
%patch6037 -p1 %patch6037 -p1
%patch6038 -p1
%patch6039 -p1
%patch6040 -p1
%patch6041 -p1
%patch6042 -p1
%patch9000 -p1 %patch9000 -p1
sed -i "s/generic_os/%{_vendor}/g" Lib/platform.py sed -i "s/generic_os/%{_vendor}/g" Lib/platform.py
@ -876,6 +887,16 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
%{_mandir}/*/* %{_mandir}/*/*
%changelog %changelog
* Thu Aug 19 2021 hehuazhen<hehuazhen@huawei.com> - 3.7.9-16
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:fix _PyEval_FiniThreads
rewrite _PyObject_IsFreed unit tests
get test_capi passing with address sanitize
remove use after free reference in ctypes
fix memory leak in _asynciomodule.c
* Fri Jun 25 2021 hehuazhen<hehuazhen@huawei.com> - 3.7.9-15 * Fri Jun 25 2021 hehuazhen<hehuazhen@huawei.com> - 3.7.9-15
- Type:bugfix - Type:bugfix
- CVE:NA - CVE:NA