From 93e8b8778ae4eb7e2f1d8eae5159a5f3e0e9ed70 Mon Sep 17 00:00:00 2001 From: Osier Yang Date: Wed, 23 Mar 2011 22:57:44 +0800 Subject: [PATCH] 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 --- src/util/json.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/util/json.c b/src/util/json.c index f90594cb1d..be47f64031 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -65,7 +65,7 @@ void virJSONValueFree(virJSONValuePtr value) switch (value->type) { 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); virJSONValueFree(value->data.object.pairs[i].value); } @@ -897,6 +897,7 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring) yajl_parser_config cfg = { 1, 1 }; yajl_handle hand; virJSONParser parser = { NULL, NULL, 0 }; + virJSONValuePtr ret = NULL; VIR_DEBUG("string=%s", jsonstring); @@ -917,6 +918,8 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring) goto cleanup; } + ret = parser.head; + cleanup: yajl_free(hand); @@ -930,7 +933,7 @@ cleanup: VIR_DEBUG("result=%p", parser.head); - return parser.head; + return ret; }