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

Eric Blake eblake at redhat.com
Mon Jun 22 21:01:15 UTC 2015


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;
 };


@@ -1556,7 +1557,7 @@ virJSONParserHandleEndArray(void *ctx)

     VIR_DEBUG("parser=%p", parser);

-    if (!parser->nstate)
+    if (!(parser->nstate - parser->wrap))
         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;
     if (VIR_YAJL_STATUS_OK(rc))
         rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
+    parser.wrap = 0;
     if (VIR_YAJL_STATUS_OK(rc))
         rc = yajl_parse(hand, (const unsigned char *)"]", 1);
 # endif
diff --git a/tests/jsontest.c b/tests/jsontest.c
index a363dc0..97b9c0a 100644
--- a/tests/jsontest.c
+++ b/tests/jsontest.c
@@ -421,6 +421,7 @@ mymain(void)
     DO_TEST_PARSE_FAIL("comments", "[ /* nope */\n1 // not this either\n]");
     DO_TEST_PARSE_FAIL("trailing garbage", "[] []");
     DO_TEST_PARSE_FAIL("list without array", "1, 1");
+    DO_TEST_PARSE_FAIL("parser abuse", "1] [2");

     DO_TEST_PARSE_FAIL("object with numeric keys", "{ 1:1, 2:1, 3:2 }");
     DO_TEST_PARSE_FAIL("unterminated object", "{ \"1\":1, \"2\":1, \"3\":2");
-- 
2.4.3




More information about the libvir-list mailing list