qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	qemu-devel@nongnu.org, Michael D Roth <mdroth@us.ibm.com>,
	Markus Armbruster <armbru@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 10/11] json-streamer: limit the maximum	recursion depth and maximum token count
Date: Fri, 11 Mar 2011 17:16:03 -0600	[thread overview]
Message-ID: <4D7AAD33.1000804@linux.vnet.ibm.com> (raw)
In-Reply-To: <1299877249-13433-11-git-send-email-aliguori@us.ibm.com>

On 03/11/2011 03:00 PM, Anthony Liguori wrote:
> The JSON parse we use is a recursive decent parser which means that recursion
> is used to backtrack.  To avoid stack overflows from malformed input, we need
> to limit recursion depth.
>
> Fortunately, we know the maximum recursion depth in the message parsing phase
> so we can very easily check for unreasonably deep recursion.  If we find that
> emit the current token stream and let the parser handle it.  The idea here is
> that hopefully the stream will recover or at least error out gracefully.
>
> We also limit the maximum token count.  We don't limit the number of tokens, but
> rather the total memory used for tokens at any given point in time.
>
> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>
> diff --git a/json-streamer.c b/json-streamer.c
> index f7e7a68..c7f43b0 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&&
> @@ -56,6 +61,19 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
>           parser->emit(parser, parser->tokens);
>           QDECREF(parser->tokens);
>           parser->tokens = qlist_new();
> +        parser->token_size = 0;
> +    } 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);

Should we even bother passing this to the parser? That's a lot stuff to 
churn on that we know isn't going to result in anything useful. If there 
was a proper object earlier in the stream it would've been emitted when 
brace/bracket count reached 0.

I think it might be nicer to do parser->emit(parser, NULL), and fix up 
json_parser_parse_err() to check for this and simply return NULL back to 
qmp_dispatch_err() or whoever is calling.

I think brace_count < 0 || bracket_count < 0 should get similar treatment.

> +        QDECREF(parser->tokens);
> +        parser->tokens = qlist_new();
> +        parser->token_size = 0;
>       }
>   }
>
> @@ -66,6 +84,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);
>   }
> diff --git a/json-streamer.h b/json-streamer.h
> index 09f3bd7..f09bc4d 100644
> --- a/json-streamer.h
> +++ b/json-streamer.h
> @@ -24,6 +24,7 @@ typedef struct JSONMessageParser
>       int brace_count;
>       int bracket_count;
>       QList *tokens;
> +    uint64_t token_size;
>   } JSONMessageParser;
>
>   void json_message_parser_init(JSONMessageParser *parser,

  reply	other threads:[~2011-03-11 23:16 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-11 21:00 [Qemu-devel] [00/11] QAPI Round 0 (JSON improvements) Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
2011-03-12  8:09   ` [Qemu-devel] " Paolo Bonzini
2011-03-12 14:52     ` Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 02/11] qerror: expose a function to format an error Anthony Liguori
2011-03-11 21:08   ` [Qemu-devel] " Anthony Liguori
2011-03-14 19:17     ` Luiz Capitulino
2011-03-14 19:27       ` Anthony Liguori
2011-03-14 19:37         ` Luiz Capitulino
2011-03-14 19:45           ` Anthony Liguori
2011-03-14 20:22             ` Luiz Capitulino
2011-03-14 20:41               ` Anthony Liguori
2011-03-14 20:48                 ` Luiz Capitulino
2011-03-14 21:03                   ` Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 03/11] add a generic Error object Anthony Liguori
2011-03-12 11:05   ` Blue Swirl
2011-03-12 14:51     ` Anthony Liguori
2011-03-14 19:18   ` [Qemu-devel] " Luiz Capitulino
2011-03-14 19:34     ` Anthony Liguori
2011-03-14 19:57       ` Luiz Capitulino
2011-03-11 21:00 ` [Qemu-devel] [PATCH 04/11] qerror: split out the reporting bits of QError Anthony Liguori
2011-03-14 19:18   ` [Qemu-devel] " Luiz Capitulino
2011-03-14 19:24     ` Anthony Liguori
2011-03-14 19:30       ` Luiz Capitulino
2011-03-14 20:30         ` Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 05/11] qerror: add new error message for invalid enum values Anthony Liguori
2011-03-14 19:19   ` [Qemu-devel] " Luiz Capitulino
2011-03-11 21:00 ` [Qemu-devel] [PATCH 06/11] qerror: add JSON parsing error message Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 07/11] json: propagate error from parser Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 08/11] json-lexer: reset the lexer state on an invalid token Anthony Liguori
2011-03-14 19:22   ` [Qemu-devel] " Luiz Capitulino
2011-03-14 19:43     ` Anthony Liguori
2011-03-14 20:12       ` Luiz Capitulino
2011-03-14 20:30         ` Anthony Liguori
2011-03-14 20:43           ` Luiz Capitulino
2011-03-11 21:00 ` [Qemu-devel] [PATCH 09/11] json-lexer: limit the maximum size of a given token Anthony Liguori
2011-03-14 19:25   ` [Qemu-devel] " Luiz Capitulino
2011-03-14 20:18     ` Anthony Liguori
2011-03-14 20:33       ` Luiz Capitulino
2011-03-11 21:00 ` [Qemu-devel] [PATCH 10/11] json-streamer: limit the maximum recursion depth and maximum token count Anthony Liguori
2011-03-11 23:16   ` Michael Roth [this message]
2011-03-12 15:03     ` Anthony Liguori
2011-03-11 21:00 ` [Qemu-devel] [PATCH 11/11] json-parser: detect premature EOI Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D7AAD33.1000804@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=armbru@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=mdroth@us.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).