Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(358)

Side by Side Diff: mojo/public/cpp/bindings/lib/validation_util.cc

Issue 2064903002: Mojo: Report bindings validation errors via MojoNotifyBadMessage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/cpp/bindings/lib/validation_util.h ('k') | mojo/public/cpp/bindings/message.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/public/cpp/bindings/lib/validation_util.h" 5 #include "mojo/public/cpp/bindings/lib/validation_util.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
11 #include "mojo/public/cpp/bindings/lib/message_internal.h" 11 #include "mojo/public/cpp/bindings/lib/message_internal.h"
12 #include "mojo/public/cpp/bindings/lib/serialization_util.h" 12 #include "mojo/public/cpp/bindings/lib/serialization_util.h"
13 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 13 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
14 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h" 14 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
15 15
16 namespace mojo { 16 namespace mojo {
17 namespace internal { 17 namespace internal {
18 18
19 bool ValidateEncodedPointer(const uint64_t* offset) { 19 bool ValidateEncodedPointer(const uint64_t* offset) {
20 // - Make sure |*offset| is no more than 32-bits. 20 // - Make sure |*offset| is no more than 32-bits.
21 // - Cast |offset| to uintptr_t so overflow behavior is well defined across 21 // - Cast |offset| to uintptr_t so overflow behavior is well defined across
22 // 32-bit and 64-bit systems. 22 // 32-bit and 64-bit systems.
23 return *offset <= std::numeric_limits<uint32_t>::max() && 23 return *offset <= std::numeric_limits<uint32_t>::max() &&
24 (reinterpret_cast<uintptr_t>(offset) + 24 (reinterpret_cast<uintptr_t>(offset) +
25 static_cast<uint32_t>(*offset) >= 25 static_cast<uint32_t>(*offset) >=
26 reinterpret_cast<uintptr_t>(offset)); 26 reinterpret_cast<uintptr_t>(offset));
27 } 27 }
28 28
29 bool ValidateStructHeaderAndClaimMemory(const void* data, 29 bool ValidateStructHeaderAndClaimMemory(const void* data,
30 BoundsChecker* bounds_checker) { 30 ValidationContext* validation_context) {
31 if (!IsAligned(data)) { 31 if (!IsAligned(data)) {
32 ReportValidationError(VALIDATION_ERROR_MISALIGNED_OBJECT); 32 ReportValidationError(validation_context,
33 VALIDATION_ERROR_MISALIGNED_OBJECT);
33 return false; 34 return false;
34 } 35 }
35 if (!bounds_checker->IsValidRange(data, sizeof(StructHeader))) { 36 if (!validation_context->IsValidRange(data, sizeof(StructHeader))) {
36 ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 37 ReportValidationError(validation_context,
38 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
37 return false; 39 return false;
38 } 40 }
39 41
40 const StructHeader* header = static_cast<const StructHeader*>(data); 42 const StructHeader* header = static_cast<const StructHeader*>(data);
41 43
42 if (header->num_bytes < sizeof(StructHeader)) { 44 if (header->num_bytes < sizeof(StructHeader)) {
43 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 45 ReportValidationError(validation_context,
46 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
44 return false; 47 return false;
45 } 48 }
46 49
47 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) { 50 if (!validation_context->ClaimMemory(data, header->num_bytes)) {
48 ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 51 ReportValidationError(validation_context,
52 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
49 return false; 53 return false;
50 } 54 }
51 55
52 return true; 56 return true;
53 } 57 }
54 58
55 bool ValidateUnionHeaderAndClaimMemory(const void* data, 59 bool ValidateUnionHeaderAndClaimMemory(const void* data,
56 bool inlined, 60 bool inlined,
57 BoundsChecker* bounds_checker) { 61 ValidationContext* validation_context) {
58 if (!IsAligned(data)) { 62 if (!IsAligned(data)) {
59 ReportValidationError(VALIDATION_ERROR_MISALIGNED_OBJECT); 63 ReportValidationError(validation_context,
64 VALIDATION_ERROR_MISALIGNED_OBJECT);
60 return false; 65 return false;
61 } 66 }
62 67
63 // If the union is inlined in another structure its memory was already 68 // If the union is inlined in another structure its memory was already
64 // claimed. 69 // claimed.
65 // This ONLY applies to the union itself, NOT anything which the union points 70 // This ONLY applies to the union itself, NOT anything which the union points
66 // to. 71 // to.
67 if (!inlined && !bounds_checker->ClaimMemory(data, kUnionDataSize)) { 72 if (!inlined && !validation_context->ClaimMemory(data, kUnionDataSize)) {
68 ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 73 ReportValidationError(validation_context,
74 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
69 return false; 75 return false;
70 } 76 }
71 77
72 return true; 78 return true;
73 } 79 }
74 80
75 bool ValidateMessageIsRequestWithoutResponse(const Message* message) { 81 bool ValidateMessageIsRequestWithoutResponse(
82 const Message* message,
83 ValidationContext* validation_context) {
76 if (message->has_flag(kMessageIsResponse) || 84 if (message->has_flag(kMessageIsResponse) ||
77 message->has_flag(kMessageExpectsResponse)) { 85 message->has_flag(kMessageExpectsResponse)) {
78 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 86 ReportValidationError(validation_context,
87 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
79 return false; 88 return false;
80 } 89 }
81 return true; 90 return true;
82 } 91 }
83 92
84 bool ValidateMessageIsRequestExpectingResponse(const Message* message) { 93 bool ValidateMessageIsRequestExpectingResponse(
94 const Message* message,
95 ValidationContext* validation_context) {
85 if (message->has_flag(kMessageIsResponse) || 96 if (message->has_flag(kMessageIsResponse) ||
86 !message->has_flag(kMessageExpectsResponse)) { 97 !message->has_flag(kMessageExpectsResponse)) {
87 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 98 ReportValidationError(validation_context,
99 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
88 return false; 100 return false;
89 } 101 }
90 return true; 102 return true;
91 } 103 }
92 104
93 bool ValidateMessageIsResponse(const Message* message) { 105 bool ValidateMessageIsResponse(const Message* message,
106 ValidationContext* validation_context) {
94 if (message->has_flag(kMessageExpectsResponse) || 107 if (message->has_flag(kMessageExpectsResponse) ||
95 !message->has_flag(kMessageIsResponse)) { 108 !message->has_flag(kMessageIsResponse)) {
96 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 109 ReportValidationError(validation_context,
110 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
97 return false; 111 return false;
98 } 112 }
99 return true; 113 return true;
100 } 114 }
101 115
102 bool ValidateControlRequest(const Message* message) { 116 bool ValidateControlRequest(const Message* message,
117 ValidationContext* validation_context) {
103 switch (message->header()->name) { 118 switch (message->header()->name) {
104 case kRunMessageId: 119 case kRunMessageId:
105 return ValidateMessageIsRequestExpectingResponse(message) && 120 return ValidateMessageIsRequestExpectingResponse(message,
106 ValidateMessagePayload<RunMessageParams_Data>(message); 121 validation_context) &&
122 ValidateMessagePayload<RunMessageParams_Data>(message,
123 validation_context);
107 case kRunOrClosePipeMessageId: 124 case kRunOrClosePipeMessageId:
108 return ValidateMessageIsRequestWithoutResponse(message) && 125 return ValidateMessageIsRequestWithoutResponse(message,
109 ValidateMessagePayload<RunOrClosePipeMessageParams_Data>(message); 126 validation_context) &&
127 ValidateMessagePayload<RunOrClosePipeMessageParams_Data>(
128 message, validation_context);
110 } 129 }
111 return false; 130 return false;
112 } 131 }
113 132
114 bool ValidateControlResponse(const Message* message) { 133 bool ValidateControlResponse(const Message* message,
115 if (!ValidateMessageIsResponse(message)) 134 ValidationContext* validation_context) {
135 if (!ValidateMessageIsResponse(message, validation_context))
116 return false; 136 return false;
117 switch (message->header()->name) { 137 switch (message->header()->name) {
118 case kRunMessageId: 138 case kRunMessageId:
119 return ValidateMessagePayload<RunResponseMessageParams_Data>(message); 139 return ValidateMessagePayload<RunResponseMessageParams_Data>(
140 message, validation_context);
120 } 141 }
121 return false; 142 return false;
122 } 143 }
123 144
124 bool ValidateHandleNonNullable(const Handle_Data& input, 145 bool ValidateHandleNonNullable(const Handle_Data& input,
125 const char* error_message) { 146 const char* error_message,
147 ValidationContext* validation_context) {
126 if (input.is_valid()) 148 if (input.is_valid())
127 return true; 149 return true;
128 150
129 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 151 ReportValidationError(validation_context,
152 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
130 error_message); 153 error_message);
131 return false; 154 return false;
132 } 155 }
133 156
134 bool ValidateInterfaceIdNonNullable(InterfaceId input, 157 bool ValidateInterfaceIdNonNullable(InterfaceId input,
135 const char* error_message) { 158 const char* error_message,
159 ValidationContext* validation_context) {
136 if (IsValidInterfaceId(input)) 160 if (IsValidInterfaceId(input))
137 return true; 161 return true;
138 162
139 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID, 163 ReportValidationError(validation_context,
164 VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
140 error_message); 165 error_message);
141 return false; 166 return false;
142 } 167 }
143 168
144 bool ValidateHandle(const Handle_Data& input, BoundsChecker* bounds_checker) { 169 bool ValidateHandle(const Handle_Data& input,
145 if (bounds_checker->ClaimHandle(input)) 170 ValidationContext* validation_context) {
171 if (validation_context->ClaimHandle(input))
146 return true; 172 return true;
147 173
148 ReportValidationError(VALIDATION_ERROR_ILLEGAL_HANDLE); 174 ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE);
149 return false; 175 return false;
150 } 176 }
151 177
152 bool ValidateAssociatedInterfaceId(InterfaceId input) { 178 bool ValidateAssociatedInterfaceId(InterfaceId input,
179 ValidationContext* validation_context) {
153 if (!IsMasterInterfaceId(input)) 180 if (!IsMasterInterfaceId(input))
154 return true; 181 return true;
155 182
156 ReportValidationError(VALIDATION_ERROR_ILLEGAL_INTERFACE_ID); 183 ReportValidationError(validation_context,
184 VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
157 return false; 185 return false;
158 } 186 }
159 187
160 } // namespace internal 188 } // namespace internal
161 } // namespace mojo 189 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/validation_util.h ('k') | mojo/public/cpp/bindings/message.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698