From: Victor Stinner Date: Fri, 4 Mar 2022 00:31:54 +0000 (+0100) Subject: bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) ... X-Git-Tag: v3.9.11~39 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6a14330318c9c7aedf3e9841c3dfea337064d8e6;p=thirdparty%2FPython%2Fcpython.git bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) (GH-31676) * bpo-46913: Fix test_faulthandler.test_sigfpe() on UBSAN (GH-31662) Disable undefined behavior sanitizer (UBSAN) on faulthandler_sigfpe(). (cherry picked from commit 4173d677a1d7c72bb32d292fbff1b4cf073d615c) * bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672) Disable undefined behavior sanitizer (UBSan) on faulthandler._read_null(). (cherry picked from commit 65b92ccdec2ee4a99e54aaf7ae2d9bbc2ebfe549) * bpo-46913: test_hashlib skips _sha3 tests on UBSan (GH-31673) If Python is built with UBSan, test_hashlib skips tests on the _sha3 extension which currently has undefined behaviors. This change allows to run test_hashlib to check for new UBSan regression, but the known _sha3 undefined behavior must be fixed. (cherry picked from commit 6d0d7d2b8c1e04fd51c6cb29cc09a41b60b97b7b) * bpo-46913: Skip test_ctypes.test_shorts() on UBSan (GH-31674) If Python is built with UBSan, test_ctypes now skips test_shorts(). This change allows to run test_ctypes to check for new UBSan regression, but the known test_shorts() undefined behavior must be fixed. (cherry picked from commit ad1b04451d3aca2c6fa6dbe2891676a4e0baac49) (cherry picked from commit 7b5b429adab4fe0fe81858fe3831f06adc2e2141) --- diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index 992b8c4da3a7..66acd62e6851 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,5 +1,6 @@ from ctypes import * from ctypes.test import need_symbol +from test import support import unittest import os @@ -39,6 +40,8 @@ class C_Test(unittest.TestCase): setattr(b, name, i) self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii'))) + # bpo-46913: _ctypes/cfield.c h_get() has an undefined behavior + @support.skip_if_sanitizer(ub=True) def test_shorts(self): b = BITS() name = "M" diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 969e5e42e44c..214bc3cb2b18 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -66,7 +66,9 @@ try: except ImportError: _sha3 = None -requires_sha3 = unittest.skipUnless(_sha3, 'requires _sha3') +# bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +SKIP_SHA3 = support.check_sanitizer(ub=True) +requires_sha3 = unittest.skipUnless(not SKIP_SHA3 and _sha3, 'requires _sha3') def hexstr(s): @@ -129,6 +131,8 @@ class HashLibTestCase(unittest.TestCase): self.constructors_to_test = {} for algorithm in algorithms: + if SKIP_SHA3 and algorithm.startswith('sha3_'): + continue self.constructors_to_test[algorithm] = set() # For each algorithm, test the direct constructor and the use @@ -181,14 +185,15 @@ class HashLibTestCase(unittest.TestCase): add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') - add_builtin_constructor('shake_128') - add_builtin_constructor('shake_256') + if not SKIP_SHA3: + _sha3 = self._conditional_import_module('_sha3') + if _sha3: + add_builtin_constructor('sha3_224') + add_builtin_constructor('sha3_256') + add_builtin_constructor('sha3_384') + add_builtin_constructor('sha3_512') + add_builtin_constructor('shake_128') + add_builtin_constructor('shake_256') super(HashLibTestCase, self).__init__(*args, **kwargs) diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst new file mode 100644 index 000000000000..65fed1c249d8 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst @@ -0,0 +1,3 @@ +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index e7a285033051..9855a3e0065c 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -27,6 +27,23 @@ #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) + +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + + _Py_IDENTIFIER(enable); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(flush); @@ -1010,7 +1027,7 @@ faulthandler_suppress_crash_report(void) #endif } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; @@ -1099,17 +1116,20 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { + faulthandler_suppress_crash_report(); + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z to silence a compiler warning. */ return PyLong_FromLong(z);