From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60117) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XRh2z-0002z8-J9 for qemu-devel@nongnu.org; Wed, 10 Sep 2014 08:30:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XRh2t-0007h2-Vy for qemu-devel@nongnu.org; Wed, 10 Sep 2014 08:30:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:31914) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XRh2t-0007gr-Pm for qemu-devel@nongnu.org; Wed, 10 Sep 2014 08:30:47 -0400 From: Fam Zheng Date: Wed, 10 Sep 2014 20:30:39 +0800 Message-Id: <1410352239-8705-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH] qapi: Fix crash with enum dealloc when kind is invalid List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Markus Armbruster , Michael Roth , Stefan Hajnoczi , Paolo Bonzini , Luiz Capitulino We shouldn't do anything in the switch block in enum's visit_type_ function, when the enum data's ->kind is not valid at all. This happens when the dealloc visitor is called, after qmp input visitor returned error. Now, the input visitor will set ->kind to _MAX if the value is not found, so that in dealloc, the switch block knows to skip calling into specific type's visiting functions. The added test case would trigger SIGSEGV without this fix. This crash is introduced since commit b1de5f43 (QMP: Add support for Archipelago). Signed-off-by: Fam Zheng --- qapi/qapi-visit-core.c | 12 +++++------- scripts/qapi-visit.py | 6 ++++++ tests/qemu-iotests/087 | 17 +++++++++++++++++ tests/qemu-iotests/087.out | 13 +++++++++++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 55f8d40..6c46e0e 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -276,23 +276,21 @@ void input_type_enum(Visitor *v, int *obj, const char *strings[], visit_type_str(v, &enum_str, name, &local_err); if (local_err) { - error_propagate(errp, local_err); - return; + enum_str = NULL; } while (strings[value] != NULL) { - if (strcmp(strings[value], enum_str) == 0) { + if (enum_str && strcmp(strings[value], enum_str) == 0) { break; } value++; } - if (strings[value] == NULL) { - error_set(errp, QERR_INVALID_PARAMETER, enum_str); - g_free(enum_str); - return; + if (!local_err && strings[value] == NULL) { + error_set(&local_err, QERR_INVALID_PARAMETER, enum_str); } g_free(enum_str); *obj = value; + error_propagate(errp, local_err); } diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index c129697..dad7561 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -379,6 +379,12 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e c_name=c_fun(key)) ret += mcgen(''' + case %(enum_full_value)s: + break; +''', + enum_full_value = generate_enum_full_value(disc_type, 'MAX')) + + ret += mcgen(''' default: abort(); } diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 index 82c56b1..d7454d1 100755 --- a/tests/qemu-iotests/087 +++ b/tests/qemu-iotests/087 @@ -218,6 +218,23 @@ run_qemu <