OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ |
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" | 10 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
11 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" | |
12 #include "mojo/public/cpp/bindings/lib/serialization_util.h" | 11 #include "mojo/public/cpp/bindings/lib/serialization_util.h" |
13 #include "mojo/public/cpp/bindings/lib/validate_params.h" | 12 #include "mojo/public/cpp/bindings/lib/validate_params.h" |
| 13 #include "mojo/public/cpp/bindings/lib/validation_context.h" |
14 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | 14 #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
15 #include "mojo/public/cpp/bindings/message.h" | 15 #include "mojo/public/cpp/bindings/message.h" |
16 | 16 |
17 namespace mojo { | 17 namespace mojo { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 // Checks whether decoding the pointer will overflow and produce a pointer | 20 // Checks whether decoding the pointer will overflow and produce a pointer |
21 // smaller than |offset|. | 21 // smaller than |offset|. |
22 bool ValidateEncodedPointer(const uint64_t* offset); | 22 bool ValidateEncodedPointer(const uint64_t* offset); |
23 | 23 |
24 // Validates that |data| contains a valid struct header, in terms of alignment | 24 // Validates that |data| contains a valid struct header, in terms of alignment |
25 // and size (i.e., the |num_bytes| field of the header is sufficient for storing | 25 // and size (i.e., the |num_bytes| field of the header is sufficient for storing |
26 // the header itself). Besides, it checks that the memory range | 26 // the header itself). Besides, it checks that the memory range |
27 // [data, data + num_bytes) is not marked as occupied by other objects in | 27 // [data, data + num_bytes) is not marked as occupied by other objects in |
28 // |bounds_checker|. On success, the memory range is marked as occupied. | 28 // |validation_context|. On success, the memory range is marked as occupied. |
29 // Note: Does not verify |version| or that |num_bytes| is correct for the | 29 // Note: Does not verify |version| or that |num_bytes| is correct for the |
30 // claimed version. | 30 // claimed version. |
31 bool ValidateStructHeaderAndClaimMemory(const void* data, | 31 bool ValidateStructHeaderAndClaimMemory(const void* data, |
32 BoundsChecker* bounds_checker); | 32 ValidationContext* validation_context); |
33 | 33 |
34 // Validates that |data| contains a valid union header, in terms of alignment | 34 // Validates that |data| contains a valid union header, in terms of alignment |
35 // and size. If not inlined, it checks that the memory range | 35 // and size. If not inlined, it checks that the memory range |
36 // [data, data + num_bytes) is not marked as occupied by other objects in | 36 // [data, data + num_bytes) is not marked as occupied by other objects in |
37 // |bounds_checker|. On success, the memory range is marked as occupied. | 37 // |validation_context|. On success, the memory range is marked as occupied. |
38 bool ValidateUnionHeaderAndClaimMemory(const void* data, | 38 bool ValidateUnionHeaderAndClaimMemory(const void* data, |
39 bool inlined, | 39 bool inlined, |
40 BoundsChecker* bounds_checker); | 40 ValidationContext* validation_context); |
41 | 41 |
42 // Validates that the message is a request which doesn't expect a response. | 42 // Validates that the message is a request which doesn't expect a response. |
43 bool ValidateMessageIsRequestWithoutResponse(const Message* message); | 43 bool ValidateMessageIsRequestWithoutResponse( |
| 44 const Message* message, |
| 45 ValidationContext* validation_context); |
| 46 |
44 // Validates that the message is a request expecting a response. | 47 // Validates that the message is a request expecting a response. |
45 bool ValidateMessageIsRequestExpectingResponse(const Message* message); | 48 bool ValidateMessageIsRequestExpectingResponse( |
| 49 const Message* message, |
| 50 ValidationContext* validation_context); |
| 51 |
46 // Validates that the message is a response. | 52 // Validates that the message is a response. |
47 bool ValidateMessageIsResponse(const Message* message); | 53 bool ValidateMessageIsResponse(const Message* message, |
| 54 ValidationContext* validation_context); |
48 | 55 |
49 // Validates that the message payload is a valid struct of type ParamsType. | 56 // Validates that the message payload is a valid struct of type ParamsType. |
50 template <typename ParamsType> | 57 template <typename ParamsType> |
51 bool ValidateMessagePayload(const Message* message) { | 58 bool ValidateMessagePayload(const Message* message, |
52 BoundsChecker bounds_checker(message->payload(), message->payload_num_bytes(), | 59 ValidationContext* validation_context) { |
53 message->handles()->size()); | 60 return ParamsType::Validate(message->payload(), validation_context); |
54 return ParamsType::Validate(message->payload(), &bounds_checker); | |
55 } | 61 } |
56 | 62 |
57 // The following methods validate control messages defined in | 63 // The following methods validate control messages defined in |
58 // interface_control_messages.mojom. | 64 // interface_control_messages.mojom. |
59 bool ValidateControlRequest(const Message* message); | 65 bool ValidateControlRequest(const Message* message, |
60 bool ValidateControlResponse(const Message* message); | 66 ValidationContext* validation_context); |
| 67 bool ValidateControlResponse(const Message* message, |
| 68 ValidationContext* validation_context); |
61 | 69 |
62 // The following Validate.*NonNullable() functions validate that the given | 70 // The following Validate.*NonNullable() functions validate that the given |
63 // |input| is not null/invalid. | 71 // |input| is not null/invalid. |
64 template <typename T> | 72 template <typename T> |
65 bool ValidatePointerNonNullable(const T& input, const char* error_message) { | 73 bool ValidatePointerNonNullable(const T& input, |
| 74 const char* error_message, |
| 75 ValidationContext* validation_context) { |
66 if (input.offset) | 76 if (input.offset) |
67 return true; | 77 return true; |
68 | 78 |
69 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 79 ReportValidationError(validation_context, |
| 80 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
70 error_message); | 81 error_message); |
71 return false; | 82 return false; |
72 } | 83 } |
73 | 84 |
74 template <typename T> | 85 template <typename T> |
75 bool ValidateInlinedUnionNonNullable(const T& input, | 86 bool ValidateInlinedUnionNonNullable(const T& input, |
76 const char* error_message) { | 87 const char* error_message, |
| 88 ValidationContext* validation_context) { |
77 if (!input.is_null()) | 89 if (!input.is_null()) |
78 return true; | 90 return true; |
79 | 91 |
80 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, | 92 ReportValidationError(validation_context, |
| 93 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
81 error_message); | 94 error_message); |
82 return false; | 95 return false; |
83 } | 96 } |
84 | 97 |
85 bool ValidateHandleNonNullable(const Handle_Data& input, | 98 bool ValidateHandleNonNullable(const Handle_Data& input, |
86 const char* error_message); | 99 const char* error_message, |
| 100 ValidationContext* validation_context); |
87 | 101 |
88 bool ValidateInterfaceIdNonNullable(InterfaceId input, | 102 bool ValidateInterfaceIdNonNullable(InterfaceId input, |
89 const char* error_message); | 103 const char* error_message, |
| 104 ValidationContext* validation_context); |
90 | 105 |
91 template <typename T> | 106 template <typename T> |
92 bool ValidateArray(const Pointer<Array_Data<T>>& input, | 107 bool ValidateArray(const Pointer<Array_Data<T>>& input, |
93 BoundsChecker* bounds_checker, | 108 ValidationContext* validation_context, |
94 const ContainerValidateParams* validate_params) { | 109 const ContainerValidateParams* validate_params) { |
95 if (!ValidateEncodedPointer(&input.offset)) { | 110 if (!ValidateEncodedPointer(&input.offset)) { |
96 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER); | 111 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_POINTER); |
97 return false; | 112 return false; |
98 } | 113 } |
99 | 114 |
100 return Array_Data<T>::Validate(DecodePointerRaw(&input.offset), | 115 return Array_Data<T>::Validate(DecodePointerRaw(&input.offset), |
101 bounds_checker, validate_params); | 116 validation_context, validate_params); |
102 } | 117 } |
103 | 118 |
104 template <typename T> | 119 template <typename T> |
105 bool ValidateMap(const Pointer<T>& input, | 120 bool ValidateMap(const Pointer<T>& input, |
106 BoundsChecker* bounds_checker, | 121 ValidationContext* validation_context, |
107 const ContainerValidateParams* validate_params) { | 122 const ContainerValidateParams* validate_params) { |
108 if (!ValidateEncodedPointer(&input.offset)) { | 123 if (!ValidateEncodedPointer(&input.offset)) { |
109 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER); | 124 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_POINTER); |
110 return false; | 125 return false; |
111 } | 126 } |
112 | 127 |
113 return T::Validate(DecodePointerRaw(&input.offset), bounds_checker, | 128 return T::Validate(DecodePointerRaw(&input.offset), validation_context, |
114 validate_params); | 129 validate_params); |
115 } | 130 } |
116 | 131 |
117 template <typename T> | 132 template <typename T> |
118 bool ValidateStruct(const Pointer<T>& input, BoundsChecker* bounds_checker) { | 133 bool ValidateStruct(const Pointer<T>& input, |
| 134 ValidationContext* validation_context) { |
119 if (!ValidateEncodedPointer(&input.offset)) { | 135 if (!ValidateEncodedPointer(&input.offset)) { |
120 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER); | 136 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_POINTER); |
121 return false; | 137 return false; |
122 } | 138 } |
123 | 139 |
124 return T::Validate(DecodePointerRaw(&input.offset), bounds_checker); | 140 return T::Validate(DecodePointerRaw(&input.offset), validation_context); |
125 } | 141 } |
126 | 142 |
127 template <typename T> | 143 template <typename T> |
128 bool ValidateInlinedUnion(const T& input, BoundsChecker* bounds_checker) { | 144 bool ValidateInlinedUnion(const T& input, |
129 return T::Validate(&input, bounds_checker, true); | 145 ValidationContext* validation_context) { |
| 146 return T::Validate(&input, validation_context, true); |
130 } | 147 } |
131 | 148 |
132 template <typename T> | 149 template <typename T> |
133 bool ValidateNonInlinedUnion(const Pointer<T>& input, | 150 bool ValidateNonInlinedUnion(const Pointer<T>& input, |
134 BoundsChecker* bounds_checker) { | 151 ValidationContext* validation_context) { |
135 if (!ValidateEncodedPointer(&input.offset)) { | 152 if (!ValidateEncodedPointer(&input.offset)) { |
136 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER); | 153 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_POINTER); |
137 return false; | 154 return false; |
138 } | 155 } |
139 | 156 |
140 return T::Validate(DecodePointerRaw(&input.offset), bounds_checker, false); | 157 return T::Validate(DecodePointerRaw(&input.offset), validation_context, |
| 158 false); |
141 } | 159 } |
142 | 160 |
143 bool ValidateHandle(const Handle_Data& input, BoundsChecker* bounds_checker); | 161 bool ValidateHandle(const Handle_Data& input, |
| 162 ValidationContext* validation_context); |
144 | 163 |
145 bool ValidateAssociatedInterfaceId(InterfaceId input); | 164 bool ValidateAssociatedInterfaceId(InterfaceId input, |
| 165 ValidationContext* validation_context); |
146 | 166 |
147 } // namespace internal | 167 } // namespace internal |
148 } // namespace mojo | 168 } // namespace mojo |
149 | 169 |
150 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ | 170 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_ |
OLD | NEW |