1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/message_header_validator.h" 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/lib/validation_context.h" 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/lib/validation_errors.h" 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/lib/validation_util.h" 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo { 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace { 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool IsValidMessageHeader(const internal::MessageHeader* header, 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ValidationContext* validation_context) { 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // NOTE: Our goal is to preserve support for future extension of the message 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // header. If we encounter fields we do not understand, we must ignore them. 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Extra validation of the struct header: 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (header->version == 0) { 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (header->num_bytes != sizeof(internal::MessageHeader)) { 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ReportValidationError( 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez validation_context, 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } else if (header->version == 1) { 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (header->num_bytes != sizeof(internal::MessageHeaderWithRequestID)) { 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ReportValidationError( 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez validation_context, 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } else if (header->version > 1) { 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (header->num_bytes < sizeof(internal::MessageHeaderWithRequestID)) { 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ReportValidationError( 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez validation_context, 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Validate flags (allow unknown bits): 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // These flags require a RequestID. 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (header->version < 1 && ((header->flags & Message::kFlagExpectsResponse) || 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez (header->flags & Message::kFlagIsResponse))) { 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ReportValidationError( 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez validation_context, 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID); 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // These flags are mutually exclusive. 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if ((header->flags & Message::kFlagExpectsResponse) && 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez (header->flags & Message::kFlagIsResponse)) { 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ReportValidationError( 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez validation_context, 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS); 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return true; 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezMessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink) 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez : MessageHeaderValidator("MessageHeaderValidator", sink) {} 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezMessageHeaderValidator::MessageHeaderValidator(const std::string& description, 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MessageReceiver* sink) 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez : MessageFilter(sink), description_(description) { 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid MessageHeaderValidator::SetDescription(const std::string& description) { 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez description_ = description; 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool MessageHeaderValidator::Accept(Message* message) { 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Pass 0 as number of handles because we don't expect any in the header, even 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // if |message| contains handles. 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez internal::ValidationContext validation_context( 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez message->data(), message->data_num_bytes(), 0, message, description_); 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (!internal::ValidateStructHeaderAndClaimMemory(message->data(), 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez &validation_context)) 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (!IsValidMessageHeader(message->header(), &validation_context)) 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return false; 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return sink_->Accept(message); 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace mojo 97