• 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/validation_context.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include "base/logging.h"
11 #include "mojo/public/cpp/bindings/lib/serialization_util.h"
12 #include "mojo/public/cpp/bindings/message.h"
13 #include "mojo/public/cpp/system/handle.h"
14 
15 namespace mojo {
16 namespace internal {
17 
ValidationContext(const void * data,size_t data_num_bytes,size_t num_handles,Message * message,const base::StringPiece & description)18 ValidationContext::ValidationContext(const void* data,
19                                      size_t data_num_bytes,
20                                      size_t num_handles,
21                                      Message* message,
22                                      const base::StringPiece& description)
23     : message_(message),
24       description_(description),
25       data_begin_(reinterpret_cast<uintptr_t>(data)),
26       data_end_(data_begin_ + data_num_bytes),
27       handle_begin_(0),
28       handle_end_(static_cast<uint32_t>(num_handles)) {
29   if (data_end_ < data_begin_) {
30     // The calculation of |data_end_| overflowed.
31     // It shouldn't happen but if it does, set the range to empty so
32     // IsValidRange() and ClaimMemory() always fail.
33     NOTREACHED();
34     data_end_ = data_begin_;
35   }
36   if (handle_end_ < num_handles) {
37     // Assigning |num_handles| to |handle_end_| overflowed.
38     // It shouldn't happen but if it does, set the handle index range to empty.
39     NOTREACHED();
40     handle_end_ = 0;
41   }
42 }
43 
~ValidationContext()44 ValidationContext::~ValidationContext() {
45 }
46 
ClaimMemory(const void * position,uint32_t num_bytes)47 bool ValidationContext::ClaimMemory(const void* position, uint32_t num_bytes) {
48   uintptr_t begin = reinterpret_cast<uintptr_t>(position);
49   uintptr_t end = begin + num_bytes;
50 
51   if (!InternalIsValidRange(begin, end))
52     return false;
53 
54   data_begin_ = end;
55   return true;
56 }
57 
ClaimHandle(const Handle_Data & encoded_handle)58 bool ValidationContext::ClaimHandle(const Handle_Data& encoded_handle) {
59   uint32_t index = encoded_handle.value;
60   if (index == kEncodedInvalidHandleValue)
61     return true;
62 
63   if (index < handle_begin_ || index >= handle_end_)
64     return false;
65 
66   // |index| + 1 shouldn't overflow, because |index| is not the max value of
67   // uint32_t (it is less than |handle_end_|).
68   handle_begin_ = index + 1;
69   return true;
70 }
71 
IsValidRange(const void * position,uint32_t num_bytes) const72 bool ValidationContext::IsValidRange(const void* position,
73                                      uint32_t num_bytes) const {
74   uintptr_t begin = reinterpret_cast<uintptr_t>(position);
75   uintptr_t end = begin + num_bytes;
76 
77   return InternalIsValidRange(begin, end);
78 }
79 
InternalIsValidRange(uintptr_t begin,uintptr_t end) const80 bool ValidationContext::InternalIsValidRange(uintptr_t begin,
81                                              uintptr_t end) const {
82   return end > begin && begin >= data_begin_ && end <= data_end_;
83 }
84 
85 }  // namespace internal
86 }  // namespace mojo
87