Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: mojo/public/cpp/bindings/lib/bindings_serialization.cc

Issue 289333002: Mojo cpp bindings: validation logic for incoming messages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" 5 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
6 6
7 #include <assert.h> 7 #include <assert.h>
8 8
9 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" 9 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
10 #include "mojo/public/cpp/bindings/lib/bounds_checker.h"
10 11
11 namespace mojo { 12 namespace mojo {
12 namespace internal { 13 namespace internal {
13 14
14 namespace { 15 namespace {
15 16
17 const size_t kAlignment = 8;
18
16 template<typename T> 19 template<typename T>
17 T AlignImpl(T t) { 20 T AlignImpl(T t) {
18 const size_t kAlignment = 8;
19 return t + (kAlignment - (t % kAlignment)) % kAlignment; 21 return t + (kAlignment - (t % kAlignment)) % kAlignment;
20 } 22 }
21 23
22 } // namespace 24 } // namespace
23 25
24 size_t Align(size_t size) { 26 size_t Align(size_t size) {
25 return AlignImpl(size); 27 return AlignImpl(size);
26 } 28 }
27 29
28 char* AlignPointer(char* ptr) { 30 char* AlignPointer(char* ptr) {
29 return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr))); 31 return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr)));
30 } 32 }
31 33
34 bool IsAligned(const void* ptr) {
35 return !(reinterpret_cast<uintptr_t>(ptr) % kAlignment);
36 }
37
32 void EncodePointer(const void* ptr, uint64_t* offset) { 38 void EncodePointer(const void* ptr, uint64_t* offset) {
33 if (!ptr) { 39 if (!ptr) {
34 *offset = 0; 40 *offset = 0;
35 return; 41 return;
36 } 42 }
37 43
38 const char* p_obj = reinterpret_cast<const char*>(ptr); 44 const char* p_obj = reinterpret_cast<const char*>(ptr);
39 const char* p_slot = reinterpret_cast<const char*>(offset); 45 const char* p_slot = reinterpret_cast<const char*>(offset);
40 assert(p_obj > p_slot); 46 assert(p_obj > p_slot);
41 47
42 *offset = static_cast<uint64_t>(p_obj - p_slot); 48 *offset = static_cast<uint64_t>(p_obj - p_slot);
43 } 49 }
44 50
45 const void* DecodePointerRaw(const uint64_t* offset) { 51 const void* DecodePointerRaw(const uint64_t* offset) {
46 if (!*offset) 52 if (!*offset)
47 return NULL; 53 return NULL;
48 return reinterpret_cast<const char*>(offset) + *offset; 54 return reinterpret_cast<const char*>(offset) + *offset;
49 } 55 }
50 56
57 bool ValidateEncodedPointer(const uint64_t* offset) {
58 // Cast to uintptr_t so overflow behavior is well defined.
59 return reinterpret_cast<uintptr_t>(offset) + *offset >=
60 reinterpret_cast<uintptr_t>(offset);
61 }
62
51 bool ValidatePointer(const void* ptr, const Message& message) { 63 bool ValidatePointer(const void* ptr, const Message& message) {
52 const uint8_t* data = static_cast<const uint8_t*>(ptr); 64 const uint8_t* data = static_cast<const uint8_t*>(ptr);
53 if (reinterpret_cast<uintptr_t>(data) % 8 != 0) 65 if (reinterpret_cast<uintptr_t>(data) % 8 != 0)
54 return false; 66 return false;
55 67
56 const uint8_t* data_start = message.data(); 68 const uint8_t* data_start = message.data();
57 const uint8_t* data_end = data_start + message.data_num_bytes(); 69 const uint8_t* data_end = data_start + message.data_num_bytes();
58 70
59 return data >= data_start && data < data_end; 71 return data >= data_start && data < data_end;
60 } 72 }
61 73
62 void EncodeHandle(Handle* handle, std::vector<Handle>* handles) { 74 void EncodeHandle(Handle* handle, std::vector<Handle>* handles) {
63 if (handle->is_valid()) { 75 if (handle->is_valid()) {
64 handles->push_back(*handle); 76 handles->push_back(*handle);
65 handle->set_value(static_cast<MojoHandle>(handles->size() - 1)); 77 handle->set_value(static_cast<MojoHandle>(handles->size() - 1));
66 } else { 78 } else {
67 // Encode -1 to mean the invalid handle. 79 handle->set_value(kEncodedInvalidHandleValue);
68 handle->set_value(static_cast<MojoHandle>(-1));
69 } 80 }
70 } 81 }
71 82
72 bool DecodeHandle(Handle* handle, std::vector<Handle>* handles) { 83 bool DecodeHandle(Handle* handle, std::vector<Handle>* handles) {
73 // Decode -1 to mean the invalid handle. 84 if (handle->value() == kEncodedInvalidHandleValue) {
74 if (handle->value() == static_cast<MojoHandle>(-1)) {
75 *handle = Handle(); 85 *handle = Handle();
76 return true; 86 return true;
77 } 87 }
78 if (handle->value() >= handles->size()) 88 if (handle->value() >= handles->size())
79 return false; 89 return false;
80 // Just leave holes in the vector so we don't screw up other indices. 90 // Just leave holes in the vector so we don't screw up other indices.
81 *handle = FetchAndReset(&handles->at(handle->value())); 91 *handle = FetchAndReset(&handles->at(handle->value()));
82 return true; 92 return true;
83 } 93 }
84 94
95 bool ValidateStructHeader(const void* data,
96 uint32_t min_num_bytes,
97 uint32_t min_num_fields,
98 BoundsChecker* bounds_checker) {
99 if (!IsAligned(data))
100 return false;
101 if (!bounds_checker->IsValidRange(data, sizeof(StructHeader)))
102 return false;
103
104 const StructHeader* header = static_cast<const StructHeader*>(data);
105
106 // TODO(yzshen): Currently our binding code cannot handle structs of smaller
107 // size or with fewer fields than the version that it sees. That needs to be
108 // changed in order to provide backward compatibility.
109 if (header->num_bytes < min_num_bytes || header->num_fields < min_num_fields)
110 return false;
111
112 if (!bounds_checker->ClaimMemory(data, header->num_bytes))
113 return false;
114
115 return true;
116 }
117
85 } // namespace internal 118 } // namespace internal
86 } // namespace mojo 119 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/bindings_serialization.h ('k') | mojo/public/cpp/bindings/lib/bounds_checker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698