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 3 // found in the LICENSE file. 4 5 #include "mojo/public/cpp/bindings/lib/validation_util.h" 6 7 #include <stdint.h> 8 9 #include <limits> 10 11 #include "mojo/public/cpp/bindings/lib/message_internal.h" 12 #include "mojo/public/cpp/bindings/lib/serialization_util.h" 13 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 14 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h" 15 16 namespace mojo { 17 namespace internal { 18 19 bool ValidateStructHeaderAndClaimMemory(const void* data, 20 ValidationContext* validation_context) { 21 if (!IsAligned(data)) { 22 ReportValidationError(validation_context, 23 VALIDATION_ERROR_MISALIGNED_OBJECT); 24 return false; 25 } 26 if (!validation_context->IsValidRange(data, sizeof(StructHeader))) { 27 ReportValidationError(validation_context, 28 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 29 return false; 30 } 31 32 const StructHeader* header = static_cast<const StructHeader*>(data); 33 34 if (header->num_bytes < sizeof(StructHeader)) { 35 ReportValidationError(validation_context, 36 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 37 return false; 38 } 39 40 if (!validation_context->ClaimMemory(data, header->num_bytes)) { 41 ReportValidationError(validation_context, 42 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 43 return false; 44 } 45 46 return true; 47 } 48 49 bool ValidateNonInlinedUnionHeaderAndClaimMemory( 50 const void* data, 51 ValidationContext* validation_context) { 52 if (!IsAligned(data)) { 53 ReportValidationError(validation_context, 54 VALIDATION_ERROR_MISALIGNED_OBJECT); 55 return false; 56 } 57 58 if (!validation_context->ClaimMemory(data, kUnionDataSize) || 59 *static_cast<const uint32_t*>(data) != kUnionDataSize) { 60 ReportValidationError(validation_context, 61 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 62 return false; 63 } 64 65 return true; 66 } 67 68 bool ValidateMessageIsRequestWithoutResponse( 69 const Message* message, 70 ValidationContext* validation_context) { 71 if (message->has_flag(Message::kFlagIsResponse) || 72 message->has_flag(Message::kFlagExpectsResponse)) { 73 ReportValidationError(validation_context, 74 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 75 return false; 76 } 77 return true; 78 } 79 80 bool ValidateMessageIsRequestExpectingResponse( 81 const Message* message, 82 ValidationContext* validation_context) { 83 if (message->has_flag(Message::kFlagIsResponse) || 84 !message->has_flag(Message::kFlagExpectsResponse)) { 85 ReportValidationError(validation_context, 86 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 87 return false; 88 } 89 return true; 90 } 91 92 bool ValidateMessageIsResponse(const Message* message, 93 ValidationContext* validation_context) { 94 if (message->has_flag(Message::kFlagExpectsResponse) || 95 !message->has_flag(Message::kFlagIsResponse)) { 96 ReportValidationError(validation_context, 97 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 98 return false; 99 } 100 return true; 101 } 102 103 bool IsHandleOrInterfaceValid(const AssociatedInterface_Data& input) { 104 return input.handle.is_valid(); 105 } 106 107 bool IsHandleOrInterfaceValid(const AssociatedEndpointHandle_Data& input) { 108 return input.is_valid(); 109 } 110 111 bool IsHandleOrInterfaceValid(const Interface_Data& input) { 112 return input.handle.is_valid(); 113 } 114 115 bool IsHandleOrInterfaceValid(const Handle_Data& input) { 116 return input.is_valid(); 117 } 118 119 bool ValidateHandleOrInterfaceNonNullable( 120 const AssociatedInterface_Data& input, 121 const char* error_message, 122 ValidationContext* validation_context) { 123 if (IsHandleOrInterfaceValid(input)) 124 return true; 125 126 ReportValidationError(validation_context, 127 VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID, 128 error_message); 129 return false; 130 } 131 132 bool ValidateHandleOrInterfaceNonNullable( 133 const AssociatedEndpointHandle_Data& input, 134 const char* error_message, 135 ValidationContext* validation_context) { 136 if (IsHandleOrInterfaceValid(input)) 137 return true; 138 139 ReportValidationError(validation_context, 140 VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID, 141 error_message); 142 return false; 143 } 144 145 bool ValidateHandleOrInterfaceNonNullable( 146 const Interface_Data& input, 147 const char* error_message, 148 ValidationContext* validation_context) { 149 if (IsHandleOrInterfaceValid(input)) 150 return true; 151 152 ReportValidationError(validation_context, 153 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 154 error_message); 155 return false; 156 } 157 158 bool ValidateHandleOrInterfaceNonNullable( 159 const Handle_Data& input, 160 const char* error_message, 161 ValidationContext* validation_context) { 162 if (IsHandleOrInterfaceValid(input)) 163 return true; 164 165 ReportValidationError(validation_context, 166 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 167 error_message); 168 return false; 169 } 170 171 bool ValidateHandleOrInterface(const AssociatedInterface_Data& input, 172 ValidationContext* validation_context) { 173 if (validation_context->ClaimAssociatedEndpointHandle(input.handle)) 174 return true; 175 176 ReportValidationError(validation_context, 177 VALIDATION_ERROR_ILLEGAL_INTERFACE_ID); 178 return false; 179 } 180 181 bool ValidateHandleOrInterface(const AssociatedEndpointHandle_Data& input, 182 ValidationContext* validation_context) { 183 if (validation_context->ClaimAssociatedEndpointHandle(input)) 184 return true; 185 186 ReportValidationError(validation_context, 187 VALIDATION_ERROR_ILLEGAL_INTERFACE_ID); 188 return false; 189 } 190 191 bool ValidateHandleOrInterface(const Interface_Data& input, 192 ValidationContext* validation_context) { 193 if (validation_context->ClaimHandle(input.handle)) 194 return true; 195 196 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE); 197 return false; 198 } 199 200 bool ValidateHandleOrInterface(const Handle_Data& input, 201 ValidationContext* validation_context) { 202 if (validation_context->ClaimHandle(input)) 203 return true; 204 205 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE); 206 return false; 207 } 208 209 } // namespace internal 210 } // namespace mojo 211