Compare commits
4 Commits
a88f6ef6ce
...
aebcd739a4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aebcd739a4 | ||
|
|
2677b5a6f2 | ||
|
|
0860696e15 | ||
|
|
7be871eb60 |
3787
cet-protections.patch
Normal file
3787
cet-protections.patch
Normal file
File diff suppressed because it is too large
Load Diff
249
coverity-fixes.patch
Normal file
249
coverity-fixes.patch
Normal 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
|
||||
|
||||
70
fix-signed-overflow-s390x.patch
Normal file
70
fix-signed-overflow-s390x.patch
Normal 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
|
||||
|
||||
40
fix-test_validate_transcendentals-x86_64.patch
Normal file
40
fix-test_validate_transcendentals-x86_64.patch
Normal 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
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user