From c55f2924fe30e6f06c71c59143835baf4c154ac3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Egorov Date: Mon, 14 Nov 2022 15:42:52 +0000 Subject: [PATCH] [vm] Guard against bad brand strings in CPUID Brand string is supposed to be NULL-terminated. However we are seeing cases in the wild where this string is not null-terminated which causes buffer overrun when trying to print it. Add trailing '\0' to the brand string to guard against such cases. Fixes https://github.com/flutter/flutter/issues/114346 TEST=manually Change-Id: I21e545bd2fb52336a1fcd7edacb0b867740e8d61 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/269720 Reviewed-by: Martin Kustermann Commit-Queue: Slava Egorov --- runtime/vm/cpuid.cc | 21 +++++++++++---------- runtime/vm/cpuid.h | 2 -- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/runtime/vm/cpuid.cc b/runtime/vm/cpuid.cc index 0541712b5e6..7f71880c545 100644 --- a/runtime/vm/cpuid.cc +++ b/runtime/vm/cpuid.cc @@ -27,7 +27,7 @@ const char* CpuId::brand_string_ = nullptr; #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) -void CpuId::GetCpuId(int32_t level, uint32_t info[4]) { +static void GetCpuId(int32_t level, uint32_t info[4]) { #if defined(DART_HOST_OS_WINDOWS) // The documentation for __cpuid is at: // http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx @@ -57,15 +57,16 @@ void CpuId::Init() { GetCpuId(0x80000001, info); CpuId::abm_ = (info[2] & (1 << 5)) != 0; - char* brand_string = - reinterpret_cast(malloc(3 * 4 * sizeof(uint32_t))); - for (uint32_t i = 0x80000002; i <= 0x80000004; i++) { - uint32_t off = (i - 0x80000002U) * 4 * sizeof(uint32_t); - GetCpuId(i, info); - *reinterpret_cast(brand_string + off) = info[0]; - *reinterpret_cast(brand_string + off + 4) = info[1]; - *reinterpret_cast(brand_string + off + 8) = info[2]; - *reinterpret_cast(brand_string + off + 12) = info[3]; + // Brand string returned by CPUID is expected to be NULL-terminated, + // however we have seen cases in the wild which violate this assumption. + // To avoid going out of bounds when trying to print this string + // we add null-terminator ourselves, just in case. + // + // See https://github.com/flutter/flutter/issues/114346 + char* brand_string = reinterpret_cast(calloc(3 * sizeof(info) + 1, 1)); + for (uint32_t i = 0; i < 2; i++) { + GetCpuId(0x80000002U + i, info); + memmove(&brand_string[i * sizeof(info)], &info, sizeof(info)); } CpuId::brand_string_ = brand_string; } diff --git a/runtime/vm/cpuid.h b/runtime/vm/cpuid.h index abb4fdc0725..881dd6c97ae 100644 --- a/runtime/vm/cpuid.h +++ b/runtime/vm/cpuid.h @@ -42,8 +42,6 @@ class CpuId : public AllStatic { static bool abm_; static const char* id_string_; static const char* brand_string_; - - static void GetCpuId(int32_t level, uint32_t info[4]); }; } // namespace dart