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

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

Issue 2660733002: Mojo C++ bindings: introduce an optional array to store transferred interface IDs in messages. (Closed)
Patch Set: . Created 3 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/message_header_validator.h" 5 #include "mojo/public/cpp/bindings/message_header_validator.h"
6 6
7 #include "mojo/public/cpp/bindings/lib/array_internal.h"
8 #include "mojo/public/cpp/bindings/lib/validate_params.h"
7 #include "mojo/public/cpp/bindings/lib/validation_context.h" 9 #include "mojo/public/cpp/bindings/lib/validation_context.h"
8 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 10 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
9 #include "mojo/public/cpp/bindings/lib/validation_util.h" 11 #include "mojo/public/cpp/bindings/lib/validation_util.h"
10 12
11 namespace mojo { 13 namespace mojo {
12 namespace { 14 namespace {
13 15
16 // TODO(yzshen): Define a mojom struct for message header and use the generated
17 // validation and data view code.
14 bool IsValidMessageHeader(const internal::MessageHeader* header, 18 bool IsValidMessageHeader(const internal::MessageHeader* header,
15 internal::ValidationContext* validation_context) { 19 internal::ValidationContext* validation_context) {
16 // NOTE: Our goal is to preserve support for future extension of the message 20 // NOTE: Our goal is to preserve support for future extension of the message
17 // header. If we encounter fields we do not understand, we must ignore them. 21 // header. If we encounter fields we do not understand, we must ignore them.
18 22
19 // Extra validation of the struct header: 23 // Extra validation of the struct header:
20 if (header->version == 0) { 24 do {
21 if (header->num_bytes != sizeof(internal::MessageHeader)) { 25 if (header->version == 0) {
22 internal::ReportValidationError( 26 if (header->num_bytes == sizeof(internal::MessageHeader))
23 validation_context, 27 break;
24 internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 28 } else if (header->version == 1) {
25 return false; 29 if (header->num_bytes == sizeof(internal::MessageHeaderV1))
30 break;
31 } else if (header->version == 2) {
32 if (header->num_bytes == sizeof(internal::MessageHeaderV2))
33 break;
34 } else if (header->version > 2) {
35 if (header->num_bytes >= sizeof(internal::MessageHeaderV2))
36 break;
26 } 37 }
27 } else if (header->version == 1) { 38 internal::ReportValidationError(
28 if (header->num_bytes != sizeof(internal::MessageHeaderWithRequestID)) { 39 validation_context,
29 internal::ReportValidationError( 40 internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
30 validation_context, 41 return false;
31 internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 42 } while (false);
32 return false;
33 }
34 } else if (header->version > 1) {
35 if (header->num_bytes < sizeof(internal::MessageHeaderWithRequestID)) {
36 internal::ReportValidationError(
37 validation_context,
38 internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
39 return false;
40 }
41 }
42 43
43 // Validate flags (allow unknown bits): 44 // Validate flags (allow unknown bits):
44 45
45 // These flags require a RequestID. 46 // These flags require a RequestID.
46 if (header->version < 1 && ((header->flags & Message::kFlagExpectsResponse) || 47 constexpr uint32_t kRequestIdFlags =
47 (header->flags & Message::kFlagIsResponse))) { 48 Message::kFlagExpectsResponse | Message::kFlagIsResponse;
49 if (header->version == 0 && (header->flags & kRequestIdFlags)) {
48 internal::ReportValidationError( 50 internal::ReportValidationError(
49 validation_context, 51 validation_context,
50 internal::VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID); 52 internal::VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID);
51 return false; 53 return false;
52 } 54 }
53 55
54 // These flags are mutually exclusive. 56 // These flags are mutually exclusive.
55 if ((header->flags & Message::kFlagExpectsResponse) && 57 if ((header->flags & kRequestIdFlags) == kRequestIdFlags) {
56 (header->flags & Message::kFlagIsResponse)) {
57 internal::ReportValidationError( 58 internal::ReportValidationError(
58 validation_context, 59 validation_context,
59 internal::VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 60 internal::VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
60 return false; 61 return false;
61 } 62 }
62 63
64 if (header->version < 2)
65 return true;
66
67 auto header_v2 = static_cast<const internal::MessageHeaderV2*>(header);
68 // For the payload pointer:
69 // - Check that the pointer can be safely decoded.
70 // - Claim one byte that the pointer points to. It makes sure not only the
71 // address is within the message, but also the address precedes the array
72 // storing interface IDs (which is important for safely calculating the
73 // payload size).
74 // - Validation of the payload contents will be done separately based on the
75 // payload type.
76 if (!header_v2->payload.is_null() &&
77 (!internal::ValidatePointer(header_v2->payload, validation_context) ||
78 !validation_context->ClaimMemory(header_v2->payload.Get(), 1))) {
79 return false;
80 }
81
82 const internal::ContainerValidateParams validate_params(0, false, nullptr);
83 if (!internal::ValidateContainer(header_v2->payload_interface_ids,
84 validation_context, &validate_params)) {
85 return false;
86 }
87
88 if (!header_v2->payload_interface_ids.is_null()) {
89 size_t num_ids = header_v2->payload_interface_ids.Get()->size();
90 const uint32_t* ids = header_v2->payload_interface_ids.Get()->storage();
91 for (size_t i = 0; i < num_ids; ++i) {
92 if (!IsValidInterfaceId(ids[i]) || IsMasterInterfaceId(ids[i])) {
93 internal::ReportValidationError(
94 validation_context,
95 internal::VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
96 return false;
97 }
98 }
99 }
100
63 return true; 101 return true;
64 } 102 }
65 103
66 } // namespace 104 } // namespace
67 105
68 MessageHeaderValidator::MessageHeaderValidator() 106 MessageHeaderValidator::MessageHeaderValidator()
69 : MessageHeaderValidator("MessageHeaderValidator") {} 107 : MessageHeaderValidator("MessageHeaderValidator") {}
70 108
71 MessageHeaderValidator::MessageHeaderValidator(const std::string& description) 109 MessageHeaderValidator::MessageHeaderValidator(const std::string& description)
72 : description_(description) { 110 : description_(description) {
73 } 111 }
74 112
75 void MessageHeaderValidator::SetDescription(const std::string& description) { 113 void MessageHeaderValidator::SetDescription(const std::string& description) {
76 description_ = description; 114 description_ = description;
77 } 115 }
78 116
79 bool MessageHeaderValidator::Accept(Message* message) { 117 bool MessageHeaderValidator::Accept(Message* message) {
80 // Pass 0 as number of handles because we don't expect any in the header, even 118 // Pass 0 as number of handles and associated endpoint handles because we
81 // if |message| contains handles. 119 // don't expect any in the header, even if |message| contains handles.
82 internal::ValidationContext validation_context( 120 internal::ValidationContext validation_context(
83 message->data(), message->data_num_bytes(), 0, message, description_); 121 message->data(), message->data_num_bytes(), 0, 0, message, description_);
84 122
85 if (!internal::ValidateStructHeaderAndClaimMemory(message->data(), 123 if (!internal::ValidateStructHeaderAndClaimMemory(message->data(),
86 &validation_context)) 124 &validation_context))
87 return false; 125 return false;
88 126
89 if (!IsValidMessageHeader(message->header(), &validation_context)) 127 if (!IsValidMessageHeader(message->header(), &validation_context))
90 return false; 128 return false;
91 129
92 return true; 130 return true;
93 } 131 }
94 132
95 } // namespace mojo 133 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/message_builder.cc ('k') | mojo/public/cpp/bindings/lib/message_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698