Patchwork [v1,07/14] json-streamer: limit the maximum recursion depth and maximum token count

login
register
mail settings
Submitter Michael Roth
Date June 1, 2011, 5:14 p.m.
Message ID <1306948500-15086-8-git-send-email-mdroth@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/98315/
State New
Headers show

Comments

Michael Roth - June 1, 2011, 5:14 p.m.
From: Anthony Liguori <aliguori@us.ibm.com>


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 json-streamer.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

Patch

diff --git a/json-streamer.c b/json-streamer.c
index 549e9b7..6b9af63 100644
--- a/json-streamer.c
+++ b/json-streamer.c
@@ -18,6 +18,9 @@ 
 #include "json-lexer.h"
 #include "json-streamer.h"
 
+#define MAX_TOKEN_SIZE (64ULL << 20)
+#define MAX_NESTING (1ULL << 10)
+
 static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
 {
     JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
@@ -49,6 +52,8 @@  static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
     qdict_put(dict, "x", qint_from_int(x));
     qdict_put(dict, "y", qint_from_int(y));
 
+    parser->token_size += token->length;
+
     qlist_append(parser->tokens, dict);
 
     if (parser->brace_count < 0 ||
@@ -60,6 +65,17 @@  static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
         parser->emit(parser, parser->tokens);
         QDECREF(parser->tokens);
         parser->tokens = qlist_new();
+    } else if (parser->token_size > MAX_TOKEN_SIZE ||
+               parser->bracket_count > MAX_NESTING ||
+               parser->brace_count > MAX_NESTING) {
+        /* Security consideration, we limit total memory allocated per object
+         * and the maximum recursion depth that a message can force.
+         */
+        parser->brace_count = 0;
+        parser->bracket_count = 0;
+        parser->emit(parser, parser->tokens);
+        QDECREF(parser->tokens);
+        parser->tokens = qlist_new();
     }
 }
 
@@ -70,6 +86,7 @@  void json_message_parser_init(JSONMessageParser *parser,
     parser->brace_count = 0;
     parser->bracket_count = 0;
     parser->tokens = qlist_new();
+    parser->token_size = 0;
 
     json_lexer_init(&parser->lexer, json_message_process_token);
 }