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 4173d677a1)

* bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672)

Disable undefined behavior sanitizer (UBSan) on
faulthandler._read_null().

(cherry picked from commit 65b92ccdec)

* 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 6d0d7d2b8c)

* 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 ad1b04451d)
(cherry picked from commit 7b5b429ada)
This commit is contained in:
Victor Stinner 2022-03-04 01:31:54 +01:00 committed by GitHub
parent 09819863a3
commit 6a14330318
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 12 deletions

View file

@ -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"

View file

@ -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)

View file

@ -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.

View file

@ -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);