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 |