From 61ebf44868739342020b7c88bcf2b1e70d594ea7 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Mon, 27 Oct 2025 21:14:39 +0000 Subject: [PATCH 01/15] Add direct build dependency on OpenCL as a workaround --- usd.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/usd.spec b/usd.spec index c1c00a2..26e7309 100644 --- a/usd.spec +++ b/usd.spec @@ -167,6 +167,11 @@ BuildRequires: pkgconfig(dri) BuildRequires: hdf5-devel BuildRequires: cmake(OpenSubdiv) BuildRequires: pkgconfig(tbb) +# This seems to be an indirect dependency, probably through OpenSubdiv. +# Ideally, everything would take care of its own dependencies, and we wouldn’t +# have to specify it directly, but we haven’t studied the problem closely +# enough to propose a fix. +BuildRequires: pkgconfig(OpenCL) # Unbundled: BuildRequires: cmake(double-conversion) BuildRequires: pkgconfig(liblz4) From 2b21748f535f3d239196ca3e449605f55606dcaf Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Tue, 25 Nov 2025 10:58:20 +0000 Subject: [PATCH 02/15] Use macros for supported architectures [skip changelog] --- usd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usd.spec b/usd.spec index 26e7309..7b3646e 100644 --- a/usd.spec +++ b/usd.spec @@ -255,7 +255,7 @@ Requires: python3-usd%{?_isa} = %{version}-%{release} # # Note that pxr/base/arch/assumptions.cpp explicitly tests the machine is not # big-endian, and pxr/base/arch/defines.h explicitly enforces x86_64 or ARM64. -ExclusiveArch: aarch64 x86_64 +ExclusiveArch: %{arm64} %{x86_64} %description Universal Scene Description (USD) is a time-sampled scene From 498e0bda2d4ad0f78dfda3d2bc9ae86a264fb09b Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Tue, 25 Nov 2025 10:57:29 +0000 Subject: [PATCH 03/15] Rebuilt with stb_image patched for two new security bugs --- usd.spec | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/usd.spec b/usd.spec index 7b3646e..98140c0 100644 --- a/usd.spec +++ b/usd.spec @@ -239,12 +239,11 @@ BuildRequires: pkgconfig(ptex) # CVE-2023-45664 # CVE-2023-45666 # CVE-2023-45667 -BuildRequires: stb_image-devel >= 2.28^20231011gitbeebb24-12 -BuildRequires: stb_image-static -BuildRequires: stb_image_write-devel >= 1.16 -BuildRequires: stb_image_write-static -BuildRequires: stb_image_resize-devel >= 0.97 -BuildRequires: stb_image_resize-static +# https://github.com/nothings/stb/issues/1860 +# https://github.com/nothings/stb/issues/1861 +BuildRequires: stb_image-static >= 2.30^20251025gitf1c79c0-1 +BuildRequires: stb_image_write-static >= 1.16 +BuildRequires: stb_image_resize-static >= 0.97 Requires: usd-libs%{?_isa} = %{version}-%{release} Requires: python3-usd%{?_isa} = %{version}-%{release} From 842d69ec9ed51239be138cfed59c4b6e9db2017e Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Tue, 25 Nov 2025 14:32:01 +0000 Subject: [PATCH 04/15] Correct minimum NVR for stb_image --- usd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usd.spec b/usd.spec index 98140c0..e2a9ccc 100644 --- a/usd.spec +++ b/usd.spec @@ -241,7 +241,7 @@ BuildRequires: pkgconfig(ptex) # CVE-2023-45667 # https://github.com/nothings/stb/issues/1860 # https://github.com/nothings/stb/issues/1861 -BuildRequires: stb_image-static >= 2.30^20251025gitf1c79c0-1 +BuildRequires: stb_image-static >= 2.30^20251025gitf1c79c0-2 BuildRequires: stb_image_write-static >= 1.16 BuildRequires: stb_image_resize-static >= 0.97 From 76dc6944392ea818420b47bab4008834bf228e3d Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Tue, 2 Dec 2025 15:51:30 +0100 Subject: [PATCH 05/15] Rebuild (python-pyside6) From 4b70806822772364b5ee08bec822447f6a1d5e81 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Tue, 2 Dec 2025 14:53:34 +0000 Subject: [PATCH 06/15] Backport fixes for CVE-2025-64181 etc. in OpenEXRCore --- ...or-CVE-2025-64181-etc.-in-OpenEXRCor.patch | 86 +++++++++++++++++++ usd.spec | 5 ++ 2 files changed, 91 insertions(+) create mode 100644 0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch diff --git a/0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch b/0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch new file mode 100644 index 0000000..5e4df95 --- /dev/null +++ b/0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch @@ -0,0 +1,86 @@ +From 63e1c9120a52766f7509dec4a312ced5cb15dd3f Mon Sep 17 00:00:00 2001 +From: "Benjamin A. Beasley" +Date: Tue, 2 Dec 2025 10:43:31 +0000 +Subject: [PATCH] Backport fixes for CVE-2025-64181 etc. in OpenEXRCore + +--- + pxr/imaging/hio/OpenEXR/OpenEXRCore/chunk.c | 20 ++++++++++++++++--- + .../hio/OpenEXR/OpenEXRCore/internal_util.h | 4 ++-- + .../hio/OpenEXR/OpenEXRCore/parse_header.c | 4 +++- + 3 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/chunk.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/chunk.c +index cfe80b4cd..e11209fe6 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/chunk.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/chunk.c +@@ -1292,6 +1292,16 @@ exr_read_tile_chunk_info ( + return pctxt->report_error ( + pctxt, EXR_ERR_INVALID_ARGUMENT, "Invalid packed size of 0"); + ++ if (part->comp_type == EXR_COMPRESSION_NONE && ++ cinfo->packed_size != cinfo->unpacked_size) ++ { ++ return pctxt->print_error ( ++ pctxt, ++ EXR_ERR_BAD_CHUNK_LEADER, ++ "Mismatch between unpacked and packed size with uncompressed data: packed is %" PRIu64 "; unpacked is %" PRIu64, ++ cinfo->packed_size, cinfo->unpacked_size); ++ } ++ + return EXR_ERR_SUCCESS; + } + +@@ -1350,11 +1360,15 @@ exr_read_chunk ( + rv = pctxt->do_read ( + pctxt, packed_data, toread, &dataoffset, &nread, rmode); + +- if (rmode == EXR_ALLOW_SHORT_READ && nread < (int64_t) toread) ++ if (rmode == EXR_ALLOW_SHORT_READ && ++ nread >= 0 && ++ nread < (int64_t) toread) ++ { + memset ( + ((uint8_t*) packed_data) + nread, +- 0, +- toread - (uint64_t) (nread)); ++ 0, ++ (size_t)(toread - (uint64_t)nread)); ++ } + } + else + rv = EXR_ERR_SUCCESS; +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_util.h b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_util.h +index 3c6f02786..e0fa3933d 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_util.h ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_util.h +@@ -31,10 +31,10 @@ compute_sampled_height (int height, int y_sampling, int start_y) + else + start = start_y; + end = start_y + height - 1; +- end -= (end < 0) ? (-end % y_sampling) : (end % y_sampling); ++ end -= (end < 0 ? -end : end) % y_sampling; + + if (start > end) +- nlines = 0; ++ nlines = start == start_y ? 1 : 0; + else + nlines = (end - start) / y_sampling + 1; + } +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/parse_header.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/parse_header.c +index d72303926..8b6cf78cc 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/parse_header.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/parse_header.c +@@ -2293,7 +2293,9 @@ internal_exr_compute_chunk_offset_size (struct _internal_exr_part* curpart) + + w = (uint64_t) (((int64_t) dw.max.x) - ((int64_t) dw.min.x) + 1); + +- if (curpart->tiles) ++ if (curpart->storage_mode != EXR_STORAGE_SCANLINE && ++ curpart->storage_mode != EXR_STORAGE_DEEP_SCANLINE && ++ curpart->tiles) + { + const exr_attr_tiledesc_t* tiledesc = curpart->tiles->tiledesc; + int64_t tilecount = 0; +-- +2.52.0 + diff --git a/usd.spec b/usd.spec index e2a9ccc..ba937db 100644 --- a/usd.spec +++ b/usd.spec @@ -151,6 +151,11 @@ Patch: 0005-Downstream-only-use-the-system-libdeflate.patch # Downstream-only: use the system libavif library Patch: 0006-Downstream-only-use-the-system-libavif.patch +# Backport fixes for CVE-2025-64181 etc. in OpenEXRCore +# https://github.com/PixarAnimationStudios/OpenUSD/pull/3903 +# Rebased on v25.08 +Patch: 0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch + # Base BuildRequires: gcc-c++ From 2bae199246bf31024575d54353f00cb940e3f159 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Wed, 24 Dec 2025 13:37:46 +0000 Subject: [PATCH 07/15] Backport fix for CVE-2025-14439/GHSA-grjp-54v3-c442 (fix RHBZ#2422276) --- ...t-invalid-primChildren-in-crate-file.patch | 686 ++++++++++++++++++ usd.spec | 25 +- 2 files changed, 710 insertions(+), 1 deletion(-) create mode 100644 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch diff --git a/0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch b/0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch new file mode 100644 index 0000000..cfd0f51 --- /dev/null +++ b/0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch @@ -0,0 +1,686 @@ +From 5c609492c6c01bbd5fe57c73cb88d279d9195c29 Mon Sep 17 00:00:00 2001 +From: sunyab +Date: Fri, 26 Sep 2025 13:16:55 -0700 +Subject: [PATCH] sdf: Guard against invalid primChildren in crate files + +A crate file containing a primChildren field on a prim with invalid +entries (e.g. an empty name or name with invalid characters) +could lead to issues when accessing that prim's children later +on. In addition, duplicate entries in the field could cause +unexpected behavior when iterating over those children. + +We now check for these conditions when loading a crate file and +emit a runtime error and fail to load the layer if we encounter +this problem. + +This situation typically does not occur via regular Sdf and +Usd usage, so we only do this verification if +PXR_PREFER_SAFETY_OVER_SPEED is enabled. + +(Internal change: 2380262) +(Internal change: 2380126) +--- + pxr/usd/sdf/CMakeLists.txt | 19 +++ + pxr/usd/sdf/crateData.cpp | 127 +++++++++++++++++- + .../testSdfUsdcInvalidPrimChildren.cpp | 84 ++++++++++++ + .../duplicate_prim_children.usdc | Bin 0 -> 704 bytes + .../root.usdc | Bin 0 -> 38110 bytes + 5 files changed, 227 insertions(+), 3 deletions(-) + create mode 100644 pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.cpp + create mode 100644 pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/duplicate_prim_children.usdc + create mode 100644 pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/root.usdc + +diff --git a/pxr/usd/sdf/CMakeLists.txt b/pxr/usd/sdf/CMakeLists.txt +index 092422acb..38bc4c4d2 100644 +--- a/pxr/usd/sdf/CMakeLists.txt ++++ b/pxr/usd/sdf/CMakeLists.txt +@@ -412,6 +412,16 @@ pxr_build_test(testSdfZipFile_CPP + testenv/testSdfZipFile.cpp + ) + ++pxr_build_test(testSdfUsdcInvalidPrimChildren ++ LIBRARIES ++ ar ++ arch ++ tf ++ sdf ++ CPPFILES ++ testenv/testSdfUsdcInvalidPrimChildren.cpp ++) ++ + pxr_install_test_dir( + SRC testenv/testSdfBatchNamespaceEdit.testenv + DEST testSdfBatchNamespaceEdit/testSdfBatchNamespaceEdit.testenv +@@ -461,6 +471,11 @@ pxr_install_test_dir( + SRC testenv/testSdfUsdzResolver + DEST testSdfUsdzResolver + ) ++ ++pxr_install_test_dir( ++ SRC testenv/testSdfUsdcInvalidPrimChildren.testenv ++ DEST testSdfUsdcInvalidPrimChildren ++) + + pxr_register_test(testSdfAbstractData_Cpp + COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfAbstractData_Cpp" +@@ -704,3 +719,7 @@ pxr_register_test(testSdfVariants + PYTHON + COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfVariants" + ) ++pxr_register_test(testSdfUsdcInvalidPrimChildren ++ COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfUsdcInvalidPrimChildren" ++ EXPECTED_RETURN_CODE 0 ++) +diff --git a/pxr/usd/sdf/crateData.cpp b/pxr/usd/sdf/crateData.cpp +index 8fe924779..820418128 100644 +--- a/pxr/usd/sdf/crateData.cpp ++++ b/pxr/usd/sdf/crateData.cpp +@@ -17,6 +17,7 @@ + #include "pxr/base/tf/stringUtils.h" + #include "pxr/base/tf/typeInfoMap.h" + #include "pxr/base/tf/pxrTslRobinMap/robin_map.h" ++#include "pxr/base/tf/pxrTslRobinMap/robin_set.h" + #include "pxr/base/trace/trace.h" + + #include "pxr/base/work/dispatcher.h" +@@ -29,6 +30,8 @@ + + #include + #include ++#include ++#include + + #include + #include +@@ -717,6 +720,7 @@ public: + + //////////////////////////////////////////////////////////////////////// + private: ++ using TokenSet = pxr_tsl::robin_set; + + bool _PopulateFromCrateFile() { + +@@ -815,10 +819,11 @@ private: + } + + // Create all the specData entries and store pointers to them. +- tbb::parallel_for( +- tbb::blocked_range(0, specs.size()), ++ auto createSpecData = + [this, crateFile, &liveFieldSets, &specs]( +- tbb::blocked_range const &r) { ++ tbb::blocked_range const &r, ++ auto&& validateChildrenFn) { ++ + for (size_t i = r.begin(), + end = r.end(); i != end; ++i) { + +@@ -830,10 +835,59 @@ private: + specData.fields = + liveFieldSets.find(spec.fieldSetIndex)->second; + ++ std::forward ++ (validateChildrenFn)(spec, specData); ++ } ++ }; ++ ++#ifndef PXR_PREFER_SAFETY_OVER_SPEED ++ tbb::parallel_for( ++ tbb::blocked_range(0, specs.size()), ++ [&createSpecData](tbb::blocked_range const& r) { ++ createSpecData(r, [](auto&&...) {}); ++ }); ++#else ++ // In safety-over-speed mode we perform additional validation ++ // on specs in worker threads. We need to collect runtime errors ++ // emitted in those threads and transport them back to the ++ // original thread. ++ tbb::concurrent_vector errorTransports; ++ ++ tbb::parallel_for( ++ tbb::blocked_range(0, specs.size()), ++ [this, &createSpecData, &errorTransports]( ++ tbb::blocked_range const& r) { ++ ++ // Reuse a TokenSet for duplicate checking in ++ // _ValidateSpecChildren to avoid allocating memory ++ // repeatedly. ++ TokenSet dupeTokenSet; ++ TfErrorMark m; ++ ++ createSpecData( ++ r, ++ [this, &dupeTokenSet](auto&&... args) { ++ _ValidateSpecChildren( ++ std::forward(args)..., ++ &dupeTokenSet); ++ }); ++ ++ if (!m.IsClean()) { ++ TfErrorTransport transport = m.Transport(); ++ errorTransports.grow_by(1)->swap(transport); + } + }, + tbb::static_partitioner()); + ++ for (TfErrorTransport& transport : errorTransports) { ++ transport.Post(); ++ } ++ ++ if (!m.IsClean()) { ++ return false; ++ } ++#endif ++ + _lastSet = _data.end(); + + return true; +@@ -851,6 +905,73 @@ private: + return ret; + } + ++ inline bool _HasValidChildren(const SdfPath &path, ++ const VtValue &val, ++ TokenSet* dupeTokenSet) const { ++ if (!val.IsHolding()) { ++ return false; ++ } ++ ++ enum class ErrorType { Invalid, Duplicate }; ++ ErrorType errorType; ++ dupeTokenSet->clear(); ++ ++ const TfTokenVector& children = val.UncheckedGet(); ++ auto invalidChild = std::find_if(children.begin(), children.end(), ++ [&](const TfToken& childName) { ++ // Check that the child has a valid identifier and that the ++ // child path exists in the data. ++ if (!SdfPath::IsValidIdentifier(childName) || ++ _data.find(path.AppendChild(childName)) == _data.end()) { ++ errorType = ErrorType::Invalid; ++ return true; ++ } ++ ++ // Check that the child does not duplicate another child. ++ if (!dupeTokenSet->insert(childName).second) { ++ errorType = ErrorType::Duplicate; ++ return true; ++ } ++ ++ return false; ++ }); ++ if (ARCH_UNLIKELY(invalidChild != children.end())) { ++ TF_RUNTIME_ERROR( ++ "%s child identifier '%s' found on parent '%s'", ++ (errorType == ErrorType::Duplicate ? ++ "Duplicate" : "Invalid"), ++ invalidChild->GetText(), path.GetAsString().c_str()); ++ return false; ++ } ++ ++ return true; ++ } ++ ++ inline bool _ValidateSpecChildren(const CrateFile::Spec& spec, ++ const _SpecData &specData, ++ TokenSet* dupeTokenSet) const { ++ if (specData.specType == SdfSpecTypePrim) { ++ // Check for invalid children in primChildren field ++ _FieldValuePairVector const &fields = specData.fields.Get(); ++ auto field = std::find_if(fields.begin(), fields.end(), ++ [](_FieldValuePair const &fieldValue) { ++ return fieldValue.first == SdfChildrenKeys->PrimChildren; ++ }); ++ if (field != fields.end()) { ++ SdfPath const &path = _crateFile->GetPath(spec.pathIndex); ++ VtValue const &value = field->second; ++ if (!_HasValidChildren(path, value, dupeTokenSet)) { ++ TF_RUNTIME_ERROR( ++ "Invalid children found in primChildren field for path " ++ "'%s'", path.GetAsString().c_str()); ++ return false; ++ } ++ } ++ } ++ ++ return true; ++ } ++ + inline std::vector const & + _ListTimeSamplesForPath(const SdfPath &path) const { + TF_DESCRIBE_SCOPE(GetAssetPath().c_str()); +diff --git a/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.cpp b/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.cpp +new file mode 100644 +index 000000000..49258b657 +--- /dev/null ++++ b/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.cpp +@@ -0,0 +1,84 @@ ++// ++// Copyright 2025 Pixar ++// ++// Licensed under the terms set forth in the LICENSE.txt file available at ++// https://openusd.org/license. ++// ++ ++#include "pxr/pxr.h" ++ ++#include "pxr/base/tf/error.h" ++#include "pxr/base/tf/errorMark.h" ++#include "pxr/base/tf/diagnosticLite.h" ++#include "pxr/usd/sdf/childrenView.h" ++#include "pxr/usd/sdf/layer.h" ++#include "pxr/usd/sdf/primSpec.h" ++ ++#include ++#include ++ ++PXR_NAMESPACE_USING_DIRECTIVE ++ ++static void ++TestInvalidPrimChildren() ++{ ++ // This test relies on verification checks that are only enabled when ++ // PXR_PREFER_SAFETY_OVER_SPEED is enabled. ++#ifdef PXR_PREFER_SAFETY_OVER_SPEED ++ // open the layer and check for invalid child prim names and specs ++ TfErrorMark m; ++ ++ auto layer = SdfLayer::FindOrOpen("root.usdc"); ++ TF_AXIOM(!layer); ++ ++ TF_AXIOM(!m.IsClean()); ++ TF_AXIOM(std::any_of(m.begin(), m.end(), ++ [](const TfError& e) { ++ return TfStringEndsWith(e.GetCommentary(), ++ "Invalid child identifier '' found " ++ "on parent '/_materials'"); ++ })); ++ TF_AXIOM(std::any_of(m.begin(), m.end(), ++ [](const TfError& e) { ++ return TfStringEndsWith(e.GetCommentary(), ++ "Invalid children found in primChildren field " ++ "for path '/_materials'"); ++ })); ++#endif ++} ++ ++static void ++TestDuplicatePrimChildren() ++{ ++ // This test relies on verification checks that are only enabled when ++ // PXR_PREFER_SAFETY_OVER_SPEED is enabled. ++#ifdef PXR_PREFER_SAFETY_OVER_SPEED ++ // open the layer and check for invalid child prim names and specs ++ TfErrorMark m; ++ ++ auto layer = SdfLayer::FindOrOpen("duplicate_prim_children.usdc"); ++ TF_AXIOM(!layer); ++ ++ TF_AXIOM(!m.IsClean()); ++ TF_AXIOM(std::any_of(m.begin(), m.end(), ++ [](const TfError& e) { ++ return TfStringEndsWith(e.GetCommentary(), ++ "Duplicate child identifier 'Child1' found " ++ "on parent '/Root'"); ++ })); ++ TF_AXIOM(std::any_of(m.begin(), m.end(), ++ [](const TfError& e) { ++ return TfStringEndsWith(e.GetCommentary(), ++ "Invalid children found in primChildren field " ++ "for path '/Root'"); ++ })); ++#endif ++} ++ ++int main(int argc, char** argv) ++{ ++ TestInvalidPrimChildren(); ++ TestDuplicatePrimChildren(); ++ ++ return 0; ++} +diff --git a/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/duplicate_prim_children.usdc b/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/duplicate_prim_children.usdc +new file mode 100644 +index 0000000000000000000000000000000000000000..b6710e961deb11804a49dbaf2fd2ceb31d261d65 +GIT binary patch +literal 704 +zcmbu7&rZTX5XQf4sV$-j!K(+Z97z0gG*L-eg+OXUYvNH1O(X%@)SBRpgAc$1_y8Wg +z`Zhj-9!yNcVismBoSn-zncwWUJJY&Xo$94mw_#xsUt+2M4Ytt$=wy}yU;x+v*0`#x +zSmi2b4--IvdfKE7QhZoP)e6uF!vs;>AKJJ5K`#zQ$fLAxqI6*5ediF}B#9BlVHCtk +zKe$6LyuTR)NFJiV=?(*S`+LhKS0?JkQirz7mGT$@dlfvIuu;L2g-L$F3a3j2iro9A +z5?_kBmg+ybnVMV$D^G=~nzbgNr|TtGXrEi#bP6wOlhT-DrloAbS0YjtBHI+EYWKnb +zMCPfSjGQ_D=HvcFOFAB306bHAP3rlbrgNS(SoBfocfnaxw(A*2k@zv4UvlYli$lCj +X+^zWyW-3O+Tf{wA+N=DP_zCe}Iz2v9 + +literal 0 +HcmV?d00001 + +diff --git a/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/root.usdc b/pxr/usd/sdf/testenv/testSdfUsdcInvalidPrimChildren.testenv/root.usdc +new file mode 100644 +index 0000000000000000000000000000000000000000..651668dd7b6012b65e8fde4bfb4a973a697ceb58 +GIT binary patch +literal 38110 +zcmeHw33yY*+W&8o^z=Y_4yQd73Q`CK6_BN+VN=_*1r$)AK+BF0pg<7{Hbo%@ySVST +zpoj~IsDKMqP|+4aRK$H((5kqjVl0YEQgY`1yh$cGRJeMt_q)&k`<^?`)8_ZiyUhO1 +zoH?0E;l#1MipLEZ3>o3j=GMsP-wiXP1`>g==@tN504qbOX>GKo0WyFciR90L}(548U*zBLJKO;9LMB0gM7L8bBd{F#yH_7zdyTKrw*v044yK2w)O` +z$pEGRmIsE&xyt +zzyqKHICBYr3jthYlBc>7^2-2t0bC5g2VgmXO8`_x^F^TwKsA6G0G9%|48Y|8t^jZ) +zfU5vp4d5C8*8;c>!1Vxb0B|FK6##Ama5I2g08sZ_3E(yWw*y!O;0^$*0o)1TE&z7} +zxCg)*a6X*__X1c4;64EB0o)JZ0RRsI*Z^Q7fK31%0`M?^M*utuU^9SP0FME99KaR; +zTLC-);7I^a0oVrMX#mdvr~^Lz~m4GCPykTIe3A|xe829SYVpG1SSV7 +zFgaX-$*~Gdj#glDwgQtA7MPr}z%;Q4OcR{IG@%Jhlb^se!3j(gpujXS3QUutz%)4u +zOp~U-G_eXy6Pv&^*$PY(t-v%H3rrKOz%*eCOcT4nG?@!b6THAF$c$l{=tVqDsshu( +zKww%R2uzCxfob9qm=+JOzxG-Vu!p*^nBPnx4@epeTu1D@WBK7YT8TvYRVMzq1;Cm4 +zz>0ieYyq%4jN|&3n)p{7hfn&XL+PK0Pxb{rl2+V4rAcu+^AJvpZ0$7V?~*9LDnHI& +zVbT};876*}i7)bRwm-wfr#zeU*S!4Z{E7ORk#C`eK{!yIiXiIOT>nC!@;5nJSLXZ) +zK9x`K&E*sAL-i->+RU%d2Rao1d-5ZHi^4cwzYjKj^0wMB<3w +zF^bLU6Q9zj{_~IcLO&uKPhaR0U!-NWZw|4#HuVoGH`zQ<{wYty&pSc>?>3chQxtD7 +z<&XHnKJf`3kG~-w|4^UO7ipRGFE@=J!XM;QUgPyMD#|DQf5fNqlWcSSPYM8E{_O=< +z<^!J<0N;eMu)ntH99s67LUaE?c^3L>{-BR=+_TZ~O=%HcYsx?AMB)(Uf76VgIGF55 +z+K<|o@U}c!KSx3f6W=}j_qHOJ}3Bp?0*Q?pYT7#Cv0v%G3Ka$ +zA8&j{`gf%N5N@8nxqS#Xw=dd^>>n?Ep-=U9JihQR$lF>=<1gZC#Q2Jj$rJHuObh=a +ze2sbhi!o366S8K$@VUen{>99{y8u#tpW?*)-61-coApH;=@V{lU&Il=>v8xLC-QeZ +zzB&Iw)||fJ)BJxteRKb%`i=P7c>fXeJLQjXxc{z+^TqtWEkDlRW6~FV>c2wYJboQ{ +z@%~4+`S=ig(q9qfA5Wjs7yNkoYnxu(9JfF8w21vUzxEEnr+HkYALmB`<%!DwXZDFt +zW67*f{a5&(h%ctOFkXM={&T$kMSVIlryhTN(fmR_m-2VK`Gfqc;2+Qbngi*F=il%n +zC(KMF2!%Ww8335L}Owm52m +zm0OP367ZAU@=#NYP(W4>C;g%r++x@aYcRpz`kVF#Q-5nxze$#@M~$PB4MA&&!(y@h +zlmf&0ZTrxH4o7WYC8mUaM5tXTF=#Vv2ikp`X8F49cPD+_?r36@4Hj-`;s*jpdNn5h +z)}m4S-TrG!3+D%U+wW8P4{f+5WaEa#I1)@qJYxS5>fDC3#_k=o9Ht5OVY>^y!mm(HUs} +zBODrKN`|Et7bn25!mtJ{mZOOQTj)e7kT?ZV0-{BYQ7R&Z=G|?`nBoM4xHV)8CI)Ry +z7TT4fK)Yh$@VkXf<+m;#lUiI{TwIi&Iz*xk-jMAmxXogKTM}?6#6sRgF?nKo{jUnVkLyg7%k^kOeY(A&KjL9h5?#9A{!FZ*H~dgB)(=(S&rpm%>Uf?fc|2zm<`Bj{CNjG*^{ +zF@jzS#t3>d7$fNQV2q%5gfW6%6vha8TNoqgm0^sa_l7ZoULHn+Snr9zc_qCy3x^Y7 +zpeiQwckqeqo8$kE{r~EU@Za`|gnv&x{I_3;@Zb9UPxmXcZ#)tH-`GD-R2FmmUn!Sa +z{zUk%*!kZmbE5M8v+@5M%l_Xyi|~KLCyO10|FnPoEB)xNjHf@dW8O3Tca%}=G5$Mj +zMUDJv8UCBr|BbO`Zbz}nY>xXM#PrqPX!yTZmyz(FDVOjkKim4z*M#ZQ^>^@b?Cmhw +z`=_z62ULag7p#s)Sl6HrMmx@@p0@?KN0r+X)Nr; +z!{4jFcso$|d$#^vc_KT_^7U`&bAPr*h=hNfmicYRf3m)gZTG+5PQu<_SzG-T8Da0Q +z)Zt%|5$#WDFYdpdUWl9!i*~)Y>DAsR!hfXpa>&{$(5wybnb^<~sQ+p;!iM`EQb^^uA78*Q~Y=?%+WHTO-Zzvu#M?)Zk~ +zuGWqT_0ODd&E4_oa@Uk?o$H@oXw7ZiveI?!ij4YRZEABGc2v4vPwG-HUzM3Nb$g}j +z+MG%CtR^$(sl-ax6I&T}#oW +zzTuM0oE=9iT~&Eq>R*`m&6d-Hm9D%CCeceR%-mk->f3)(ecIB@oQc~jU3q;b)la!1 +zGv~7%m9EQ-jQZ`DX6EcXTIm|qx=TG82MxG#|8m#HejnC_7Fu&Z{dBqOw^uvYzg=q0 +zonGK`{rHfh{)bMzb4v?+uA47))E9T^o!fPY&-HTu59$UvdgpG~zufik?hor6^R2l@ +z?UkeYfj#j#s +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 +zUg?6_*HBHn#-h7SAgw +zFL~MaLfPUa6`s?}-Lp%VcvRe4T2@g~<|(aMmW;xZrHdDNu7R}=ie@cZu&6v8C9_NC +z%vs{;0JLZQmMn00LLMJ2RQ-YR7F#{wx200~k +z9@t-kB?-xcl8`)50_%^I0V!Z-hCeJxV3UzNa1@dUWFmP$0g?w0o`K{69g#fn8YB;p +zklc3^lKW;Nxo_9#C(#8+>DvQr0aCIu!Gok>3?!`gtQg7pO(4psm*66`#% +zUP#XB4mJYGS$&X_H5Dua$yo!CoHY>1S;LT=nK(aFl$=R7m$?gc&1IgL_ +zk(^zCJlAYy9ab|*zLUMlzDgAnY6(QMKfD~r|6*ak^gyjBbBDvov +zB=@@vDg9DlDF_SoI}^$MyCS83N`xd6lt_Q1^e=)X4VM03mtk=K0T_8o%UUchFS)R^ +zg}zRi+0c$4Mw@_eBaM>)Rf9mdu=8dSR)jbWzzPur^kf +zWY0K#=0!Mc$LvK*W-cfhS30|7HcFOOl$2Fq&VohmioVsh{g}CE(E?oPE-!V@EM4%R +zl{s*8_LONTEvuL^tq-=KV$t~}WhnN{E_5+#CS%*JUuMrig}Z!iNkyT%VxDIW9NBYn +zu+}}RWW2k4S!vna(HL7&zIf4sckBhT7L}DfX0!AIOJU4OKTYJGG7U@0N`JOxE-opT +zY}FN|7nY!GQQ246UtYS@IXjZzlxeX$5NQT<(*=joUrP!H`b85IGib~X)q>m=t1YQC +z`RY|^$XmO%rKX{k1xTG&gjN|y=+uoa=(FHwHV>$(u~;mYS&Uh%0h<+#wxe|asLgj} +zz;-2;@vC7h<1NtAhMQU}=2s%=u(F^7YHz{eWt{j|Vw89&zbW#K%ocfI$ZDCFAS273 +zH&I4bcO=Tt?G9x3$XlSnae%czc6S_+q4jQsLfG?cmT*ir8QRiT7z}%!Q-eNHhW=R^ +z91Yem_kaxTiwO6y28U)#MrL<>n}~ea^EznAa-h3RhKptBZW;PQ8Tv9A`sFh8n`G#B +z%g{H<(4UZ@KPN+fU536-hW@n-{g4bjBqO;+cb459sWSA=GW1?D^g%N8p)&L_GW2OO +z^imo65*d264E=f;`W-U#`(@~l$RWkGqGW0z%^aC=w$Sw2eI^z@b +z?SH~g`V+qLCw%o!_^tkgul)%>`A_&Mf5O-Qgx~rPeC^1o;r7{}p|5rAD>AxNeJ>*= +zC?j)iYHD|6TdSy3mdHq1CL?3*Dj6A7J7r|8eXUI$QbnDQM##M~QufK{yVlyS8&b}Y(Pix{8Tv~y^xtG;bZp-Z`Un|%jf|8>WjNLb +zI>Az#xWWarW%hTi;a^9v>*9?|1n107c +z4$rb5%tLktzLcRiMuxMa7~AIZ?am7yP&k-<8wg09NYPm-Zix1~{BAVVK5L!TNg`h_y|OJ(RQqAq8X4E-q? +z`U}w!{HYB62O0Vi85s%bYoVve&^yV{dq%y@Su*r-GV~cyALf;zUnxVsHR=)`m7&)~ +z#|U|vFJ$OHMd~M`MaQ+!+sM$n$j~#R-he84f((5&`4}1cB{KADW$3G-uIq6b`VJZT +zYf*>zjST%485!ub3Oc!$_A>NSW$4bR(;6j*8$Uc^$rskh&~KEX-z7sc=7xJ$twuwe +zYj6zf(Ed>MIt)1dE_k+C>i +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 +z2|TKzrcH2^cabS~*n)bmFl6!n$ +zql%i7g2N^Egun(BH64P(B=^L?gDPs$gJ(k=#=Q_o=Aq92_jUrv=ujsL2QxNbd6j_o}Gr63my}(*tW&)N~EzN$weeH7aUO +z4!R__J8+MRnp1+gl6z+0ZWT4B26H6$tiW9=YPto_l-#oecdDrA9y~*GmjqU;sOb?r +zU2@L}+@Yf8wBR7gJvXpQMNQA(K*>EXaJ!0{Ucmv9yEJf{ikjZR{*rrsV5N$hKEZyH +z`~1MIDrz!=PRYF>aEpqXtYEg}UKqGpMNQveU&&n-xJgA#b}&nFFAA(sQR56|O76vh +z8&%Zw3-*!R7X)rlQPV%zTXL5Nu2)erAlOTCdji*~s2LdSDY+{G*Q%%)6g*9GF9}?u +zqUQ8q56OLD;A#~$X9T-T?u!Cfsi-+K*iCXT4P2?BCMS5R?pZw0?QRtpB+q>+?NJ?3aW<%J4o)!0v9W&9v(bN +za$g?sDySY2Y%jU52rN@jeNM2QjEAH)nkIX7YAEO?wbN-3aZBkRmpvGV4;HQ2|-12-x64$pn763NpjyBIA1~a +zq@Z1LuMEsrP(3-=QgYuGC{<8BCD=l8-yWE!pn7UhmfWiXa}`ui3nohLI|6eQRG$}= +zB=_n-iGu3s!34>DXJEF1>KQ?s&K6&8dXqMcPHta(&DfQjiY(ap*)=J}-A5GN-)+pwbwi33_zzib8d7{#N^!g4 +zMI~Lwth{$f@f95z6v*vyxI-%IHJjg!DLlcjg^ULp@J#3~O&b!!bJDh8n+YaZQti%rI +zS~kND=Y4FN9nNdn5<8sh*;G56cd)s3I9Ibdb~x{6Q|xfAW9Ql7yq8V4!?}r#x5K%S +zO|ZlH5G%IB`7kT8!+9O6u*3Nn8*PX4aW={hXDutV!?}fxw8OcXjj_YIflai-xs{!3 +zhw~{m+z#h9Hp~v^BW#=<&TH6(b~qnpW9@K0$R^q0e43qYhx17`!Vc#X>>N9s&$0qL +zoZH!8JDfXMz8%hbHpC8R9UE$g^Lpm7!?~EPu)}!~yV?%tB6gD<&SmUMJDe5lIy;;f +zup8}gE@9W&;k=MtV~5kjuD8RvklkX3^9ELKhqH{`Y=^U)-C&1v0lU=>=Tdf+9nMmA +zyB*G%>>fLu^VljooO9S}JDlgUm3BDiv)k-&u3(GpaL#6T+2Jf1J!} +zaL#3S*zt>$!rXi#e5JzEj?LqD;A<70wroDX9p9?(v|;D-+i*aICzUPW +zEAgEQPiwZ2--_>5cyw0AZ@~{LJSl7uzZnNrc#_#-eiMFF;nCOydz +z;Tg;N@OSXA3QsN@%%8b=JR^jQ-&f!mDj|z{IjpSSLiVDvF +zHiAEemsEJN*(kmRud472WW)J3>{j79gPq0e@Vp977j_=M4`7?Myg=Y{O#-GNEDm(?u#do1zg(sio@#nBz +zg=a9!<Sm2Y*FDko1M;I!c!_dc`Tpr#Iq_q=dynMH9W4uGn)0~Z(_3wPa(_VZ{blDo}uha +z{vw`M;mKgr`8qVH@SMfY;JdL+g~!DT_zvt);Tgj+`P+Czg=ZAY=5L@@g=Zvl^4Ia0 +z3eR|U8vg(rRCtP6PyRkOs_;x;J@|)sP=%+6_2TbglM2r`)|fk7*r&oH +zG1?Y9qQaxF3VuBfsqiE)AHN&{6`oeCoZpC_RCrpli}*D-tiqGXy!=Z1uEJwy7xHWI +ziwaK?Tf(oy&ni4E*iwEqepTVIvP<}-Xj0)hg-ziPV6O^~jVQN=ipno6F8nMZK-Qi8d!d|!ogrMdobkxuq~D~969LkWIfTGqY90LWsO_j!ze&x(i60oMp(kgU>Goxh!__LLa +zab~poB>{X_VHk_2#FL}Okw@R|w9(gp`00J}iWyGol(3x5aargmTGtm^xs_Ymh_Bf$ +zBCVoghVGpO-)5YQ7TYaNI#mH +z&^nKy2zf=tsq}N07HCBYVIzGCSt`QcRLV<8q;Dy;+JJ=2)Z)~WpbbqxLLxHnFS<#E +zVnL@nx-ltza!*(+KqER1X+)MO+Tw>MKQR5?*>{!RUUswR`lVMb +zzqAIIgulgf9V+-uSj2C`e10cN_*%^1_hSm*gzL<_M?%;4jAd| +zOCy7QYMjdU89mv1MizV1=+9m;&R{PZd2FXKl+_s{*ptR+_Lxz`9yTVi2aWUCI%5{Q +z+nC2z84KAhMmf8|xQJbC_}FDeHLEnPU|!=|w!~P$78@(s`NnEC$5_MM#(Fl@*vKXr +zkFv4G7BWNmdQ#UE;QxP|p_DCzgqN;EoxEq+h3TKy^h)F09goMio?^JiTfPTkkT +z`fjH6_5NQ-UktKZtu|{Yp!}j)t%qA>Q_~HbVYAt6N0KBQdcbCDY;CjIUUTm6YTMiM +z$euLq;K3pFc{_V{u-R-64|KejdH87SwP$vFZ+~H}me%vV_j>Mi4BVg{?0ICrqoM1W +zwzacus}>xUm-6diyK3sT_ilyNVk9)lN9@0 +z>+^QsH~PIgaL*Yp=I+YhF{J+Nr$;3;0i#Wq(J%m@$kH3Mw{B88%@1bXs +z^$Un0G=^$@;8TYeC&`Aixj>PwlUN1DRaOhw&|E3!w{L7>M@c#iB +C@)ZIA + +literal 0 +HcmV?d00001 + +-- +2.52.0 + diff --git a/usd.spec b/usd.spec index ba937db..2a9d568 100644 --- a/usd.spec +++ b/usd.spec @@ -156,6 +156,23 @@ Patch: 0006-Downstream-only-use-the-system-libavif.patch # Rebased on v25.08 Patch: 0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch +# sdf: Guard against invalid primChildren in crate files +# https://github.com/PixarAnimationStudios/OpenUSD/commit/b9530922b6a8ea72cd43661226b693fff8abbe4c +# +# Fixes: +# +# CVE-2025-14439 usd: OpenUSD File Parsing Use-After-Free Remote Code Execution +# Vulnerability [fedora-43] +# https://bugzilla.redhat.com/show_bug.cgi?id=2422276 +# +# …which is: +# +# OpenUSD File Parsing Use-After-Free Remote Code Execution Vulnerability +# https://github.com/advisories/GHSA-grjp-54v3-c442 +# +# Cherry-picked on v25.08. +Patch: 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch + # Base BuildRequires: gcc-c++ @@ -166,6 +183,9 @@ BuildRequires: ninja-build BuildRequires: dos2unix BuildRequires: help2man +# For applying 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch, +# which includes binary diffs. +BuildRequires: git-core BuildRequires: pkgconfig(blosc) BuildRequires: pkgconfig(dri) @@ -407,7 +427,10 @@ Requires: usd-libs%{?_isa} = %{version}-%{release} Python language bindings for the Universal Scene Description (USD) C++ API %prep -%autosetup -p1 -n OpenUSD-%{version} +# The -S git is for applying +# 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch, which +# includes binary diffs. +%autosetup -p1 -n OpenUSD-%{version} -S git # Convert NOTICE.txt from CRNL line encoding dos2unix NOTICE.txt From 30f8fab7704965d103dae3a74e21f60b06b48e5c Mon Sep 17 00:00:00 2001 From: Luya Tshimbalanga Date: Wed, 7 Jan 2026 18:38:55 -0800 Subject: [PATCH 08/15] Remove unused MaterialX support This commit removed the unusued materialx support dropped by upstream. --- usd.spec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/usd.spec b/usd.spec index 2a9d568..9576f6f 100644 --- a/usd.spec +++ b/usd.spec @@ -8,9 +8,6 @@ %bcond draco 1 %bcond embree 1 %bcond jemalloc 0 -# Not yet packaged: https://github.com/AcademySoftwareFoundation/MaterialX -# https://bugzilla.redhat.com/show_bug.cgi?id=2262694 -%bcond materialx 0 # Default "UNIX Makefiles" backend for CMake would also work fine; ninja is a # bit faster. We conditionalize it just in case there are backend-specific # issues in the future. @@ -599,7 +596,6 @@ extra_flags="${extra_flags-} -DTBB_SUPPRESS_DEPRECATED_MESSAGES=1" -DPXR_BUILD_ALEMBIC_PLUGIN=%{expr:%{with alembic}?"ON":"OFF"} \ -DPXR_BUILD_DRACO_PLUGIN=%{expr:%{with draco}?"ON":"OFF"} \ -DPXR_BUILD_EMBREE_PLUGIN=%{expr:%{with embree}?"ON":"OFF"} \ - -DPXR_BUILD_MATERIALX_PLUGIN=%{expr:%{with materialx}?"ON":"OFF"} \ -DPXR_BUILD_OPENCOLORIO_PLUGIN=%{expr:%{with ocio}?"ON":"OFF"} \ -DPXR_BUILD_OPENIMAGEIO_PLUGIN=%{expr:%{with oiio}?"ON":"OFF"} \ -DPXR_BUILD_PRMAN_PLUGIN=OFF \ From c42e9560b7ffae24bcdb70aebd00227c2dfa1d79 Mon Sep 17 00:00:00 2001 From: Luya Tshimbalanga Date: Thu, 8 Jan 2026 08:01:05 -0800 Subject: [PATCH 09/15] Enable materialx support --- usd.spec | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/usd.spec b/usd.spec index 9576f6f..d792f31 100644 --- a/usd.spec +++ b/usd.spec @@ -8,6 +8,7 @@ %bcond draco 1 %bcond embree 1 %bcond jemalloc 0 +%bcond materialx 1 # Default "UNIX Makefiles" backend for CMake would also work fine; ninja is a # bit faster. We conditionalize it just in case there are backend-specific # issues in the future. @@ -226,6 +227,13 @@ BuildRequires: embree-devel BuildRequires: pkgconfig(jemalloc) %endif +%if %{with materialx} +BuildRequires: cmake(materialx) +BuildRequires: materialx-data +BuildRequires: pkgconfig(xt) +BuildRequires: python3-materialx +%endif + %if %{with ocio} BuildRequires: cmake(OpenColorIO) %endif @@ -605,6 +613,7 @@ extra_flags="${extra_flags-} -DTBB_SUPPRESS_DEPRECATED_MESSAGES=1" -DPXR_ENABLE_PTEX_SUPPORT=%{expr:%{with ptex}?"ON":"OFF"} \ -DPXR_ENABLE_OSL_SUPPORT=%{expr:%{with openshading}?"ON":"OFF"} \ -DPXR_ENABLE_MALLOCHOOK_SUPPORT=OFF \ + -DPXR_ENABLE_MATERIALX_SUPPORT=%{expr:%{with materialx}?"ON":"OFF"} \ -DPXR_ENABLE_PYTHON_SUPPORT=ON \ \ -DPXR_INSTALL_LOCATION="%{_libdir}/usd/plugin" \ @@ -670,6 +679,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.openusd.usdview.d %{_bindir}/hdGenSchema %{_bindir}/sdfdump %{_bindir}/sdffilter +%if %{with materialx} +%{_bindir}/usdBakeMaterialX +%endif %{_bindir}/usdGenSchema %{_bindir}/usdInitSchema %{_bindir}/usdcat @@ -698,6 +710,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.openusd.usdview.d %{_mandir}/man1/hdGenSchema.1* %{_mandir}/man1/sdfdump.1* %{_mandir}/man1/sdffilter.1* +%if %{with materialx} +%{_bindir}/usdBakeMaterialX.1* +%endif %{_mandir}/man1/usdGenSchema.1* %{_mandir}/man1/usdInitSchema.1* %{_mandir}/man1/usdcat.1* From 19df409851b4a0f12dacf024e8582352e9390d19 Mon Sep 17 00:00:00 2001 From: Luya Tshimbalanga Date: Thu, 8 Jan 2026 09:09:41 -0800 Subject: [PATCH 10/15] Fix manpage line --- usd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usd.spec b/usd.spec index d792f31..97df2ac 100644 --- a/usd.spec +++ b/usd.spec @@ -711,7 +711,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.openusd.usdview.d %{_mandir}/man1/sdfdump.1* %{_mandir}/man1/sdffilter.1* %if %{with materialx} -%{_bindir}/usdBakeMaterialX.1* +%{_mandir}/usdBakeMaterialX.1* %endif %{_mandir}/man1/usdGenSchema.1* %{_mandir}/man1/usdInitSchema.1* From 0fbf7be4a4518e04f4c32c291f71629e069dccc8 Mon Sep 17 00:00:00 2001 From: Luya Tshimbalanga Date: Thu, 8 Jan 2026 15:16:34 -0800 Subject: [PATCH 11/15] Fix path for manterialx manual --- usd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usd.spec b/usd.spec index 97df2ac..5684513 100644 --- a/usd.spec +++ b/usd.spec @@ -711,7 +711,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.openusd.usdview.d %{_mandir}/man1/sdfdump.1* %{_mandir}/man1/sdffilter.1* %if %{with materialx} -%{_mandir}/usdBakeMaterialX.1* +%{_mandir}/man1/usdBakeMaterialX.1* %endif %{_mandir}/man1/usdGenSchema.1* %{_mandir}/man1/usdInitSchema.1* From 9f0cb9518662121af7c95c86f3795c86ad4e6cf5 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Sat, 21 Feb 2026 12:24:33 -0700 Subject: [PATCH 12/15] Make devel require cmake(OpenSubdiv) and cmake(materialx) --- usd.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/usd.spec b/usd.spec index 5684513..4e706ca 100644 --- a/usd.spec +++ b/usd.spec @@ -396,6 +396,11 @@ Requires: usd-libs%{?_isa} = %{version}-%{release} # Unbundled, and exposed in the API: Requires: cli11-devel cli11-static Requires: robin-map-devel robin-map-static +# Needed by cmake config +Requires: cmake(OpenSubdiv) +%if %{with materialx} +Requires: cmake(materialx) +%endif %description devel This package contains the C++ header files and symbolic links to the shared From 5cfa713d7ced8adea52ee14f4eca0f45db2f9df2 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Mon, 6 Apr 2026 13:07:00 +0100 Subject: [PATCH 13/15] Backport fix for CVE-2026-34544 in OpenEXRCore - Fixes RHBZ#2454226 --- ...eger-overflow-use-uint64_t-for-row-o.patch | 74 +++++++++++++++++++ usd.spec | 4 + 2 files changed, 78 insertions(+) create mode 100644 0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch diff --git a/0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch b/0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch new file mode 100644 index 0000000..5b50927 --- /dev/null +++ b/0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch @@ -0,0 +1,74 @@ +From ae97658675f83466d13149178ccfad95731c3ed2 Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Thu, 19 Mar 2026 14:22:40 -0700 +Subject: [PATCH] Fix B44/B44A integer overflow: use uint64_t for row offset + (#2312) + +The B44 and B44A decoder and encoder use channel width (`nx`) and +height (`ny`) in row pointer math. `nx` and `ny` are `int`; the +scratch buffer is correctly sized with `(uint64_t)ny * (uint64_t)nx * +bytes_per_element`, but row bases were computed as: + +``` + row0 = (uint16_t*)scratch; + row0 += y * nx; // int * int -> signed overflow when y*nx > INT_MAX +``` + +For large `nx` (e.g. 268435456), `y*nx` overflows, so `row0`/`row1`/`row2`/`row3` +point before the scratch buffer. + +Fix: compute the row offset in `uint64_t` before pointer arithmetic in both +`uncompress_b44_impl` (decoder) and `compress_b44_impl` (encoder). + +Analysis and solution with the help of Curor / Claude Opus 4.5 + +Signed-off-by: Cary Phillips +--- + .../hio/OpenEXR/OpenEXRCore/internal_b44.c | 23 ++++++++++--------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_b44.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_b44.c +index 8d0c257e6..93279ff2e 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_b44.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_b44.c +@@ -390,13 +390,13 @@ compress_b44_impl (exr_encode_pipeline_t* encode, int flat_field) + // rightmost column and the bottom row. + // + uint16_t *row0, *row1, *row2, *row3; ++ /* row offset in elements: use uint64_t so y*nx cannot overflow int */ ++ uint64_t row_off = (uint64_t) (y) * (uint64_t) (nx); + +- row0 = (uint16_t*) scratch; +- row0 += y * nx; +- +- row1 = row0 + nx; +- row2 = row1 + nx; +- row3 = row2 + nx; ++ row0 = (uint16_t*) scratch + row_off; ++ row1 = row0 + (uint64_t) nx; ++ row2 = row1 + (uint64_t) nx; ++ row3 = row2 + (uint64_t) nx; + + if (y + 3 >= ny) + { +@@ -512,11 +512,12 @@ uncompress_b44_impl ( + + for (int y = 0; y < ny; y += 4) + { +- row0 = (uint16_t*) scratch; +- row0 += y * nx; +- row1 = row0 + nx; +- row2 = row1 + nx; +- row3 = row2 + nx; ++ /* row offset in elements: use uint64_t so y*nx cannot overflow int */ ++ uint64_t row_off = (uint64_t) (y) * (uint64_t) (nx); ++ row0 = (uint16_t*) scratch + row_off; ++ row1 = row0 + (uint64_t) nx; ++ row2 = row1 + (uint64_t) nx; ++ row3 = row2 + (uint64_t) nx; + for (int x = 0; x < nx; x += 4) + { + if (bIn + 3 > comp_buf_size) return EXR_ERR_OUT_OF_MEMORY; +-- +2.53.0 + diff --git a/usd.spec b/usd.spec index 4e706ca..a66f331 100644 --- a/usd.spec +++ b/usd.spec @@ -170,6 +170,10 @@ Patch: 0001-Backport-fixes-for-CVE-2025-64181-etc.-in-OpenEXRCor.patch # # Cherry-picked on v25.08. Patch: 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch +# Backport fix for CVE-2026-34544 in OpenEXRCore +# https://github.com/PixarAnimationStudios/OpenUSD/pull/4028 +# Cherry-picked on v25.08. +Patch: 0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch # Base BuildRequires: gcc-c++ From 5b067fcf4440919772027e284998e90818ac3dcc Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Wed, 8 Apr 2026 11:58:16 +0100 Subject: [PATCH 14/15] Backport several OpenEXRCore security fixes - Fixes CVE-2026-34378 / GHSA-v76p-4qvv-vh4g; closes RHBZ#2455493 - Fixes CVE-2026-34380 / GHSA-q3v8-hw4m-59w5; closes RHBZ#2455534 - Fixes CVE-2026-34588 / GHSA-588r-cr5c-w6hf; closes RHBZ#2455505 - Fixes CVE-2026-34589 / GHSA-p8xc-w3q4-h64x; closes RHBZ#2455501 - Fixes CVE-2026-34379 / GHSA-w88v-vqhq-5p24; closes RHBZ#2455497 --- usd-25.08-pr-4030.patch | 630 ++++++++++++++++++++++++++++++++++++++++ usd.spec | 10 + 2 files changed, 640 insertions(+) create mode 100644 usd-25.08-pr-4030.patch diff --git a/usd-25.08-pr-4030.patch b/usd-25.08-pr-4030.patch new file mode 100644 index 0000000..3b1000b --- /dev/null +++ b/usd-25.08-pr-4030.patch @@ -0,0 +1,630 @@ +From e3c7f7bdf877aae4961a6d6f38f14ae7e3484640 Mon Sep 17 00:00:00 2001 +From: Christoph Gohlke +Date: Tue, 17 Mar 2026 20:56:39 -0700 +Subject: [PATCH 1/6] Fix comparison operator for buffer size check (#2307) + +Signed-off-by: Christoph Gohlke +--- + pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_zip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_zip.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_zip.c +index 628438c5c..56df6a49c 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_zip.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_zip.c +@@ -367,7 +367,7 @@ apply_zip_impl (exr_encode_pipeline_t* encode) + + if (rv == EXR_ERR_SUCCESS) + { +- if (compbufsz > encode->packed_bytes) ++ if (compbufsz >= encode->packed_bytes) + { + memcpy ( + encode->compressed_buffer, +-- +2.53.0 + + +From 2d415fb1a62e8c951e3c515a3cb46bda7cc60749 Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Thu, 26 Mar 2026 16:35:49 -0700 +Subject: [PATCH 2/6] Fix integer overflow in `srcbuffer` pointer arithmetic in + `unpack_*` (#2321) + +Pointer arithmetic involving `srcbuffer` in the `unpack_*` functions +can overflow for very wide images. + +Multiplying `int w` by a bytes-per-element constant (2, 4, 6, or 8) in +`srcbuffer +=` expressions causes signed integer overflow when the +image width is large. + +Promote the leading operand to `int64_t` at every affected multiplication +so pointer arithmetic is performed in 64-bit signed arithmetic throughout, +eliminating the undefined behavior without imposing any image size limit. + +Affected sites: `generic_unpack`, `unpack_16bit`, `unpack_32bit`, and +all 3- and 4-channel interleave/planar specializations. + +Made-with: Cursor + +Signed-off-by: Cary Phillips +--- + pxr/imaging/hio/OpenEXR/OpenEXRCore/unpack.c | 38 ++++++++++---------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/unpack.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/unpack.c +index b88c98974..a311f9129 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/unpack.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/unpack.c +@@ -229,7 +229,7 @@ unpack_16bit_3chan_interleave (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = one_to_native16 (in0[x]); +@@ -269,7 +269,7 @@ unpack_16bit_3chan_interleave_rev (exr_decode_pipeline_t* decode) + in1 = in0 + w; // G + in2 = in1 + w; // R + +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = one_to_native16 (in2[x]); +@@ -309,7 +309,7 @@ unpack_half_to_float_3chan_interleave (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = half_to_float (one_to_native16 (in0[x])); +@@ -349,7 +349,7 @@ unpack_half_to_float_3chan_interleave_rev (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = half_to_float (one_to_native16 (in2[x])); +@@ -390,7 +390,7 @@ unpack_16bit_3chan_planar (exr_decode_pipeline_t* decode) + in0 = (const uint16_t*) srcbuffer; + in1 = in0 + w; + in2 = in1 + w; +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + /* specialise to memcpy if we can */ + #if EXR_HOST_IS_NOT_LITTLE_ENDIAN + for (int x = 0; x < w; ++x) +@@ -440,7 +440,7 @@ unpack_half_to_float_3chan_planar (exr_decode_pipeline_t* decode) + in0 = (const uint16_t*) srcbuffer; + in1 = in0 + w; + in2 = in1 + w; +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + /* specialise to memcpy if we can */ + half_to_float_buffer ((float*) out0, in0, w); + half_to_float_buffer ((float*) out1, in1, w); +@@ -485,7 +485,7 @@ unpack_16bit_3chan (exr_decode_pipeline_t* decode) + in0 = (const uint16_t*) srcbuffer; + in1 = in0 + w; + in2 = in1 + w; +- srcbuffer += w * 6; // 3 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 6; // 3 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + *((uint16_t*) (out0 + x * inc0)) = one_to_native16 (in0[x]); + for (int x = 0; x < w; ++x) +@@ -539,7 +539,7 @@ unpack_16bit_4chan_interleave (exr_decode_pipeline_t* decode) + in2 = in1 + w; + in3 = in2 + w; + +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + combined.a = one_to_native16 (in0[x]); +@@ -592,7 +592,7 @@ unpack_16bit_4chan_interleave_rev (exr_decode_pipeline_t* decode) + in2 = in1 + w; + in3 = in2 + w; + +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + combined.a = one_to_native16 (in0[x]); +@@ -633,7 +633,7 @@ unpack_half_to_float_4chan_interleave (exr_decode_pipeline_t* decode) + in2 = in1 + w; + in3 = in2 + w; + +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = half_to_float (one_to_native16 (in3[x])); +@@ -674,7 +674,7 @@ unpack_half_to_float_4chan_interleave_rev (exr_decode_pipeline_t* decode) + in2 = in1 + w; + in3 = in2 + w; + +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + { + out[0] = half_to_float (one_to_native16 (in0[x])); +@@ -719,7 +719,7 @@ unpack_16bit_4chan_planar (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + in3 = in2 + w; +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + /* specialize to memcpy if we can */ + #if EXR_HOST_IS_NOT_LITTLE_ENDIAN + for (int x = 0; x < w; ++x) +@@ -775,7 +775,7 @@ unpack_half_to_float_4chan_planar (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + in3 = in2 + w; +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + + half_to_float_buffer ((float*) out0, in0, w); + half_to_float_buffer ((float*) out1, in1, w); +@@ -825,7 +825,7 @@ unpack_16bit_4chan (exr_decode_pipeline_t* decode) + in1 = in0 + w; + in2 = in1 + w; + in3 = in2 + w; +- srcbuffer += w * 8; // 4 * sizeof(uint16_t), avoid type conversion ++ srcbuffer += (int64_t) w * 8; // 4 * sizeof(uint16_t), avoid type conversion + for (int x = 0; x < w; ++x) + *((uint16_t*) (out0 + x * inc0)) = one_to_native16 (in0[x]); + for (int x = 0; x < w; ++x) +@@ -898,7 +898,7 @@ unpack_16bit (exr_decode_pipeline_t* decode) + } + } + #endif +- srcbuffer += w * 2; ++ srcbuffer += (int64_t) w * 2; + } + } + return EXR_ERR_SUCCESS; +@@ -963,7 +963,7 @@ unpack_32bit (exr_decode_pipeline_t* decode) + } + } + #endif +- srcbuffer += w * 4; ++ srcbuffer += (int64_t) w * 4; + } + } + return EXR_ERR_SUCCESS; +@@ -1118,7 +1118,7 @@ generic_unpack (exr_decode_pipeline_t* decode) + (uint64_t) decc->user_line_stride); + else + { +- srcbuffer += w * bpc; ++ srcbuffer += (int64_t) w * bpc; + continue; + } + } +@@ -1128,12 +1128,12 @@ generic_unpack (exr_decode_pipeline_t* decode) + } + else + { +- srcbuffer += w * bpc; ++ srcbuffer += (int64_t) w * bpc; + continue; + } + + UNPACK_SAMPLES (w) +- srcbuffer += w * bpc; ++ srcbuffer += (int64_t) w * bpc; + } + } + return EXR_ERR_SUCCESS; +-- +2.53.0 + + +From b76c840e5c0b7a99e25c02e2ced420b4a8af0896 Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Sun, 29 Mar 2026 19:19:12 -0700 +Subject: [PATCH 3/6] Security: fix signed integer overflow in + `undo_pxr24_impl()` (PXR24 decoder) (#2323) + +In the `EXR_PIXEL_FLOAT` branch of `undo_pxr24_impl()`, the expressions + + (uint64_t)(w * 3) + +compute the signed 32-bit product `w * 3` before the cast to `uint64_t`. +When `w` is large this is undefined behavior under the C standard; on +two's-complement builds without sanitizers the result wraps to a small +positive value, which can cause the bounds check + + if (nDec + (uint64_t)(w * 3) > outSize) + +to pass incorrectly. If the check is bypassed the decode loop proceeds +to write `4*w` bytes through `dout`, potentially far beyond the allocated +output buffer. + +Fix: cast `w` to `uint64_t` before multiplying so that both the bounds +check and the counter update are performed entirely in 64-bit unsigned +arithmetic: + + (uint64_t)w * 3 (cast before multiply, not after) + +The `EXR_PIXEL_UINT` and `EXR_PIXEL_HALF` decode branches are unaffected: +they reuse the pre-computed `nBytes` variable, which is already formed as +`(uint64_t)(w) * (uint64_t)(bytes_per_element)`. + +Also fix the symmetric issue in `apply_pxr24_impl()` (the encoder): + lastIn += w * 4 +advances a pointer by a signed 32-bit product; corrected to + lastIn += (uint64_t)w * 4 + +Made-with: Cursor + +Signed-off-by: Cary Phillips +--- + pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_pxr24.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_pxr24.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_pxr24.c +index 43e52c982..30f71f4f8 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_pxr24.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_pxr24.c +@@ -182,7 +182,7 @@ apply_pxr24_impl (exr_encode_pipeline_t* encode) + if (nOut + nBytes > encode->scratch_alloc_size_1) + return EXR_ERR_OUT_OF_MEMORY; + nOut += nBytes; +- lastIn += w * 4; ++ lastIn += (uint64_t) w * 4; + + ptr[0] = out; + out += w; +@@ -371,7 +371,7 @@ undo_pxr24_impl ( + ptr[2] = lastIn; + lastIn += w; + +- if (nDec + (uint64_t) (w * 3) > outSize) ++ if (nDec + (uint64_t) w * 3 > outSize) + return EXR_ERR_CORRUPT_CHUNK; + + for (int x = 0; x < w; ++x) +@@ -384,7 +384,7 @@ undo_pxr24_impl ( + unaligned_store32 (dout, pixel); + ++dout; + } +- nDec += (uint64_t) (w * 3); ++ nDec += (uint64_t) w * 3; + break; + } + default: return EXR_ERR_INVALID_ARGUMENT; +-- +2.53.0 + + +From 72af902014ba12d414f31b585175723bc7e62cd2 Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Sun, 29 Mar 2026 19:19:49 -0700 +Subject: [PATCH 4/6] fix integer overflow in PIZ wavelet buffer arithmetic + (#2328) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Three classes of signed integer overflow in the PIZ codec path, all +reachable from corrupt `dataWindow` dimensions in the EXR file header. + +**`wav_2D_encode` / `wav_2D_decode` — wavelet loop pointer arithmetic** + +`oy` is passed as `int` (value `wcount * nx`, at most ~INT32_MAX after +the guard below). Inside the hierarchical wavelet loop the expressions + + ey = in + oy * (ny - p2) // pointer end-of-row sentinel + oy1 = oy * p // row stride at level p + oy2 = oy * p2 // row stride at level p2 + +multiply two values that can each approach INT32_MAX, producing a +signed 32-bit product that wraps to a small or negative value. The +wrapped value is used as a pointer offset, causing reads and writes +through `px` / `py` to land outside the allocated wavelet buffer. + +Fix: widen by introducing `int64_t oy64 = oy` and using it for all +three expressions; `oy1` and `oy2` are also declared `int64_t`. + +**`wavbuf += nx * ny * wcount` — per-channel buffer advance** + +`nx`, `ny`, and `wcount` are all `int`. Their triple product overflows +int32 for moderately large images, causing subsequent channels to be +processed at an incorrect (too-small) offset into the wavelet buffer, +corrupting both encode and decode output. + +Fix: cast to `(uint64_t)` before multiplying. + +**`wcount * nx` — call-site argument overflow** + +The fifth argument to `wav_2D_encode` / `wav_2D_decode` is `wcount * nx` +(`oy` = y-stride = elements per row). `wcount` is 1 or 2 +(`bytes_per_element / 2`); for `wcount = 2` the product overflows int32 +when `nx > INT32_MAX / 2`. + +Fix: add an early bounds check `if (wcount > 0 && nx > INT_MAX / wcount)` +that rejects such input as `EXR_ERR_CORRUPT_CHUNK` before any arithmetic +is performed. This also keeps `wcount * nx` within int32 range at the +call site, ensuring `oy` arrives in the wavelet functions with a valid +non-overflowed value. + +Made-with: Cursor + +Signed-off-by: Cary Phillips +--- + .../hio/OpenEXR/OpenEXRCore/internal_piz.c | 39 +++++++++++-------- + 1 file changed, 23 insertions(+), 16 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_piz.c b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_piz.c +index 6c2750b16..787d2752c 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_piz.c ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_piz.c +@@ -10,6 +10,7 @@ + #include "internal_huf.h" + #include "internal_xdr.h" + ++#include + #include + + /**************************************/ +@@ -171,10 +172,11 @@ wdec16 (uint16_t l, uint16_t h, uint16_t* a, uint16_t* b) + static void + wav_2D_encode (uint16_t* in, int nx, int ox, int ny, int oy, uint16_t mx) + { +- int w14 = (mx < (1 << 14)) ? 1 : 0; +- int n = (nx > ny) ? ny : nx; +- int p = 1; // == 1 << level +- int p2 = 2; // == 1 << (level+1) ++ int w14 = (mx < (1 << 14)) ? 1 : 0; ++ int n = (nx > ny) ? ny : nx; ++ int p = 1; // == 1 << level ++ int p2 = 2; // == 1 << (level+1) ++ int64_t oy64 = oy; + + // + // Hierarchical loop on smaller dimension n +@@ -183,9 +185,9 @@ wav_2D_encode (uint16_t* in, int nx, int ox, int ny, int oy, uint16_t mx) + while (p2 <= n) + { + uint16_t* py = in; +- uint16_t* ey = in + oy * (ny - p2); +- int oy1 = oy * p; +- int oy2 = oy * p2; ++ uint16_t* ey = in + oy64 * (ny - p2); ++ int64_t oy1 = oy64 * p; ++ int64_t oy2 = oy64 * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + uint16_t i00, i01, i10, i11; +@@ -284,10 +286,11 @@ wav_2D_decode ( + int oy, // i : y offset + uint16_t mx) // i : maximum in[x][y] value + { +- int w14 = (mx < (1 << 14)) ? 1 : 0; +- int n = (nx > ny) ? ny : nx; +- int p = 1; +- int p2; ++ int w14 = (mx < (1 << 14)) ? 1 : 0; ++ int n = (nx > ny) ? ny : nx; ++ int p = 1; ++ int p2; ++ int64_t oy64 = oy; + + // + // Search max level +@@ -307,9 +310,9 @@ wav_2D_decode ( + while (p >= 1) + { + uint16_t* py = in; +- uint16_t* ey = in + oy * (ny - p2); +- int oy1 = oy * p; +- int oy2 = oy * p2; ++ uint16_t* ey = in + oy64 * (ny - p2); ++ int64_t oy1 = oy64 * p; ++ int64_t oy2 = oy64 * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + uint16_t i00, i01, i10, i11; +@@ -502,11 +505,13 @@ internal_exr_apply_piz (exr_encode_pipeline_t* encode) + nx = curc->width; + ny = curc->height; + wcount = (int) (curc->bytes_per_element / 2); ++ if (wcount > 0 && nx > INT_MAX / wcount) ++ return EXR_ERR_CORRUPT_CHUNK; + for (int j = 0; j < wcount; ++j) + { + wav_2D_encode (wavbuf + j, nx, wcount, ny, wcount * nx, maxValue); + } +- wavbuf += nx * ny * wcount; ++ wavbuf += (uint64_t) nx * ny * wcount; + } + + nBytes = 0; +@@ -655,11 +660,13 @@ internal_exr_undo_piz ( + nx = curc->width; + ny = curc->height; + wcount = (int) (curc->bytes_per_element / 2); ++ if (wcount > 0 && nx > INT_MAX / wcount) ++ return EXR_ERR_CORRUPT_CHUNK; + for (int j = 0; j < wcount; ++j) + { + wav_2D_decode (wavbuf + j, nx, wcount, ny, wcount * nx, maxValue); + } +- wavbuf += nx * ny * wcount; ++ wavbuf += (uint64_t) nx * ny * wcount; + } + + // +-- +2.53.0 + + +From 7d3eb08f2322d199a874602e961d63004a145650 Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Sun, 29 Mar 2026 19:20:52 -0700 +Subject: [PATCH 5/6] Fix signed integer overflow in + `LossyDctDecoder_execute()` pointer arithmetic (#2329) + +`numBlocksX` and `numBlocksY` are declared as `int`. Two pointer-offset +expressions in `LossyDctDecoder_execute()` multiplied them as signed +32-bit integers before using the result as a pointer offset: + + rowBlock[comp] = rowBlock[comp - 1] + numBlocksX * 64; + currDcComp[comp] = currDcComp[comp - 1] + numBlocksX * numBlocksY; + +`dataWindow.max.x` is a signed 32-bit value in the EXR file format, so +`numBlocksX` can reach `(INT32_MAX + 7) / 8 = 268,435,456`. At that +point `numBlocksX * 64 = 17,179,869,184` overflows `int32`, and +`numBlocksX * numBlocksY` overflows even sooner. The wraparound +produces a small or negative pointer offset, causing `rowBlock[comp]` +and `currDcComp[comp]` to point into already-used or pre-buffer memory +rather than the intended component stride. + +Fix: cast `numBlocksX` to `size_t` before multiplying so the +arithmetic is performed in pointer-sized unsigned arithmetic: + + rowBlock[comp] = rowBlock[comp - 1] + (size_t) numBlocksX * 64; + currDcComp[comp] = currDcComp[comp - 1] + (size_t) numBlocksX * numBlocksY; + +This is consistent with the allocation on the line above, which already +uses `(size_t) numComp * (size_t) numBlocksX * 64 * sizeof(uint16_t)`, +and with the packed-DC count check, which uses explicit `uint64_t` casts. + +Made-with: Cursor + +Signed-off-by: Cary Phillips +--- + pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h +index bcdebd985..e289b064d 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h +@@ -265,7 +265,7 @@ LossyDctDecoder_execute ( + } + + for (int comp = 1; comp < numComp; ++comp) +- rowBlock[comp] = rowBlock[comp - 1] + numBlocksX * 64; ++ rowBlock[comp] = rowBlock[comp - 1] + (size_t) numBlocksX * 64; + + // + // Pack DC components together by common plane, so we can get +@@ -275,7 +275,7 @@ LossyDctDecoder_execute ( + + currDcComp[0] = (uint16_t*) d->_packedDc; + for (int comp = 1; comp < numComp; ++comp) +- currDcComp[comp] = currDcComp[comp - 1] + numBlocksX * numBlocksY; ++ currDcComp[comp] = currDcComp[comp - 1] + (size_t) numBlocksX * numBlocksY; + + for (int blocky = 0; blocky < numBlocksY; ++blocky) + { +-- +2.53.0 + + +From 5240e8159a07033477b94c2ad359bb7e3f20ed2d Mon Sep 17 00:00:00 2001 +From: Cary Phillips +Date: Tue, 31 Mar 2026 07:49:09 -0700 +Subject: [PATCH 6/6] =?UTF-8?q?Fix=20misaligned=20memory=20access=20in=20`?= + =?UTF-8?q?LossyDctDecoder=5Fexecute`=20HALF=E2=86=92FLOAT=20expansion=20(?= + =?UTF-8?q?#2324)?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Fix misaligned memory access in `LossyDctDecoder_execute` HALF→FLOAT expansion + +After DCT decoding, `LossyDctDecoder_execute()` expands FLOAT-type channels +from their intermediate HALF (16-bit) XDR representation back to FLOAT (32-bit) +XDR in place. The expansion was done by casting `_rows[y]` (a `uint8_t *`) +directly to `float *` and `uint16_t *`, then reading and writing through those +typed pointers. + +Because row buffers are assigned by advancing a byte pointer with no alignment +padding (`outBufferEnd += chan->width * chan->bytes_per_element` in +`internal_dwa_compressor.h`), a FLOAT channel that follows a HALF channel of +odd width receives a `_rows[y]` pointer that is 2-byte aligned but not 4-byte +aligned. Dereferencing a `float *` cast from such a pointer is undefined +behavior under the C standard: + +- On ARM, RISC-V, and MIPS (strict alignment) this crashes immediately. +- On x86 it is silently tolerated at the hardware level but remains UB: + auto-vectorizing compilers (SSE/AVX) may assume aligned access and generate + incorrect code. +- UBSan reports: `store to misaligned address ... for type 'float', which + requires 4 byte alignment` at `internal_dwa_decoder.h:749`. + +Fix: replace the cast-and-dereference pattern with the `unaligned_load16` / +`memcpy` / `unaligned_store32` helpers already used throughout the rest of +OpenEXRCore (`internal_xdr.h`, `unpack.c`, `pack.c`, `internal_pxr24.c`). +These helpers use `memcpy` internally, which the C standard guarantees is safe +for unaligned addresses and which compilers compile to a single load/store +instruction on architectures that support it. + +The byte-order handling is preserved correctly: +- `unaligned_load16` reads 2 bytes via `memcpy` and applies `one_to_native16` + (XDR → native), returning a native-endian HALF value. +- `half_to_float` converts native HALF → native float. +- `memcpy(&bits, &f, 4)` reinterprets the float's bit pattern as `uint32_t` + without numeric conversion (the correct type-pun idiom in C). +- `unaligned_store32` applies `one_from_native32` (native → XDR) and writes + 4 bytes via `memcpy`, storing the result in XDR float format. + +Made-with: Cursor +Signed-off-by: Cary Phillips + +* add TODO comment + +Signed-off-by: Cary Phillips + +--------- + +Signed-off-by: Cary Phillips +--- + .../OpenEXR/OpenEXRCore/internal_dwa_decoder.h | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h +index e289b064d..046615ec5 100644 +--- a/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h ++++ b/pxr/imaging/hio/OpenEXR/OpenEXRCore/internal_dwa_decoder.h +@@ -651,13 +651,22 @@ LossyDctDecoder_execute ( + /* process in place in reverse to avoid temporary buffer */ + for (int y = 0; y < d->_height; ++y) + { +- float* floatXdrPtr = (float*) chanData[chan]->_rows[y]; +- uint16_t* halfXdr = (uint16_t*) floatXdrPtr; ++ uint8_t* rowBytes = chanData[chan]->_rows[y]; + + for (int x = d->_width - 1; x >= 0; --x) + { +- floatXdrPtr[x] = one_from_native_float ( +- half_to_float (one_to_native16 (halfXdr[x]))); ++ // TODO: make an unaligned_store32f that takes the float and ++ // packages up a one_from_native_float and calls memcpy ++ // instead of the two memcpy. We should look at the metrics ++ // for dwa and see if there's a performance difference to do ++ // so at some point. See: ++ // https://github.com/AcademySoftwareFoundation/openexr/pull/2324 ++ ++ uint16_t h = unaligned_load16 (rowBytes + x * sizeof (uint16_t)); ++ float f = half_to_float (h); ++ uint32_t bits; ++ memcpy (&bits, &f, sizeof (bits)); ++ unaligned_store32 (rowBytes + x * sizeof (float), bits); + } + } + } +-- +2.53.0 + diff --git a/usd.spec b/usd.spec index a66f331..c1e45f3 100644 --- a/usd.spec +++ b/usd.spec @@ -174,6 +174,16 @@ Patch: 0001-sdf-Guard-against-invalid-primChildren-in-crate-file.patch # https://github.com/PixarAnimationStudios/OpenUSD/pull/4028 # Cherry-picked on v25.08. Patch: 0001-Fix-B44-B44A-integer-overflow-use-uint64_t-for-row-o.patch +# Backport several OpenEXRCore security fixes +# https://github.com/PixarAnimationStudios/OpenUSD/pull/4030 +# Fixes: +# - CVE-2026-34378 / GHSA-v76p-4qvv-vh4g / RHBZ#2455493 +# - CVE-2026-34380 / GHSA-q3v8-hw4m-59w5 / RHBZ#2455534 +# - CVE-2026-34588 / GHSA-588r-cr5c-w6hf / RHBZ#2455505 +# - CVE-2026-34589 / GHSA-p8xc-w3q4-h64x / RHBZ#2455501 +# - CVE-2026-34379 / GHSA-w88v-vqhq-5p24 / RHBZ#2455497 +# Cherry-picked on v25.08. +Patch: usd-25.08-pr-4030.patch # Base BuildRequires: gcc-c++ From 0d40a09f4dbcac8545be2638a2453a98cf3ae954 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Wed, 24 Jun 2026 18:30:49 +0100 Subject: [PATCH 15/15] Rebuilt for materialx 1.39.5, which unexpectedly broke ABI - Fixes RHBZ#2492227