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

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: Created 6 years, 7 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 }
(...skipping 14 matching lines...) Expand all
75 *handle = Handle(); 87 *handle = Handle();
76 return true; 88 return true;
77 } 89 }
78 if (handle->value() >= handles->size()) 90 if (handle->value() >= handles->size())
79 return false; 91 return false;
80 // Just leave holes in the vector so we don't screw up other indices. 92 // Just leave holes in the vector so we don't screw up other indices.
81 *handle = FetchAndReset(&handles->at(handle->value())); 93 *handle = FetchAndReset(&handles->at(handle->value()));
82 return true; 94 return true;
83 } 95 }
84 96
97 bool ValidateStructHeader(const void* data,
98 uint32_t min_num_bytes,
99 uint32_t min_num_fields,
100 BoundsChecker* bounds_checker) {
101 if (!IsAligned(data))
102 return false;
103 if (!bounds_checker->IsWithinBounds(data, sizeof(StructHeader)))
104 return false;
105
106 const StructHeader* header = static_cast<const StructHeader*>(data);
107
108 // 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! :)
109 // fewer fields than the version that it sees. That needs to be changed in
110 // order to provide backward compatibility.
111 if (header->num_bytes < min_num_bytes || header->num_fields < min_num_fields)
112 return false;
113
114 if (!bounds_checker->ClaimMemory(data, header->num_bytes))
115 return false;
116
117 return true;
118 }
119
85 } // namespace internal 120 } // namespace internal
86 } // namespace mojo 121 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698