From b17458c67ab916d5aa4fbe6ce27de7fb1d51f45f Mon Sep 17 00:00:00 2001 From: Acts1631 Date: Wed, 2 Sep 2026 14:26:18 -0400 Subject: [PATCH] Reject overflowing savestate collection counts --- rpcs3/util/serialization.hpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/rpcs3/util/serialization.hpp b/rpcs3/util/serialization.hpp index 49ee3d885867..a6e38edab338 100644 --- a/rpcs3/util/serialization.hpp +++ b/rpcs3/util/serialization.hpp @@ -209,6 +209,9 @@ namespace utils template requires Integral bool deserialize_vle(T& value) { + using unsigned_type = std::make_unsigned_t; + unsigned_type result{}; + constexpr u32 bit_width = sizeof(T) * 8; value = {}; for (u32 i = 0;; i += 7) @@ -220,12 +223,25 @@ namespace utils return false; } - value |= static_cast(byte_data % 0x80) << i; + const unsigned_type payload = static_cast(byte_data % 0x80); + + if (i >= bit_width || payload > (~unsigned_type{} >> i)) + { + return false; + } + + result |= payload << i; if (!(byte_data & 0x80)) { + value = static_cast(result); break; } + + if (i > bit_width - 7) + { + return false; + } } return true; @@ -297,7 +313,14 @@ namespace utils if constexpr (Bitcopy) { - if (!raw_serialize([&](){ obj.resize(size); return obj.data(); }, sizeof(obj[0]) * size)) + if (size > static_cast(umax) / sizeof(obj[0])) + { + return false; + } + + const usz data_size = sizeof(obj[0]) * size; + + if (!raw_serialize([&](){ obj.resize(size); return obj.data(); }, data_size)) { obj.clear(); return false;