Avoid integer overflow & stack buffer overrun in ConvertStringArg (called from StrFormat()) The FixedArray size allocated is a multiple of the given buffer size, but this multiplication is not checked. It can potentially overflow and result in a small size that gets placed on the stack, thus resulting in a stack buffer overrun. PiperOrigin-RevId: 944737638 Change-Id: Ib98028f3546c10b00447cd8f253a85786b647249
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index a51f7d7..fae98f4 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc
@@ -25,6 +25,7 @@ #include <cstdlib> #include <cstring> #include <cwchar> +#include <limits> #include <string> #include <string_view> #include <type_traits> @@ -313,7 +314,14 @@ size_t len, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { - FixedArray<char> mb(len * 4); + // Each wide character may result in up to 4 bytes (UTF-8 code units). + constexpr size_t kMaxUtf8CodeUnitsPerWideChar = 4; + if (len > (std::numeric_limits<decltype(len)>::max)() / + kMaxUtf8CodeUnitsPerWideChar) { + // Size too large; we can't handle this. + return false; + } + FixedArray<char> mb(len * kMaxUtf8CodeUnitsPerWideChar); strings_internal::ShiftState s; size_t chars_written = 0; for (size_t i = 0; i < len; ++i) {