• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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