[libvirt] [PATCH 4/3] json: even stricter trailing garbage detection

Peter Krempa pkrempa at redhat.com
Tue Jun 23 11:48:44 UTC 2015


On Mon, Jun 22, 2015 at 15:01:15 -0600, Eric Blake wrote:
> Since older yajl ignores trailing garbage, a client can cause
> problems by intentionally ending the wrapper array early. Since
> we already track nesting, it's not too much harder to reject
> invalid nesting pops.
> 
> * src/util/virjson. (_virJSONParser): Add field.
> (virJSONValueFromString): Set witness.
> (virJSONParserHandleEndArray): Use it to catch abuse.
> * tests/jsontest.c (mymain): Test it.
> 
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
> 
> Could be squashed with 3/3, if desired.
> 
>  src/util/virjson.c | 7 +++++--
>  tests/jsontest.c   | 1 +
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/src/util/virjson.c b/src/util/virjson.c
> index a33005a..3c6ed34 100644
> --- a/src/util/virjson.c
> +++ b/src/util/virjson.c
> @@ -64,6 +64,7 @@ struct _virJSONParser {
>      virJSONValuePtr head;
>      virJSONParserStatePtr state;
>      size_t nstate;
> +    int wrap;

Boolean?

>  };
> 
> 
> @@ -1556,7 +1557,7 @@ virJSONParserHandleEndArray(void *ctx)
> 
>      VIR_DEBUG("parser=%p", parser);
> 
> -    if (!parser->nstate)
> +    if (!(parser->nstate - parser->wrap))

Yuck! This really covers up what's happening here.

if ((parser->nstate == 1 && parser->wrap) ||
    (parser->nstate == 0 && !parser->wrap))

It takes two lines but you at least don't cover up the logic.

>          return 0;
> 
>      state = &(parser->state[parser->nstate-1]);
> @@ -1591,7 +1592,7 @@ virJSONValuePtr
>  virJSONValueFromString(const char *jsonstring)
>  {
>      yajl_handle hand;
> -    virJSONParser parser = { NULL, NULL, 0 };
> +    virJSONParser parser = { NULL, NULL, 0, 0 };
>      virJSONValuePtr ret = NULL;
>      int rc;
>      size_t len = strlen(jsonstring);
> @@ -1627,8 +1628,10 @@ virJSONValueFromString(const char *jsonstring)
>      rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
>  # else
>      rc = yajl_parse(hand, (const unsigned char *)"[", 1);
> +    parser.wrap = 1;

True?

>      if (VIR_YAJL_STATUS_OK(rc))
>          rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
> +    parser.wrap = 0;

False?

>      if (VIR_YAJL_STATUS_OK(rc))
>          rc = yajl_parse(hand, (const unsigned char *)"]", 1);
>  # endif

Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150623/b018cb49/attachment-0001.sig>


More information about the libvir-list mailing list