Home | History | Annotate | Download | only in lib
      1 // Copyright 2015 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/validation_util.h"
      6 
      7 #include <stdint.h>
      8 
      9 #include <limits>
     10 
     11 #include "mojo/public/cpp/bindings/lib/message_internal.h"
     12 #include "mojo/public/cpp/bindings/lib/serialization_util.h"
     13 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
     14 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
     15 
     16 namespace mojo {
     17 namespace internal {
     18 
     19 bool ValidateStructHeaderAndClaimMemory(const void* data,
     20                                         ValidationContext* validation_context) {
     21   if (!IsAligned(data)) {
     22     ReportValidationError(validation_context,
     23                           VALIDATION_ERROR_MISALIGNED_OBJECT);
     24     return false;
     25   }
     26   if (!validation_context->IsValidRange(data, sizeof(StructHeader))) {
     27     ReportValidationError(validation_context,
     28                           VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
     29     return false;
     30   }
     31 
     32   const StructHeader* header = static_cast<const StructHeader*>(data);
     33 
     34   if (header->num_bytes < sizeof(StructHeader)) {
     35     ReportValidationError(validation_context,
     36                           VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
     37     return false;
     38   }
     39 
     40   if (!validation_context->ClaimMemory(data, header->num_bytes)) {
     41     ReportValidationError(validation_context,
     42                           VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
     43     return false;
     44   }
     45 
     46   return true;
     47 }
     48 
     49 bool ValidateNonInlinedUnionHeaderAndClaimMemory(
     50     const void* data,
     51     ValidationContext* validation_context) {
     52   if (!IsAligned(data)) {
     53     ReportValidationError(validation_context,
     54                           VALIDATION_ERROR_MISALIGNED_OBJECT);
     55     return false;
     56   }
     57 
     58   if (!validation_context->ClaimMemory(data, kUnionDataSize) ||
     59       *static_cast<const uint32_t*>(data) != kUnionDataSize) {
     60     ReportValidationError(validation_context,
     61                           VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
     62     return false;
     63   }
     64 
     65   return true;
     66 }
     67 
     68 bool ValidateMessageIsRequestWithoutResponse(
     69     const Message* message,
     70     ValidationContext* validation_context) {
     71   if (message->has_flag(Message::kFlagIsResponse) ||
     72       message->has_flag(Message::kFlagExpectsResponse)) {
     73     ReportValidationError(validation_context,
     74                           VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
     75     return false;
     76   }
     77   return true;
     78 }
     79 
     80 bool ValidateMessageIsRequestExpectingResponse(
     81     const Message* message,
     82     ValidationContext* validation_context) {
     83   if (message->has_flag(Message::kFlagIsResponse) ||
     84       !message->has_flag(Message::kFlagExpectsResponse)) {
     85     ReportValidationError(validation_context,
     86                           VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
     87     return false;
     88   }
     89   return true;
     90 }
     91 
     92 bool ValidateMessageIsResponse(const Message* message,
     93                                ValidationContext* validation_context) {
     94   if (message->has_flag(Message::kFlagExpectsResponse) ||
     95       !message->has_flag(Message::kFlagIsResponse)) {
     96     ReportValidationError(validation_context,
     97                           VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
     98     return false;
     99   }
    100   return true;
    101 }
    102 
    103 bool IsHandleOrInterfaceValid(const AssociatedInterface_Data& input) {
    104   return input.handle.is_valid();
    105 }
    106 
    107 bool IsHandleOrInterfaceValid(const AssociatedEndpointHandle_Data& input) {
    108   return input.is_valid();
    109 }
    110 
    111 bool IsHandleOrInterfaceValid(const Interface_Data& input) {
    112   return input.handle.is_valid();
    113 }
    114 
    115 bool IsHandleOrInterfaceValid(const Handle_Data& input) {
    116   return input.is_valid();
    117 }
    118 
    119 bool ValidateHandleOrInterfaceNonNullable(
    120     const AssociatedInterface_Data& input,
    121     const char* error_message,
    122     ValidationContext* validation_context) {
    123   if (IsHandleOrInterfaceValid(input))
    124     return true;
    125 
    126   ReportValidationError(validation_context,
    127                         VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
    128                         error_message);
    129   return false;
    130 }
    131 
    132 bool ValidateHandleOrInterfaceNonNullable(
    133     const AssociatedEndpointHandle_Data& input,
    134     const char* error_message,
    135     ValidationContext* validation_context) {
    136   if (IsHandleOrInterfaceValid(input))
    137     return true;
    138 
    139   ReportValidationError(validation_context,
    140                         VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
    141                         error_message);
    142   return false;
    143 }
    144 
    145 bool ValidateHandleOrInterfaceNonNullable(
    146     const Interface_Data& input,
    147     const char* error_message,
    148     ValidationContext* validation_context) {
    149   if (IsHandleOrInterfaceValid(input))
    150     return true;
    151 
    152   ReportValidationError(validation_context,
    153                         VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
    154                         error_message);
    155   return false;
    156 }
    157 
    158 bool ValidateHandleOrInterfaceNonNullable(
    159     const Handle_Data& input,
    160     const char* error_message,
    161     ValidationContext* validation_context) {
    162   if (IsHandleOrInterfaceValid(input))
    163     return true;
    164 
    165   ReportValidationError(validation_context,
    166                         VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
    167                         error_message);
    168   return false;
    169 }
    170 
    171 bool ValidateHandleOrInterface(const AssociatedInterface_Data& input,
    172                                ValidationContext* validation_context) {
    173   if (validation_context->ClaimAssociatedEndpointHandle(input.handle))
    174     return true;
    175 
    176   ReportValidationError(validation_context,
    177                         VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
    178   return false;
    179 }
    180 
    181 bool ValidateHandleOrInterface(const AssociatedEndpointHandle_Data& input,
    182                                ValidationContext* validation_context) {
    183   if (validation_context->ClaimAssociatedEndpointHandle(input))
    184     return true;
    185 
    186   ReportValidationError(validation_context,
    187                         VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
    188   return false;
    189 }
    190 
    191 bool ValidateHandleOrInterface(const Interface_Data& input,
    192                                ValidationContext* validation_context) {
    193   if (validation_context->ClaimHandle(input.handle))
    194     return true;
    195 
    196   ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE);
    197   return false;
    198 }
    199 
    200 bool ValidateHandleOrInterface(const Handle_Data& input,
    201                                ValidationContext* validation_context) {
    202   if (validation_context->ClaimHandle(input))
    203     return true;
    204 
    205   ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE);
    206   return false;
    207 }
    208 
    209 }  // namespace internal
    210 }  // namespace mojo
    211