Skip to content

Commit 275c2d4

Browse files
acts-1631elad335
authored andcommitted
Reject overflowing savestate collection counts
1 parent 4cb260c commit 275c2d4

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

rpcs3/util/serialization.hpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ namespace utils
209209
template <typename T> requires Integral<T>
210210
bool deserialize_vle(T& value)
211211
{
212+
using unsigned_type = std::make_unsigned_t<T>;
213+
unsigned_type result{};
214+
constexpr u32 bit_width = sizeof(T) * 8;
212215
value = {};
213216

214217
for (u32 i = 0;; i += 7)
@@ -220,12 +223,25 @@ namespace utils
220223
return false;
221224
}
222225

223-
value |= static_cast<T>(byte_data % 0x80) << i;
226+
const unsigned_type payload = static_cast<unsigned_type>(byte_data % 0x80);
227+
228+
if (i >= bit_width || payload > (~unsigned_type{} >> i))
229+
{
230+
return false;
231+
}
232+
233+
result |= payload << i;
224234

225235
if (!(byte_data & 0x80))
226236
{
237+
value = static_cast<T>(result);
227238
break;
228239
}
240+
241+
if (i > bit_width - 7)
242+
{
243+
return false;
244+
}
229245
}
230246

231247
return true;
@@ -297,7 +313,14 @@ namespace utils
297313

298314
if constexpr (Bitcopy<typename T::value_type>)
299315
{
300-
if (!raw_serialize([&](){ obj.resize(size); return obj.data(); }, sizeof(obj[0]) * size))
316+
if (size > static_cast<usz>(umax) / sizeof(obj[0]))
317+
{
318+
return false;
319+
}
320+
321+
const usz data_size = sizeof(obj[0]) * size;
322+
323+
if (!raw_serialize([&](){ obj.resize(size); return obj.data(); }, data_size))
301324
{
302325
obj.clear();
303326
return false;

0 commit comments

Comments
 (0)