Compare commits

...

4 Commits

Author SHA1 Message Date
Charalampos Stratakis
aebcd739a4 Enable CET hardware protections
Resolves: RHEL-240103
2026-08-13 15:44:20 +02:00
Charalampos Stratakis
2677b5a6f2 Fix signed overflow issue in npy_gcd for INT_MIN on s390x
Resolves: RHEL-193000
2026-08-13 15:44:15 +02:00
Charalampos Stratakis
0860696e15 Fix test_validate_transcendentals skip to match SVML dispatch
Resolves: RHEL-193001
2026-08-13 15:44:11 +02:00
Charalampos Stratakis
7be871eb60 Fix issues identified via Coverity static analysis
Resolves: RHEL-193002
2026-08-13 15:44:05 +02:00
5 changed files with 4176 additions and 1 deletions

3787
cet-protections.patch Normal file

File diff suppressed because it is too large Load Diff

249
coverity-fixes.patch Normal file
View File

@ -0,0 +1,249 @@
From 78bcbebe048bbc16c771ca96a328c01d6f299c06 Mon Sep 17 00:00:00 2001
From: stratakis <cstratak@redhat.com>
Date: Fri, 19 Dec 2025 18:43:45 +0100
Subject: [PATCH 1/4] MAINT: fix array size declarations in
string_partition_resolve_descriptors (#30475)
---
numpy/_core/src/umath/string_ufuncs.cpp | 6 +++---
numpy/_core/src/umath/stringdtype_ufuncs.cpp | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/numpy/_core/src/umath/string_ufuncs.cpp b/numpy/_core/src/umath/string_ufuncs.cpp
index 9b3d86c..4a65227 100644
--- a/numpy/_core/src/umath/string_ufuncs.cpp
+++ b/numpy/_core/src/umath/string_ufuncs.cpp
@@ -1125,9 +1125,9 @@ string_partition_promoter(PyObject *NPY_UNUSED(ufunc),
static NPY_CASTING
string_partition_resolve_descriptors(
PyArrayMethodObject *self,
- PyArray_DTypeMeta *const NPY_UNUSED(dtypes[3]),
- PyArray_Descr *const given_descrs[3],
- PyArray_Descr *loop_descrs[3],
+ PyArray_DTypeMeta *const NPY_UNUSED(dtypes[6]),
+ PyArray_Descr *const given_descrs[6],
+ PyArray_Descr *loop_descrs[6],
npy_intp *NPY_UNUSED(view_offset))
{
if (!given_descrs[3] || !given_descrs[4] || !given_descrs[5]) {
diff --git a/numpy/_core/src/umath/stringdtype_ufuncs.cpp b/numpy/_core/src/umath/stringdtype_ufuncs.cpp
index ca574f6..7f29a3e 100644
--- a/numpy/_core/src/umath/stringdtype_ufuncs.cpp
+++ b/numpy/_core/src/umath/stringdtype_ufuncs.cpp
@@ -1928,9 +1928,9 @@ zfill_strided_loop(PyArrayMethod_Context *context,
static NPY_CASTING
string_partition_resolve_descriptors(
PyArrayMethodObject *self,
- PyArray_DTypeMeta *const NPY_UNUSED(dtypes[3]),
- PyArray_Descr *const given_descrs[3],
- PyArray_Descr *loop_descrs[3],
+ PyArray_DTypeMeta *const NPY_UNUSED(dtypes[5]),
+ PyArray_Descr *const given_descrs[5],
+ PyArray_Descr *loop_descrs[5],
npy_intp *NPY_UNUSED(view_offset))
{
if (given_descrs[2] || given_descrs[3] || given_descrs[4]) {
--
2.55.0
From b8efba3ffd3f9687d90d815643ac22f750f3af31 Mon Sep 17 00:00:00 2001
From: stratakis <cstratak@redhat.com>
Date: Thu, 26 Feb 2026 15:17:50 +0100
Subject: [PATCH 2/4] BUG: Fix buffer overrun in CPU baseline validation
(#30877)
Co-authored-by: Sebastian Berg <sebastianb@nvidia.com>
---
numpy/_core/src/common/npy_cpu_features.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/numpy/_core/src/common/npy_cpu_features.c b/numpy/_core/src/common/npy_cpu_features.c
index e9239a2..3c6d517 100644
--- a/numpy/_core/src/common/npy_cpu_features.c
+++ b/numpy/_core/src/common/npy_cpu_features.c
@@ -222,14 +222,13 @@ npy__cpu_validate_baseline(void)
#define NPY__CPU_VALIDATE_CB(FEATURE, DUMMY) \
if (!npy__cpu_have[NPY_CAT(NPY_CPU_FEATURE_, FEATURE)]) { \
- const int size = sizeof(NPY_TOSTRING(FEATURE)); \
+ const int size = sizeof(NPY_TOSTRING(FEATURE)) - 1; \
memcpy(fptr, NPY_TOSTRING(FEATURE), size); \
fptr[size] = ' '; fptr += size + 1; \
}
NPY_WITH_CPU_BASELINE_CALL(NPY__CPU_VALIDATE_CB, DUMMY) // extra arg for msvc
- *fptr = '\0';
- if (baseline_failure[0] != '\0') {
+ if (fptr > baseline_failure) {
*(fptr-1) = '\0'; // trim the last space
PyErr_Format(PyExc_RuntimeError,
"NumPy was built with baseline optimizations: \n"
--
2.55.0
From a42fc7e094b9f2f01c14973f80e4236549297bcd Mon Sep 17 00:00:00 2001
From: Charalampos Stratakis <cstratak@redhat.com>
Date: Wed, 1 Jul 2026 04:45:53 +0200
Subject: [PATCH 3/4] BUG: Fix MaskedRecords.view() dtype reset and _fill_value
handling
Reset dtype after an ndarray subclass is interpreted as the view type in
MaskedRecords.view(), matching MaskedArray.view(). Reset _fill_value
for real dtype views and add test coverage.
Closes #30441
Co-authored-by: Saba Siddique <sabasiddiqdev@gmail.com>
---
numpy/ma/mrecords.py | 5 +++++
numpy/ma/tests/test_mrecords.py | 18 ++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/numpy/ma/mrecords.py b/numpy/ma/mrecords.py
index 835f3ce..29e3e39 100644
--- a/numpy/ma/mrecords.py
+++ b/numpy/ma/mrecords.py
@@ -364,6 +364,7 @@ def view(self, dtype=None, type=None):
try:
if issubclass(dtype, np.ndarray):
output = np.ndarray.view(self, dtype)
+ dtype = None
else:
output = np.ndarray.view(self, dtype)
# OK, there's the change
@@ -386,6 +387,10 @@ def view(self, dtype=None, type=None):
mdtype = ma.make_mask_descr(output.dtype)
output._mask = self._mask.view(mdtype, np.ndarray)
output._mask.shape = output.shape
+ # Make sure to reset the _fill_value if needed
+ if getattr(output, '_fill_value', None) is not None:
+ if dtype is not None:
+ output._fill_value = None
return output
def harden_mask(self):
diff --git a/numpy/ma/tests/test_mrecords.py b/numpy/ma/tests/test_mrecords.py
index 0da9151..5d9d09b 100644
--- a/numpy/ma/tests/test_mrecords.py
+++ b/numpy/ma/tests/test_mrecords.py
@@ -386,6 +386,24 @@ def test_view_flexible_type(self):
assert_equal(test.dtype, np.dtype(alttype))
assert_(test._fill_value is None)
+ def test_view_ndarray_subclass_preserves_dtype(self):
+ mrec = self.data[0]
+
+ class MySub(np.ndarray):
+ pass
+
+ test = mrec.view(MySub)
+ assert_(isinstance(test, MySub))
+ assert_equal(test.dtype, mrec.dtype)
+
+ def test_view_maskedarray_preserves_fill_value(self):
+ mrec = self.data[0]
+ original_fv = mrec.fill_value
+
+ test = mrec.view(ma.MaskedArray)
+ assert_(isinstance(test, ma.MaskedArray))
+ assert_equal(test.fill_value, original_fv)
+
##############################################################################
class TestMRecordsImport:
--
2.55.0
From d85dde322beb59450f728b505534206c230fe993 Mon Sep 17 00:00:00 2001
From: Iason Krommydas <iason.krom@gmail.com>
Date: Wed, 14 Jan 2026 13:41:18 +0100
Subject: [PATCH 4/4] BUG: unrelated error raised when a dtype's `__setstate__`
is called with an invalid state tuple size (#30647)
Raise a simple error rather than trying to correctly raise a more precise on in
__setstate__ for some bad inputs.
---
numpy/_core/src/multiarray/descriptor.c | 15 ++++++---------
numpy/_core/tests/test_dtype.py | 23 +++++++++++++++++++++++
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/numpy/_core/src/multiarray/descriptor.c b/numpy/_core/src/multiarray/descriptor.c
index abe737a..de08037 100644
--- a/numpy/_core/src/multiarray/descriptor.c
+++ b/numpy/_core/src/multiarray/descriptor.c
@@ -852,7 +852,7 @@ _try_convert_from_inherit_tuple(PyArray_Descr *type, PyObject *newobj)
return (PyArray_Descr *)Py_NotImplemented;
}
if (!PyDataType_ISLEGACY(type) || !PyDataType_ISLEGACY(conv)) {
- /*
+ /*
* This specification should probably be never supported, but
* certainly not for new-style DTypes.
*/
@@ -1978,7 +1978,7 @@ NPY_NO_EXPORT PyArray_Descr *
PyArray_DescrNew(PyArray_Descr *base_descr)
{
if (!PyDataType_ISLEGACY(base_descr)) {
- /*
+ /*
* The main use of this function is mutating strings, so probably
* disallowing this is fine in practice.
*/
@@ -2923,13 +2923,10 @@ arraydescr_setstate(_PyArray_LegacyDescr *self, PyObject *args)
}
break;
default:
- /* raise an error */
- if (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0)) > 5) {
- version = PyLong_AsLong(PyTuple_GET_ITEM(args, 0));
- }
- else {
- version = -1;
- }
+ PyErr_SetString(PyExc_ValueError,
+ "Invalid state while unpickling. Is the pickle corrupted "
+ "or created with a newer NumPy version?");
+ return NULL;
}
/*
diff --git a/numpy/_core/tests/test_dtype.py b/numpy/_core/tests/test_dtype.py
index 684672a..086d93c 100644
--- a/numpy/_core/tests/test_dtype.py
+++ b/numpy/_core/tests/test_dtype.py
@@ -1440,6 +1440,29 @@ def test_pickle_dtype(self, dt):
assert roundtrip_dt == dt
assert hash(dt) == pre_pickle_hash
+ @pytest.mark.parametrize('dt', [
+ np.dtype([('a', 'i4'), ('b', 'f8')]),
+ np.dtype('i4, i1', align=True),
+ ])
+ def test_setstate_invalid_tuple_size(self, dt):
+ # gh-30476
+ valid_state = dt.__reduce__()[2]
+ dt.__setstate__(valid_state)
+
+ for size in [1, 2, 3, 4]:
+ with pytest.raises(
+ ValueError, match="Invalid state while unpickling"
+ ):
+ dt.__setstate__(valid_state[:size])
+
+ min_extra = 10 - len(valid_state)
+ for extra in range(min_extra, min_extra + 5):
+ extended = valid_state + (None,) * extra
+ with pytest.raises(
+ ValueError, match="Invalid state while unpickling"
+ ):
+ dt.__setstate__(extended)
+
class TestPromotion:
"""Test cases related to more complex DType promotions. Further promotion
--
2.55.0

View File

@ -0,0 +1,70 @@
From 80071371601233408b4d919dfe7cc05cfee93d02 Mon Sep 17 00:00:00 2001
From: AnkitAhlawat <Ankit.Ahlawat@ibm.com>
Date: Thu, 30 Apr 2026 19:18:10 +0530
Subject: [PATCH] BUG: Fix signed overflow issue in npy_gcd for INT_MIN on
s390x (#31360)
This PR fixes signed overflow issue in npy_gcd when one of the inputs is the minimum value of a signed integer type (INT_MIN) on s390x architecture.
issue was the expression a < 0 ? -a : a in npy_math_internal.h.src causes undefined behavior when a = INT_MIN because negating INT_MIN overflows a signed integer on s390x. i see it is working fine with other arch so fix only provided to s390x
---
numpy/_core/src/npymath/npy_math_internal.h.src | 11 ++++++++++-
numpy/_core/tests/test_umath.py | 12 ++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/numpy/_core/src/npymath/npy_math_internal.h.src b/numpy/_core/src/npymath/npy_math_internal.h.src
index 2f38497..787f7e6 100644
--- a/numpy/_core/src/npymath/npy_math_internal.h.src
+++ b/numpy/_core/src/npymath/npy_math_internal.h.src
@@ -650,12 +650,21 @@ npy_lcm@c@(@type@ a, @type@ b)
*
* #type = (npy_int, npy_long, npy_longlong)*2#
* #c = (,l,ll)*2#
+ * #utype = (npy_uint, npy_ulong, npy_ulonglong)*2#
* #func=gcd*3,lcm*3#
*/
NPY_INPLACE @type@
npy_@func@@c@(@type@ a, @type@ b)
{
- return npy_@func@u@c@(a < 0 ? -a : a, b < 0 ? -b : b);
+ /*
+ * Cast to unsigned to avoid overflow when negating minimum signed value.
+ * For negative values, cast to unsigned first, then apply negation in
+ * unsigned arithmetic to avoid undefined behavior.
+ * This ensures correct behavior across all architectures. #31359
+ */
+ @utype@ a_abs = a < 0 ? (@utype@)(0) - (@utype@)a : (@utype@)a;
+ @utype@ b_abs = b < 0 ? (@utype@)(0) - (@utype@)b : (@utype@)b;
+ return (@type@)npy_@func@u@c@(a_abs, b_abs);
}
/**end repeat**/
diff --git a/numpy/_core/tests/test_umath.py b/numpy/_core/tests/test_umath.py
index 8eac236..1575dd6 100644
--- a/numpy/_core/tests/test_umath.py
+++ b/numpy/_core/tests/test_umath.py
@@ -4131,13 +4131,17 @@ def test_lcm_overflow(self):
assert_equal(np.lcm(a, b), 10 * big)
def test_gcd_overflow(self):
- for dtype in (np.int32, np.int64):
- # verify that we don't overflow when taking abs(x)
- # not relevant for lcm, where the result is unrepresentable anyway
- a = dtype(np.iinfo(dtype).min) # negative power of two
+ # verify that we don't overflow when taking abs(x) for INT_MIN
+ # this was undefined behavior that manifested on s390x with GCC 11.5
+ for dtype in (np.int8, np.int16, np.int32, np.int64):
+ a = dtype(np.iinfo(dtype).min) # INT_MIN
q = -(a // 4)
+ # Test with INT_MIN as first argument
assert_equal(np.gcd(a, q * 3), q)
assert_equal(np.gcd(a, -q * 3), q)
+ # Test with INT_MIN as second argument
+ assert_equal(np.gcd(q * 3, a), q)
+ assert_equal(np.gcd(-q * 3, a), q)
def test_decimal(self):
from decimal import Decimal
--
2.54.0

View File

@ -0,0 +1,40 @@
From 8845f7ac440a6469e84030847c2271930a1d538b Mon Sep 17 00:00:00 2001
From: Charalampos Stratakis <cstratak@redhat.com>
Date: Sat, 25 Apr 2026 05:03:20 +0200
Subject: [PATCH] TST: fix test_validate_transcendentals skip condition to
match SVML dispatch
The test was running on machines with FMA3+AVX2 or AVX512F, but the
SVML code path requires AVX512_SKX (F+BW+DQ+VL). On machines without
AVX512_SKX, the glibc libm scalar fallback is used, which exceeds the
2 ULP tolerance for some float64 cbrt inputs.
---
numpy/_core/tests/test_umath_accuracy.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/numpy/_core/tests/test_umath_accuracy.py b/numpy/_core/tests/test_umath_accuracy.py
index 5707e92..2c44e97 100644
--- a/numpy/_core/tests/test_umath_accuracy.py
+++ b/numpy/_core/tests/test_umath_accuracy.py
@@ -18,14 +18,14 @@
UNARY_OBJECT_UFUNCS.remove(np.invert)
UNARY_OBJECT_UFUNCS.remove(np.bitwise_count)
-IS_AVX = __cpu_features__.get('AVX512F', False) or \
- (__cpu_features__.get('FMA3', False) and __cpu_features__.get('AVX2', False))
+# SVML is only dispatched on AVX512_SKX (see loops_umath_fp.dispatch.c.src)
+IS_SVML = __cpu_features__.get('AVX512_SKX', False)
IS_AVX512FP16 = __cpu_features__.get('AVX512FP16', False)
-# only run on linux with AVX, also avoid old glibc (numpy/numpy#20448).
+# only run on linux with SVML, also avoid old glibc (numpy/numpy#20448).
runtest = (sys.platform.startswith('linux')
- and IS_AVX and not _glibc_older_than("2.17"))
+ and IS_SVML and not _glibc_older_than("2.17"))
platform_skip = pytest.mark.skipif(not runtest,
reason="avoid testing inconsistent platform "
"library implementations")
--
2.54.0

View File

@ -22,7 +22,7 @@
Name: python%{python3_pkgversion}-numpy
Version: 2.3.4
Release: 1%{?dist}
Release: 2%{?dist}
Summary: A fast multidimensional array facility for Python
# Everything is BSD-3-Clause except...
@ -35,6 +35,28 @@ License: BSD-3-Clause AND MIT AND Apache-2.0 AND (Zlib OR BSL-1.0)
URL: http://www.numpy.org/
Source0: https://github.com/%{modname}/%{modname}/releases/download/v%{version}/%{modname}-%{version}.tar.gz
# Resolve issues identified by coverity static analysis
# Resolved upstream:
# https://github.com/numpy/numpy/pull/30877
# https://github.com/numpy/numpy/pull/30647
# https://github.com/numpy/numpy/pull/30475
# Sent upstream:
# https://github.com/numpy/numpy/pull/31819
Patch: coverity-fixes.patch
# Fix test_validate_transcendentals skip to match SVML dispatch
# Sent upstream: https://github.com/numpy/numpy/pull/31333
Patch: fix-test_validate_transcendentals-x86_64.patch
# Fix signed overflow issue in npy_gcd for INT_MIN on s390x
# Resolved upstream:
# https://github.com/numpy/numpy/pull/31360
Patch: fix-signed-overflow-s390x.patch
# Enable CET hardware protections for the AVX-512 assembly
# Sent upstream: https://github.com/numpy/SVML/pull/8
Patch: cet-protections.patch
BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: gcc-gfortran gcc gcc-c++
BuildRequires: lapack-devel
@ -230,6 +252,13 @@ export PYTHONPATH=%{buildroot}%{python3_sitearch}
%changelog
* Tue Jul 07 2026 Charalampos Stratakis <cstratak@redhat.com> - 2.3.4-2
- Fix issues identified via Coverity static analysis
- Fix test_validate_transcendentals skip to match SVML dispatch
- Fix signed overflow issue in npy_gcd for INT_MIN on s390x
- Enable CET hardware protections
- Fixes: RHEL-193002, RHEL-193001, RHEL-193000, RHEL-240103
* Thu Oct 23 2025 Tomáš Hrnčiar <thrnciar@redhat.com> - 2.3.4-1
- Initial import
- Fedora contributions by: