Commit ae582206 authored by Antoine Labour's avatar Antoine Labour Committed by Commit Bot

Harden gpu::SizedResult against overflow

Use CheckedNumerics to prevent silent uint32_t overflow.

Bug: 905336, 905459
Change-Id: Ie518def9063143ef2393be566419a209f68f0dce
Reviewed-on: https://chromium-review.googlesource.com/c/1336083Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Reviewed-by: default avatarAbhishek Arya <inferno@chromium.org>
Commit-Queue: Antoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608184}
parent f92523f1
......@@ -12,6 +12,7 @@
#include <string.h>
#include "base/atomicops.h"
#include "base/numerics/checked_math.h"
#include "gpu/command_buffer/common/cmd_buffer_common.h"
namespace gpu {
......@@ -33,25 +34,38 @@ struct SizedResult {
// Returns the total size in bytes of the SizedResult for a given number of
// results including the size field.
static size_t ComputeSize(size_t num_results) {
return sizeof(T) * num_results + sizeof(uint32_t); // NOLINT
static uint32_t ComputeSize(base::CheckedNumeric<uint32_t> num_results) {
base::CheckedNumeric<uint32_t> size = num_results;
size *= sizeof(T);
size += sizeof(uint32_t);
return size.ValueOrDie();
}
// Returns the maximum number of results for a given buffer size.
static uint32_t ComputeMaxResults(size_t size_of_buffer) {
return (size_of_buffer >= sizeof(uint32_t))
? ((size_of_buffer - sizeof(uint32_t)) / sizeof(T))
: 0; // NOLINT
base::CheckedNumeric<uint32_t> max_results = 0;
if (size_of_buffer >= sizeof(uint32_t)) {
max_results = size_of_buffer;
max_results -= sizeof(uint32_t);
max_results /= sizeof(T);
}
return max_results.ValueOrDefault(0);
}
// Set the size for a given number of results.
void SetNumResults(size_t num_results) {
size = sizeof(T) * num_results; // NOLINT
void SetNumResults(base::CheckedNumeric<uint32_t> num_results) {
base::CheckedNumeric<uint32_t> bytes = num_results;
bytes *= sizeof(T);
size = bytes.ValueOrDie();
}
// Get the number of elements in the result
int32_t GetNumResults() const {
return size / sizeof(T); // NOLINT
// TODO(piman): return uint32_t here to remove the need for checked
// numerics.
base::CheckedNumeric<uint32_t> num_results = size;
num_results /= sizeof(T);
return num_results.ValueOrDie<int32_t>();
}
// Copy the result.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment