Chromium Code Reviews| Index: mojo/public/cpp/bindings/lib/bindings_serialization.cc |
| diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/mojo/public/cpp/bindings/lib/bindings_serialization.cc |
| index 5e60c65a5c4b52e8e89a46b36ab368958d2c6696..41b003cc7fc19dbe4276dd46bd159b39971304e2 100644 |
| --- a/mojo/public/cpp/bindings/lib/bindings_serialization.cc |
| +++ b/mojo/public/cpp/bindings/lib/bindings_serialization.cc |
| @@ -7,15 +7,17 @@ |
| #include <assert.h> |
| #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
| +#include "mojo/public/cpp/bindings/lib/bounds_checker.h" |
| namespace mojo { |
| namespace internal { |
| namespace { |
| +const size_t kAlignment = 8; |
| + |
| template<typename T> |
| T AlignImpl(T t) { |
| - const size_t kAlignment = 8; |
| return t + (kAlignment - (t % kAlignment)) % kAlignment; |
| } |
| @@ -29,6 +31,10 @@ char* AlignPointer(char* ptr) { |
| return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr))); |
| } |
| +bool IsAligned(const void* ptr) { |
| + return !(reinterpret_cast<uintptr_t>(ptr) % kAlignment); |
| +} |
| + |
| void EncodePointer(const void* ptr, uint64_t* offset) { |
| if (!ptr) { |
| *offset = 0; |
| @@ -48,6 +54,12 @@ const void* DecodePointerRaw(const uint64_t* offset) { |
| return reinterpret_cast<const char*>(offset) + *offset; |
| } |
| +bool ValidateEncodedPointer(const uint64_t* offset) { |
| + // Cast to uintptr_t so overflow behavior is well defined. |
| + return reinterpret_cast<uintptr_t>(offset) + *offset >= |
| + reinterpret_cast<uintptr_t>(offset); |
| +} |
| + |
| bool ValidatePointer(const void* ptr, const Message& message) { |
| const uint8_t* data = static_cast<const uint8_t*>(ptr); |
| if (reinterpret_cast<uintptr_t>(data) % 8 != 0) |
| @@ -82,5 +94,28 @@ bool DecodeHandle(Handle* handle, std::vector<Handle>* handles) { |
| return true; |
| } |
| +bool ValidateStructHeader(const void* data, |
| + uint32_t min_num_bytes, |
| + uint32_t min_num_fields, |
| + BoundsChecker* bounds_checker) { |
| + if (!IsAligned(data)) |
| + return false; |
| + if (!bounds_checker->IsWithinBounds(data, sizeof(StructHeader))) |
| + return false; |
| + |
| + const StructHeader* header = static_cast<const StructHeader*>(data); |
| + |
| + // Currently our binding code cannot handle structs of smaller size or with |
|
Tom Sepez
2014/05/22 19:39:21
nit: TODO()
yzshen1
2014/05/22 20:56:22
Done. Now it becomes my work item! :)
|
| + // fewer fields than the version that it sees. That needs to be changed in |
| + // order to provide backward compatibility. |
| + if (header->num_bytes < min_num_bytes || header->num_fields < min_num_fields) |
| + return false; |
| + |
| + if (!bounds_checker->ClaimMemory(data, header->num_bytes)) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| } // namespace internal |
| } // namespace mojo |