Index: mojo/public/cpp/bindings/lib/validation_context.h |
diff --git a/mojo/public/cpp/bindings/lib/validation_context.h b/mojo/public/cpp/bindings/lib/validation_context.h |
index 55d083cffe97691d6cc87a64adc447b63e077c7f..ea73df95e4f323edb549b25023f9117924b0b0ba 100644 |
--- a/mojo/public/cpp/bindings/lib/validation_context.h |
+++ b/mojo/public/cpp/bindings/lib/validation_context.h |
@@ -12,6 +12,8 @@ |
#include "base/strings/string_piece.h" |
#include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
+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
|
+ |
namespace mojo { |
class Message; |
@@ -33,7 +35,8 @@ class ValidationContext { |
size_t data_num_bytes, |
size_t num_handles, |
Message* message = nullptr, |
- const base::StringPiece& description = ""); |
+ const base::StringPiece& description = "", |
+ int stack_depth = 0); |
~ValidationContext(); |
@@ -81,6 +84,31 @@ class ValidationContext { |
return InternalIsValidRange(begin, end); |
} |
+ // This object should be created on the stack once every time we recurse down |
+ // into a subfield during validation to make sure we don't recurse too deep |
+ // and blow the stack. |
+ class ScopedDepthTracker { |
+ public: |
+ // |ctx| must outlive this object. |
+ ScopedDepthTracker(ValidationContext* ctx) : ctx_(ctx) { |
dcheng
2016/09/06 21:37:02
Nit: explicit
tibell
2016/09/07 05:41:20
Done.
|
+ ++ctx_->stack_depth_; |
+ } |
+ |
+ ~ScopedDepthTracker() { |
+ --ctx_->stack_depth_; |
+ } |
+ |
+ private: |
+ ValidationContext* ctx_; |
+ |
+ 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.
|
+ }; |
+ |
+ // Returns true if the recursion depth limit has been reached. |
+ bool ExceedsMaxDepth() WARN_UNUSED_RESULT { |
+ return stack_depth_ > kMaxRecursionDepth; |
+ } |
+ |
Message* message() const { return message_; } |
const base::StringPiece& description() const { return description_; } |
@@ -100,6 +128,8 @@ class ValidationContext { |
uint32_t handle_begin_; |
uint32_t handle_end_; |
+ int stack_depth_; |
+ |
DISALLOW_COPY_AND_ASSIGN(ValidationContext); |
}; |