diff --git a/CHANGELOG.md b/CHANGELOG.md index 448f86bd4..c2eed49a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes and improvements +* Fix out-of-bounds reads in StorageView index validation (#2073) by [@jordimas](https://github.com/jordimas), reported by Nathan Keys (Halo Forge Labs) + ## [v4.8.1](https://github.com/OpenNMT/CTranslate2/releases/tag/v4.8.1) (2026-07-03) ### New features diff --git a/include/ctranslate2/storage_view.h b/include/ctranslate2/storage_view.h index 8834ef651..1d4ef27d5 100644 --- a/include/ctranslate2/storage_view.h +++ b/include/ctranslate2/storage_view.h @@ -19,7 +19,7 @@ namespace ctranslate2 { #define GUARD_DIM(DIM, RANK) \ do { \ - if (DIM >= RANK) \ + if (DIM < 0 || DIM >= RANK) \ THROW_INVALID_ARGUMENT("can't index dimension " \ + std::to_string(DIM) \ + " for a storage with rank " \ @@ -194,7 +194,7 @@ namespace ctranslate2 { template const T& at(dim_t index) const { - if (index >= _size) + if (index < 0 || index >= _size) THROW_INVALID_ARGUMENT("index is out of bounds (" + std::to_string(index) + " >= " + std::to_string(_size) + ")"); diff --git a/tests/storage_view_test.cc b/tests/storage_view_test.cc index bc6da8825..4c25f4bc6 100644 --- a/tests/storage_view_test.cc +++ b/tests/storage_view_test.cc @@ -17,6 +17,16 @@ TEST(StorageViewTest, ZeroDim) { EXPECT_EQ(b.dim(2), 2); } +TEST(StorageViewTest, InvalidNegativeDim) { + StorageView scalar(1.0f); + EXPECT_THROW(scalar.dim(-1), std::invalid_argument); +} + +TEST(StorageViewTest, InvalidNegativeIndex) { + StorageView storage({1}, std::vector{0}); + EXPECT_THROW(storage.at(-1), std::invalid_argument); +} + TEST(StorageViewTest, BoolOperator) { StorageView a; EXPECT_FALSE(bool(a));