| 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 |