From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33316) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fmZOp-0001XQ-5R for qemu-devel@nongnu.org; Mon, 06 Aug 2018 02:53:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fmZOm-00087n-FC for qemu-devel@nongnu.org; Mon, 06 Aug 2018 02:53:51 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:35604 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fmZOm-00087H-7E for qemu-devel@nongnu.org; Mon, 06 Aug 2018 02:53:48 -0400 From: Markus Armbruster Date: Mon, 6 Aug 2018 08:53:31 +0200 Message-Id: <20180806065344.7103-11-armbru@redhat.com> In-Reply-To: <20180806065344.7103-1-armbru@redhat.com> References: <20180806065344.7103-1-armbru@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v3 10/23] qobject: qobject_from_jsonv() is dangerous, hide it away List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: thuth@redhat.com, f4bug@amsat.org, eblake@redhat.com qobject_from_jsonv() takes ownership of %p arguments. On failure, we can't generally know whether we failed before or after %p, so ownership becomes indeterminate. To avoid leaks, callers passing %p must terminate on error, e.g. by passing &error_abort. Trap for the unwary; document and give the function internal linkage. Signed-off-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Eric Blake --- include/qapi/qmp/qjson.h | 2 -- qobject/qjson.c | 13 ++++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h index dce78583dc..5ebbe5a118 100644 --- a/include/qapi/qmp/qjson.h +++ b/include/qapi/qmp/qjson.h @@ -15,8 +15,6 @@ #define QJSON_H =20 QObject *qobject_from_json(const char *string, Error **errp); -QObject *qobject_from_jsonv(const char *string, va_list *ap, Error **err= p) - GCC_FMT_ATTR(1, 0); =20 QObject *qobject_from_vjsonf_nofail(const char *string, va_list ap) GCC_FMT_ATTR(1, 0); diff --git a/qobject/qjson.c b/qobject/qjson.c index 2e450231ff..ab4040f235 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -39,7 +39,18 @@ static void parse_json(JSONMessageParser *parser, GQue= ue *tokens) s->result =3D json_parser_parse_err(tokens, s->ap, &s->err); } =20 -QObject *qobject_from_jsonv(const char *string, va_list *ap, Error **err= p) +/* + * Parse @string as JSON value. + * If @ap is non-null, interpolate %-escapes. + * Takes ownership of %p arguments. + * On success, return the JSON value. + * On failure, store an error through @errp and return NULL. + * Ownership of %p arguments becomes indeterminate then. To avoid + * leaks, callers passing %p must terminate on error, e.g. by passing + * &error_abort. + */ +static QObject *qobject_from_jsonv(const char *string, va_list *ap, + Error **errp) { JSONParsingState state =3D {}; =20 --=20 2.17.1