提交 93e8b877 编写于 作者: O Osier Yang

util: Fix return value for virJSONValueFromString if it fails

Problem:
  "parser.head" is not NULL even if it's free'ed by "virJSONValueFree",
returning "parser.head" when "virJSONValueFromString" fails will cause
unexpected errors (libvirtd will crash sometimes), e.g.
  In function "qemuMonitorJSONArbitraryCommand":

        if (!(cmd = virJSONValueFromString(cmd_str)))
            goto cleanup;

        if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
            goto cleanup;

        ......

     cleanup:
        virJSONValueFree(cmd);

  It will continues to send command to monitor even if "virJSONValueFromString"
is failed, and more worse, it trys to free "cmd" again.

  Crash example:
{"error":{"class":"QMPBadInputObject","desc":"Expected 'execute' in QMP input","data":{"expected":"execute"}}}
{"error":{"class":"QMPBadInputObject","desc":"Expected 'execute' in QMP input","data":{"expected":"execute"}}}
error: server closed connection:
error: unable to connect to '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: Connection refused
error: failed to connect to the hypervisor

  This fix is to:
    1) return NULL for failure of "virJSONValueFromString",
    2) and it seems "virJSONValueFree" uses incorrect loop index for type
       of "VIR_JSON_TYPE_OBJECT", fix it together.

* src/util/json.c
上级 bcac844f
...@@ -65,7 +65,7 @@ void virJSONValueFree(virJSONValuePtr value) ...@@ -65,7 +65,7 @@ void virJSONValueFree(virJSONValuePtr value)
switch (value->type) { switch (value->type) {
case VIR_JSON_TYPE_OBJECT: case VIR_JSON_TYPE_OBJECT:
for (i = 0 ; i < value->data.array.nvalues ; i++) { for (i = 0 ; i < value->data.object.npairs; i++) {
VIR_FREE(value->data.object.pairs[i].key); VIR_FREE(value->data.object.pairs[i].key);
virJSONValueFree(value->data.object.pairs[i].value); virJSONValueFree(value->data.object.pairs[i].value);
} }
...@@ -897,6 +897,7 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring) ...@@ -897,6 +897,7 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring)
yajl_parser_config cfg = { 1, 1 }; yajl_parser_config cfg = { 1, 1 };
yajl_handle hand; yajl_handle hand;
virJSONParser parser = { NULL, NULL, 0 }; virJSONParser parser = { NULL, NULL, 0 };
virJSONValuePtr ret = NULL;
VIR_DEBUG("string=%s", jsonstring); VIR_DEBUG("string=%s", jsonstring);
...@@ -917,6 +918,8 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring) ...@@ -917,6 +918,8 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring)
goto cleanup; goto cleanup;
} }
ret = parser.head;
cleanup: cleanup:
yajl_free(hand); yajl_free(hand);
...@@ -930,7 +933,7 @@ cleanup: ...@@ -930,7 +933,7 @@ cleanup:
VIR_DEBUG("result=%p", parser.head); VIR_DEBUG("result=%p", parser.head);
return parser.head; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册