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 |