[libvirt] [PATCH] util: Fix return value for virJSONValueFromString if it fails
Daniel P. Berrange
berrange at redhat.com
Wed Mar 23 13:19:06 UTC 2011
On Wed, Mar 23, 2011 at 08:07:25PM +0800, Osier Yang wrote:
> 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 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/src/util/json.c b/src/util/json.c
> index f90594c..be47f64 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;
> }
ACK
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list