• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
6 
7 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
8 #include "mojo/public/cpp/bindings/lib/bounds_checker.h"
9 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
10 
11 namespace mojo {
12 namespace internal {
13 namespace {
14 
IsValidMessageHeader(const MessageHeader * header)15 bool IsValidMessageHeader(const MessageHeader* header) {
16   // 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 
19   // Extra validation of the struct header:
20   if (header->num_fields == 2) {
21     if (header->num_bytes != sizeof(MessageHeader)) {
22       ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
23       return false;
24     }
25   } else if (header->num_fields == 3) {
26     if (header->num_bytes != sizeof(MessageHeaderWithRequestID)) {
27       ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
28       return false;
29     }
30   } else if (header->num_fields > 3) {
31     if (header->num_bytes < sizeof(MessageHeaderWithRequestID)) {
32       ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
33       return false;
34     }
35   }
36 
37   // Validate flags (allow unknown bits):
38 
39   // These flags require a RequestID.
40   if (header->num_fields < 3 &&
41         ((header->flags & kMessageExpectsResponse) ||
42          (header->flags & kMessageIsResponse))) {
43     ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID);
44     return false;
45   }
46 
47   // These flags are mutually exclusive.
48   if ((header->flags & kMessageExpectsResponse) &&
49       (header->flags & kMessageIsResponse)) {
50     ReportValidationError(
51         VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION);
52     return false;
53   }
54 
55   return true;
56 }
57 
58 }  // namespace
59 
MessageHeaderValidator(MessageReceiver * sink)60 MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink)
61     : MessageFilter(sink) {
62 }
63 
Accept(Message * message)64 bool MessageHeaderValidator::Accept(Message* message) {
65   // Pass 0 as number of handles because we don't expect any in the header, even
66   // if |message| contains handles.
67   BoundsChecker bounds_checker(message->data(), message->data_num_bytes(), 0);
68 
69   if (!ValidateStructHeader(message->data(), sizeof(MessageHeader), 2,
70                             &bounds_checker)) {
71     return false;
72   }
73 
74   if (!IsValidMessageHeader(message->header()))
75     return false;
76 
77   return sink_->Accept(message);
78 }
79 
80 }  // namespace internal
81 }  // namespace mojo
82