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