| OLD | NEW |
| 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/lib/message_header_validator.h" | 5 #include "mojo/public/cpp/bindings/lib/message_header_validator.h" |
| 6 | 6 |
| 7 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" | 7 #include "mojo/public/cpp/bindings/lib/validation_context.h" |
| 8 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | 8 #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
| 9 #include "mojo/public/cpp/bindings/lib/validation_util.h" | 9 #include "mojo/public/cpp/bindings/lib/validation_util.h" |
| 10 | 10 |
| 11 namespace mojo { | 11 namespace mojo { |
| 12 namespace internal { | 12 namespace internal { |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 bool IsValidMessageHeader(const MessageHeader* header) { | 15 bool IsValidMessageHeader(const MessageHeader* header, |
| 16 ValidationContext* validation_context) { |
| 16 // NOTE: Our goal is to preserve support for future extension of the message | 17 // 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. | 18 // header. If we encounter fields we do not understand, we must ignore them. |
| 18 | 19 |
| 19 // Extra validation of the struct header: | 20 // Extra validation of the struct header: |
| 20 if (header->version == 0) { | 21 if (header->version == 0) { |
| 21 if (header->num_bytes != sizeof(MessageHeader)) { | 22 if (header->num_bytes != sizeof(MessageHeader)) { |
| 22 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | 23 ReportValidationError(validation_context, |
| 24 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); |
| 23 return false; | 25 return false; |
| 24 } | 26 } |
| 25 } else if (header->version == 1) { | 27 } else if (header->version == 1) { |
| 26 if (header->num_bytes != sizeof(MessageHeaderWithRequestID)) { | 28 if (header->num_bytes != sizeof(MessageHeaderWithRequestID)) { |
| 27 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | 29 ReportValidationError(validation_context, |
| 30 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); |
| 28 return false; | 31 return false; |
| 29 } | 32 } |
| 30 } else if (header->version > 1) { | 33 } else if (header->version > 1) { |
| 31 if (header->num_bytes < sizeof(MessageHeaderWithRequestID)) { | 34 if (header->num_bytes < sizeof(MessageHeaderWithRequestID)) { |
| 32 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | 35 ReportValidationError(validation_context, |
| 36 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); |
| 33 return false; | 37 return false; |
| 34 } | 38 } |
| 35 } | 39 } |
| 36 | 40 |
| 37 // Validate flags (allow unknown bits): | 41 // Validate flags (allow unknown bits): |
| 38 | 42 |
| 39 // These flags require a RequestID. | 43 // These flags require a RequestID. |
| 40 if (header->version < 1 && ((header->flags & kMessageExpectsResponse) || | 44 if (header->version < 1 && ((header->flags & kMessageExpectsResponse) || |
| 41 (header->flags & kMessageIsResponse))) { | 45 (header->flags & kMessageIsResponse))) { |
| 42 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID); | 46 ReportValidationError(validation_context, |
| 47 VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID); |
| 43 return false; | 48 return false; |
| 44 } | 49 } |
| 45 | 50 |
| 46 // These flags are mutually exclusive. | 51 // These flags are mutually exclusive. |
| 47 if ((header->flags & kMessageExpectsResponse) && | 52 if ((header->flags & kMessageExpectsResponse) && |
| 48 (header->flags & kMessageIsResponse)) { | 53 (header->flags & kMessageIsResponse)) { |
| 49 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); | 54 ReportValidationError(validation_context, |
| 55 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); |
| 50 return false; | 56 return false; |
| 51 } | 57 } |
| 52 | 58 |
| 53 return true; | 59 return true; |
| 54 } | 60 } |
| 55 | 61 |
| 56 } // namespace | 62 } // namespace |
| 57 | 63 |
| 58 MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink) | 64 MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink) |
| 59 : MessageFilter(sink) { | 65 : MessageHeaderValidator("MessageHeaderValidator", sink) {} |
| 66 |
| 67 MessageHeaderValidator::MessageHeaderValidator(const std::string& description, |
| 68 MessageReceiver* sink) |
| 69 : MessageFilter(sink), description_(description) { |
| 70 } |
| 71 |
| 72 void MessageHeaderValidator::SetDescription(const std::string& description) { |
| 73 description_ = description; |
| 60 } | 74 } |
| 61 | 75 |
| 62 bool MessageHeaderValidator::Accept(Message* message) { | 76 bool MessageHeaderValidator::Accept(Message* message) { |
| 63 // Pass 0 as number of handles because we don't expect any in the header, even | 77 // Pass 0 as number of handles because we don't expect any in the header, even |
| 64 // if |message| contains handles. | 78 // if |message| contains handles. |
| 65 BoundsChecker bounds_checker(message->data(), message->data_num_bytes(), 0); | 79 ValidationContext validation_context( |
| 80 message->data(), message->data_num_bytes(), 0, message, description_); |
| 66 | 81 |
| 67 if (!ValidateStructHeaderAndClaimMemory(message->data(), &bounds_checker)) | 82 if (!ValidateStructHeaderAndClaimMemory(message->data(), &validation_context)) |
| 68 return false; | 83 return false; |
| 69 | 84 |
| 70 if (!IsValidMessageHeader(message->header())) | 85 if (!IsValidMessageHeader(message->header(), &validation_context)) |
| 71 return false; | 86 return false; |
| 72 | 87 |
| 73 return sink_->Accept(message); | 88 return sink_->Accept(message); |
| 74 } | 89 } |
| 75 | 90 |
| 76 } // namespace internal | 91 } // namespace internal |
| 77 } // namespace mojo | 92 } // namespace mojo |
| OLD | NEW |