Bug 1614569 - Jansson can not always parse QEMU's JSON
Summary: Jansson can not always parse QEMU's JSON
Keywords:
Status: CLOSED NEXTRELEASE
Alias: None
Product: Virtualization Tools
Classification: Community
Component: libvirt
Version: unspecified
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Libvirt Maintainers
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks: 1496189
TreeView+ depends on / blocked
 
Reported: 2018-08-10 00:00 UTC by Michael Chapman
Modified: 2018-08-13 13:58 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2018-08-13 13:58:35 UTC


Attachments (Terms of Use)

Description Michael Chapman 2018-08-10 00:00:09 UTC
Jansson uses `strtoll` to parse integers, and it explicitly checks for integer overflow [1]. This can only parse signed long longs, but QEMU sometimes produces JSON containing 2^64-1.

    # virsh start example --paused
    Domain example started

    # virsh domstats example
    Domain: 'example'
      [... some stats, but no error ...]

    # virsh resume example
    error: Failed to resume domain example
    error: internal error: failed to parse JSON 1:59: too big integer near '18446744073709551615'

This wedges the monitor object completely, and no further operations on the VM are possible.

I'm not really sure of the best way of solving this. A standards-compliant JSON implementation need not support integers outside of the range of JavaScript's Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER [2], but QEMU is unfortunately relying on clients supporting full unsigned 64-bit integers.

(Although YAJL has the same kind of validation as Jansson, libvirt was avoiding the problem since it would register its own callback to parse numbers.)

[1] https://jansson.readthedocs.io/en/latest/conformance.html#numbers
[2] http://www.ecma-international.org/ecma-262/6.0/index.html#sec-number.max_safe_integer

Comment 1 Daniel Berrangé 2018-08-10 09:41:58 UTC
Looks like we are pretty doomed - Jansson devs have refused to support unsigned 64-bit ints  https://github.com/akheron/jansson/issues/154

AFAICT, there's no way to get the original value as a string in jansson either - it will always parse it :-(

Comment 2 Ján Tomko 2018-08-10 11:17:18 UTC
Sigh,

even if we extend the range and say goodbye to precision by using JSON_DECODE_INT_AS_REAL, it will not overflow to -1 which QEMU expects us to do here.

I believe this is solved by my earlier series 'Revert the switch to Jansson':
https://www.redhat.com/archives/libvir-list/2018-July/msg02106.html

Comment 3 Daniel Berrangé 2018-08-10 11:23:54 UTC
Yeah, I've looked at the source and there is no "get out of jail free" option here - the parser has no way to expose the number as a string like yajl did. 

This looks like a terminal problem with jansson with revert being only option :-(

c-json doesn't look any better in this respect either, also using strtoll

Comment 4 Richard W.M. Jones 2018-08-10 12:41:07 UTC
I pointed out years and years ago that JSON integers are fundamentally
undefined:

https://lists.gnu.org/archive/html/qemu-devel/2011-05/msg02437.html

Comment 5 Ján Tomko 2018-08-13 11:56:40 UTC
Revert of the Jansson switch:
https://www.redhat.com/archives/libvir-list/2018-August/msg00633.html

Comment 6 Ján Tomko 2018-08-13 13:58:35 UTC
Pushed as of:
commit 86db0db979c39df278f03dbf3b4239c873ddb637
Author:     Ján Tomko <jtomko@redhat.com>
CommitDate: 2018-08-13 15:50:01 +0200

    Revert "build: add --with-jansson"

git describe: v4.6.0-128-g86db0db979


Note You need to log in before you can comment on or make changes to this bug.