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