Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: mojo/public/cpp/bindings/lib/validation_context.h

Issue 2312813002: Limit Mojo messages recursion depth (Closed)
Patch Set: Update comment to match arg name change Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" 13 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
14 14
15 static const int kMaxRecursionDepth = 100;
dcheng 2016/09/06 21:37:03 I'd suggest a more conservative limit. Maybe 50, s
tibell 2016/09/07 05:41:20 I took this from the old IPC limit at https://cs.c
16
15 namespace mojo { 17 namespace mojo {
16 18
17 class Message; 19 class Message;
18 20
19 namespace internal { 21 namespace internal {
20 22
21 // ValidationContext is used when validating object sizes, pointers and handle 23 // ValidationContext is used when validating object sizes, pointers and handle
22 // indices in the payload of incoming messages. 24 // indices in the payload of incoming messages.
23 class ValidationContext { 25 class ValidationContext {
24 public: 26 public:
25 // [data, data + data_num_bytes) specifies the initial valid memory range. 27 // [data, data + data_num_bytes) specifies the initial valid memory range.
26 // [0, num_handles) specifies the initial valid range of handle indices. 28 // [0, num_handles) specifies the initial valid range of handle indices.
27 // 29 //
28 // If provided, |message| and |description| provide additional information 30 // If provided, |message| and |description| provide additional information
29 // to use when reporting validation errors. In addition if |message| is 31 // to use when reporting validation errors. In addition if |message| is
30 // provided, the MojoNotifyBadMessage API will be used to notify the system of 32 // provided, the MojoNotifyBadMessage API will be used to notify the system of
31 // such errors. 33 // such errors.
32 ValidationContext(const void* data, 34 ValidationContext(const void* data,
33 size_t data_num_bytes, 35 size_t data_num_bytes,
34 size_t num_handles, 36 size_t num_handles,
35 Message* message = nullptr, 37 Message* message = nullptr,
36 const base::StringPiece& description = ""); 38 const base::StringPiece& description = "",
39 int stack_depth = 0);
37 40
38 ~ValidationContext(); 41 ~ValidationContext();
39 42
40 // Claims the specified memory range. 43 // Claims the specified memory range.
41 // The method succeeds if the range is valid to claim. (Please see 44 // The method succeeds if the range is valid to claim. (Please see
42 // the comments for IsValidRange().) 45 // the comments for IsValidRange().)
43 // On success, the valid memory range is shrinked to begin right after the end 46 // On success, the valid memory range is shrinked to begin right after the end
44 // of the claimed range. 47 // of the claimed range.
45 bool ClaimMemory(const void* position, uint32_t num_bytes) { 48 bool ClaimMemory(const void* position, uint32_t num_bytes) {
46 uintptr_t begin = reinterpret_cast<uintptr_t>(position); 49 uintptr_t begin = reinterpret_cast<uintptr_t>(position);
(...skipping 27 matching lines...) Expand all
74 77
75 // Returns true if the specified range is not empty, and the range is 78 // Returns true if the specified range is not empty, and the range is
76 // contained inside the valid memory range. 79 // contained inside the valid memory range.
77 bool IsValidRange(const void* position, uint32_t num_bytes) const { 80 bool IsValidRange(const void* position, uint32_t num_bytes) const {
78 uintptr_t begin = reinterpret_cast<uintptr_t>(position); 81 uintptr_t begin = reinterpret_cast<uintptr_t>(position);
79 uintptr_t end = begin + num_bytes; 82 uintptr_t end = begin + num_bytes;
80 83
81 return InternalIsValidRange(begin, end); 84 return InternalIsValidRange(begin, end);
82 } 85 }
83 86
87 // This object should be created on the stack once every time we recurse down
88 // into a subfield during validation to make sure we don't recurse too deep
89 // and blow the stack.
90 class ScopedDepthTracker {
91 public:
92 // |ctx| must outlive this object.
93 ScopedDepthTracker(ValidationContext* ctx) : ctx_(ctx) {
dcheng 2016/09/06 21:37:02 Nit: explicit
tibell 2016/09/07 05:41:20 Done.
94 ++ctx_->stack_depth_;
95 }
96
97 ~ScopedDepthTracker() {
98 --ctx_->stack_depth_;
99 }
100
101 private:
102 ValidationContext* ctx_;
103
104 DISALLOW_COPY_AND_ASSIGN(ScopedDepthTracker);
dcheng 2016/09/06 21:37:02 Nit: include base/compiler_specific.h
tibell 2016/09/07 05:41:20 Done.
105 };
106
107 // Returns true if the recursion depth limit has been reached.
108 bool ExceedsMaxDepth() WARN_UNUSED_RESULT {
109 return stack_depth_ > kMaxRecursionDepth;
110 }
111
84 Message* message() const { return message_; } 112 Message* message() const { return message_; }
85 const base::StringPiece& description() const { return description_; } 113 const base::StringPiece& description() const { return description_; }
86 114
87 private: 115 private:
88 bool InternalIsValidRange(uintptr_t begin, uintptr_t end) const { 116 bool InternalIsValidRange(uintptr_t begin, uintptr_t end) const {
89 return end > begin && begin >= data_begin_ && end <= data_end_; 117 return end > begin && begin >= data_begin_ && end <= data_end_;
90 } 118 }
91 119
92 Message* const message_; 120 Message* const message_;
93 const base::StringPiece description_; 121 const base::StringPiece description_;
94 122
95 // [data_begin_, data_end_) is the valid memory range. 123 // [data_begin_, data_end_) is the valid memory range.
96 uintptr_t data_begin_; 124 uintptr_t data_begin_;
97 uintptr_t data_end_; 125 uintptr_t data_end_;
98 126
99 // [handle_begin_, handle_end_) is the valid handle index range. 127 // [handle_begin_, handle_end_) is the valid handle index range.
100 uint32_t handle_begin_; 128 uint32_t handle_begin_;
101 uint32_t handle_end_; 129 uint32_t handle_end_;
102 130
131 int stack_depth_;
132
103 DISALLOW_COPY_AND_ASSIGN(ValidationContext); 133 DISALLOW_COPY_AND_ASSIGN(ValidationContext);
104 }; 134 };
105 135
106 } // namespace internal 136 } // namespace internal
107 } // namespace mojo 137 } // namespace mojo
108 138
109 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_ 139 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_CONTEXT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698