WireCmd: guard against overflows when computing array sizes
BUG=chromium:918094
BUG=chromium:918348
BUG=chromium:918260
Change-Id: Ia2ee8930592e436e8d0d76837b70e726e8d87ea7
Reviewed-on: https://dawn-review.googlesource.com/c/3620
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/generator/templates/dawn_wire/WireCmd.cpp b/generator/templates/dawn_wire/WireCmd.cpp
index 2464bf0..8bb4235 100644
--- a/generator/templates/dawn_wire/WireCmd.cpp
+++ b/generator/templates/dawn_wire/WireCmd.cpp
@@ -17,6 +17,7 @@
#include "common/Assert.h"
#include <cstring>
+#include <limits>
//* Helper macros so that the main [de]serialization functions can be written in a generic manner.
@@ -288,7 +289,11 @@
// Returns FatalError if not enough memory was available
template <typename T>
DeserializeResult GetPtrFromBuffer(const char** buffer, size_t* size, size_t count, const T** data) {
- // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+ constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+ if (count > kMaxCountWithoutOverflows) {
+ return DeserializeResult::FatalError;
+ }
+
size_t totalSize = sizeof(T) * count;
if (totalSize > *size) {
return DeserializeResult::FatalError;
@@ -305,7 +310,11 @@
// Return FatalError if the allocator couldn't allocate the memory.
template <typename T>
DeserializeResult GetSpace(DeserializeAllocator* allocator, size_t count, T** out) {
- // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+ constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+ if (count > kMaxCountWithoutOverflows) {
+ return DeserializeResult::FatalError;
+ }
+
size_t totalSize = sizeof(T) * count;
*out = static_cast<T*>(allocator->GetSpace(totalSize));
if (*out == nullptr) {