qemu/qobject
Christophe Fergeau bbc0586ced json: Fix % handling when not interpolating
Commit 8bca4613 added support for %% in json strings when interpolating,
but in doing so broke handling of % when not interpolating.

When parse_string() is fed a string token containing '%', it skips the
'%' regardless of ctxt->ap, i.e. even it's not interpolating.  If the
'%' is the string's last character, it fails an assertion.  Else, it
"merely" swallows the '%'.

Fix parse_string() to handle '%' specially only when interpolating.

To gauge the bug's impact, let's review non-interpolating users of this
parser, i.e. code passing NULL context to json_message_parser_init():

* tests/check-qjson.c, tests/test-qobject-input-visitor.c,
  tests/test-visitor-serialization.c

  Plenty of tests, but we still failed to cover the buggy case.

* monitor.c: QMP input

* qga/main.c: QGA input

* qobject_from_json():

  - qobject-input-visitor.c: JSON command line option arguments of
    -display and -blockdev

    Reproducer: -blockdev '{"%"}'

  - block.c: JSON pseudo-filenames starting with "json:"

    Reproducer: https://bugzilla.redhat.com/show_bug.cgi?id=1668244#c3

  - block/rbd.c: JSON key pairs

    Pseudo-filenames starting with "rbd:".

Command line, QMP and QGA input are trusted.

Filenames are trusted when they come from command line, QMP or HMP.
They are untrusted when they come from from image file headers.
Example: QCOW2 backing file name.  Note that this is *not* the security
boundary between host and guest.  It's the boundary between host and an
image file from an untrusted source.

Neither failing an assertion nor skipping a character in a filename of
your choice looks exploitable.  Note that we don't support compiling
with NDEBUG.

Fixes: 8bca4613e6
Cc: qemu-stable@nongnu.org
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Message-Id: <20190102140535.11512-1-cfergeau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
[Commit message extended to discuss impact]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2019-01-24 15:20:59 +01:00
..
block-qdict.c qobject: Catch another straggler for use of qdict_put_str() 2018-10-26 17:17:32 +02:00
json-lexer.c json: Eliminate lexer state IN_WHITESPACE, pseudo-token JSON_SKIP 2018-09-24 18:08:07 +02:00
json-parser-int.h json: Eliminate lexer state IN_WHITESPACE, pseudo-token JSON_SKIP 2018-09-24 18:08:07 +02:00
json-parser.c json: Fix % handling when not interpolating 2019-01-24 15:20:59 +01:00
json-streamer.c json: Clean up headers 2018-08-24 20:26:37 +02:00
Makefile.objs qobject: Move block-specific qdict code to block-qdict.c 2018-06-15 14:49:44 +02:00
qbool.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00
qdict.c qobject: Move block-specific qdict code to block-qdict.c 2018-06-15 14:49:44 +02:00
qjson.c json: Clean up headers 2018-08-24 20:26:37 +02:00
qlist.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00
qlit.c qapi: Replace qobject_to_X(o) by qobject_to(X, o) 2018-03-19 14:58:36 -05:00
qnull.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00
qnum.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00
qobject.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00
qstring.c qobject: Drop superfluous includes of qemu-common.h 2018-08-24 20:26:37 +02:00