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
ValidateStructHeaderAndClaimMemory(const void * data,ValidationContext * validation_context)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
ValidateNonInlinedUnionHeaderAndClaimMemory(const void * data,ValidationContext * validation_context)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
ValidateMessageIsRequestWithoutResponse(const Message * message,ValidationContext * validation_context)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
ValidateMessageIsRequestExpectingResponse(const Message * message,ValidationContext * validation_context)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
ValidateMessageIsResponse(const Message * message,ValidationContext * validation_context)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
IsHandleOrInterfaceValid(const AssociatedInterface_Data & input)103 bool IsHandleOrInterfaceValid(const AssociatedInterface_Data& input) {
104 return input.handle.is_valid();
105 }
106
IsHandleOrInterfaceValid(const AssociatedEndpointHandle_Data & input)107 bool IsHandleOrInterfaceValid(const AssociatedEndpointHandle_Data& input) {
108 return input.is_valid();
109 }
110
IsHandleOrInterfaceValid(const Interface_Data & input)111 bool IsHandleOrInterfaceValid(const Interface_Data& input) {
112 return input.handle.is_valid();
113 }
114
IsHandleOrInterfaceValid(const Handle_Data & input)115 bool IsHandleOrInterfaceValid(const Handle_Data& input) {
116 return input.is_valid();
117 }
118
ValidateHandleOrInterfaceNonNullable(const AssociatedInterface_Data & input,const char * error_message,ValidationContext * validation_context)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
ValidateHandleOrInterfaceNonNullable(const AssociatedEndpointHandle_Data & input,const char * error_message,ValidationContext * validation_context)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
ValidateHandleOrInterfaceNonNullable(const Interface_Data & input,const char * error_message,ValidationContext * validation_context)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
ValidateHandleOrInterfaceNonNullable(const Handle_Data & input,const char * error_message,ValidationContext * validation_context)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
ValidateHandleOrInterface(const AssociatedInterface_Data & input,ValidationContext * validation_context)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
ValidateHandleOrInterface(const AssociatedEndpointHandle_Data & input,ValidationContext * validation_context)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
ValidateHandleOrInterface(const Interface_Data & input,ValidationContext * validation_context)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
ValidateHandleOrInterface(const Handle_Data & input,ValidationContext * validation_context)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