From 36ada6308df2bef1f1bb96f5b9b11f5ae8f9e961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 7 Oct 2021 21:08:46 +0200 Subject: [PATCH] Sanity check string lengths in save state code --- Common/Serialize/Serializer.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Common/Serialize/Serializer.cpp b/Common/Serialize/Serializer.cpp index 6000328a75..6b36fb2167 100644 --- a/Common/Serialize/Serializer.cpp +++ b/Common/Serialize/Serializer.cpp @@ -106,10 +106,19 @@ void PointerWrap::DoVoid(void *data, int size) { (*ptr) += size; } +// Not exactly sane but might catch some corrupt files. +const int MAX_SANE_STRING_LENGTH = 1024 * 1024; + void Do(PointerWrap &p, std::string &x) { int stringLen = (int)x.length() + 1; Do(p, stringLen); + if (stringLen < 0 || stringLen > MAX_SANE_STRING_LENGTH) { + WARN_LOG(SAVESTATE, "Savestate failure: bad stringLen %d", stringLen); + p.SetError(PointerWrap::ERROR_FAILURE); + return; + } + switch (p.mode) { case PointerWrap::MODE_READ: x = (char*)*p.ptr; break; case PointerWrap::MODE_WRITE: memcpy(*p.ptr, x.c_str(), stringLen); break; @@ -123,6 +132,12 @@ void Do(PointerWrap &p, std::wstring &x) { int stringLen = sizeof(wchar_t) * ((int)x.length() + 1); Do(p, stringLen); + if (stringLen < 0 || stringLen > MAX_SANE_STRING_LENGTH) { + WARN_LOG(SAVESTATE, "Savestate failure: bad stringLen %d", stringLen); + p.SetError(PointerWrap::ERROR_FAILURE); + return; + } + auto read = [&]() { std::wstring r; // In case unaligned, use memcpy. @@ -144,6 +159,12 @@ void Do(PointerWrap &p, std::u16string &x) { int stringLen = sizeof(char16_t) * ((int)x.length() + 1); Do(p, stringLen); + if (stringLen < 0 || stringLen > MAX_SANE_STRING_LENGTH) { + WARN_LOG(SAVESTATE, "Savestate failure: bad stringLen %d", stringLen); + p.SetError(PointerWrap::ERROR_FAILURE); + return; + } + auto read = [&]() { std::u16string r; // In case unaligned, use memcpy.