• 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_
7 
8 #include <stdint.h>
9 
10 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
11 #include "mojo/public/cpp/bindings/lib/serialization_util.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"
15 #include "mojo/public/cpp/bindings/message.h"
16 
17 namespace mojo {
18 namespace internal {
19 
20 // Checks whether decoding the pointer will overflow and produce a pointer
21 // smaller than |offset|.
22 bool ValidateEncodedPointer(const uint64_t* offset);
23 
24 template <typename T>
ValidatePointer(const Pointer<T> & input,ValidationContext * validation_context)25 bool ValidatePointer(const Pointer<T>& input,
26                      ValidationContext* validation_context) {
27   bool result = ValidateEncodedPointer(&input.offset);
28   if (!result)
29     ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_POINTER);
30 
31   return result;
32 }
33 
34 // Validates that |data| contains a valid struct header, in terms of alignment
35 // and size (i.e., the |num_bytes| field of the header is sufficient for storing
36 // the header itself). Besides, it checks that the memory range
37 // [data, data + num_bytes) is not marked as occupied by other objects in
38 // |validation_context|. On success, the memory range is marked as occupied.
39 // Note: Does not verify |version| or that |num_bytes| is correct for the
40 // claimed version.
41 bool ValidateStructHeaderAndClaimMemory(const void* data,
42                                         ValidationContext* validation_context);
43 
44 // Validates that |data| contains a valid union header, in terms of alignment
45 // and size. If not inlined, it checks that the memory range
46 // [data, data + num_bytes) is not marked as occupied by other objects in
47 // |validation_context|. On success, the memory range is marked as occupied.
48 bool ValidateUnionHeaderAndClaimMemory(const void* data,
49                                        bool inlined,
50                                        ValidationContext* validation_context);
51 
52 // Validates that the message is a request which doesn't expect a response.
53 bool ValidateMessageIsRequestWithoutResponse(
54     const Message* message,
55     ValidationContext* validation_context);
56 
57 // Validates that the message is a request expecting a response.
58 bool ValidateMessageIsRequestExpectingResponse(
59     const Message* message,
60     ValidationContext* validation_context);
61 
62 // Validates that the message is a response.
63 bool ValidateMessageIsResponse(const Message* message,
64                                ValidationContext* validation_context);
65 
66 // Validates that the message payload is a valid struct of type ParamsType.
67 template <typename ParamsType>
ValidateMessagePayload(const Message * message,ValidationContext * validation_context)68 bool ValidateMessagePayload(const Message* message,
69                             ValidationContext* validation_context) {
70   return ParamsType::Validate(message->payload(), validation_context);
71 }
72 
73 // The following methods validate control messages defined in
74 // interface_control_messages.mojom.
75 bool ValidateControlRequest(const Message* message,
76                             ValidationContext* validation_context);
77 bool ValidateControlResponse(const Message* message,
78                              ValidationContext* validation_context);
79 
80 // The following Validate.*NonNullable() functions validate that the given
81 // |input| is not null/invalid.
82 template <typename T>
ValidatePointerNonNullable(const T & input,const char * error_message,ValidationContext * validation_context)83 bool ValidatePointerNonNullable(const T& input,
84                                 const char* error_message,
85                                 ValidationContext* validation_context) {
86   if (input.offset)
87     return true;
88 
89   ReportValidationError(validation_context,
90                         VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
91                         error_message);
92   return false;
93 }
94 
95 template <typename T>
ValidateInlinedUnionNonNullable(const T & input,const char * error_message,ValidationContext * validation_context)96 bool ValidateInlinedUnionNonNullable(const T& input,
97                                      const char* error_message,
98                                      ValidationContext* validation_context) {
99   if (!input.is_null())
100     return true;
101 
102   ReportValidationError(validation_context,
103                         VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
104                         error_message);
105   return false;
106 }
107 
108 bool IsHandleOrInterfaceValid(const AssociatedInterface_Data& input);
109 bool IsHandleOrInterfaceValid(const AssociatedInterfaceRequest_Data& input);
110 bool IsHandleOrInterfaceValid(const Interface_Data& input);
111 bool IsHandleOrInterfaceValid(const Handle_Data& input);
112 
113 bool ValidateHandleOrInterfaceNonNullable(
114     const AssociatedInterface_Data& input,
115     const char* error_message,
116     ValidationContext* validation_context);
117 bool ValidateHandleOrInterfaceNonNullable(
118     const AssociatedInterfaceRequest_Data& input,
119     const char* error_message,
120     ValidationContext* validation_context);
121 bool ValidateHandleOrInterfaceNonNullable(
122     const Interface_Data& input,
123     const char* error_message,
124     ValidationContext* validation_context);
125 bool ValidateHandleOrInterfaceNonNullable(
126     const Handle_Data& input,
127     const char* error_message,
128     ValidationContext* validation_context);
129 
130 template <typename T>
ValidateContainer(const Pointer<T> & input,ValidationContext * validation_context,const ContainerValidateParams * validate_params)131 bool ValidateContainer(const Pointer<T>& input,
132                        ValidationContext* validation_context,
133                        const ContainerValidateParams* validate_params) {
134   return ValidatePointer(input, validation_context) &&
135          T::Validate(input.Get(), validation_context, validate_params);
136 }
137 
138 template <typename T>
ValidateStruct(const Pointer<T> & input,ValidationContext * validation_context)139 bool ValidateStruct(const Pointer<T>& input,
140                     ValidationContext* validation_context) {
141   return ValidatePointer(input, validation_context) &&
142          T::Validate(input.Get(), validation_context);
143 }
144 
145 template <typename T>
ValidateInlinedUnion(const T & input,ValidationContext * validation_context)146 bool ValidateInlinedUnion(const T& input,
147                           ValidationContext* validation_context) {
148   return T::Validate(&input, validation_context, true);
149 }
150 
151 template <typename T>
ValidateNonInlinedUnion(const Pointer<T> & input,ValidationContext * validation_context)152 bool ValidateNonInlinedUnion(const Pointer<T>& input,
153                              ValidationContext* validation_context) {
154   return ValidatePointer(input, validation_context) &&
155          T::Validate(input.Get(), validation_context, false);
156 }
157 
158 bool ValidateHandleOrInterface(const AssociatedInterface_Data& input,
159                                ValidationContext* validation_context);
160 bool ValidateHandleOrInterface(const AssociatedInterfaceRequest_Data& input,
161                                ValidationContext* validation_context);
162 bool ValidateHandleOrInterface(const Interface_Data& input,
163                                ValidationContext* validation_context);
164 bool ValidateHandleOrInterface(const Handle_Data& input,
165                                ValidationContext* validation_context);
166 
167 }  // namespace internal
168 }  // namespace mojo
169 
170 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_UTIL_H_
171