Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qemu-io crashes with SIGABRT and Assertion `c->entries[i].offset != 0' failed #25

Closed
nasastry opened this issue Oct 30, 2017 · 4 comments

Comments

@nasastry
Copy link

nasastry commented Oct 30, 2017

cde:info Mirrored with LTC bug https://bugzilla.linux.ibm.com/show_bug.cgi?id=160749 </cde:info>

Re-production steps:

  1. Copy the attached files named backing_img.file.txt and test.img.txt to a directory
  2. Rename them as
mv backing_img.file.txt backing_img.file
mv test.img.txt test.img

P.S. with filename extension as .file and .img, they are not getting attached here to changed to .txt.
3. And customize the following command to point to the above directory and run the same.
/usr/bin/qemu-io <path to>/test.img -c "write 1352192 1707520"
Output of the above command.

qemu-io: block/qcow2-cache.c:411: qcow2_cache_entry_mark_dirty: Assertion `c->entries[i].offset != 0' failed.
Aborted (core dumped)

from gdb:

(gdb) bt
#0  0x00007fff9d29eff0 in raise () from /lib64/libc.so.6
#1  0x00007fff9d2a136c in abort () from /lib64/libc.so.6
#2  0x00007fff9d294c44 in __assert_fail_base () from /lib64/libc.so.6
#3  0x00007fff9d294d34 in __assert_fail () from /lib64/libc.so.6
#4  0x000000013f520ca8 in qcow2_cache_entry_mark_dirty (bs=<optimized out>, c=<optimized out>, table=<optimized out>) at block/qcow2-cache.c:411
#5  0x000000013f5161a0 in alloc_refcount_block (refcount_block=0x7fff9996f798, cluster_index=2, bs=0x153a8e7a0) at block/qcow2-refcount.c:416
#6  update_refcount (bs=0x153a8e7a0, offset=1048576, length=<optimized out>, addend=1, decrease=false, type=QCOW2_DISCARD_NEVER) at block/qcow2-refcount.c:833
#7  0x000000013f516b90 in qcow2_alloc_clusters_at (bs=0x153a8e7a0, offset=1048576, nb_clusters=1) at block/qcow2-refcount.c:1015
#8  0x000000013f51cda4 in do_alloc_cluster_offset (nb_clusters=<synthetic pointer>, host_offset=<synthetic pointer>, guest_offset=2097152, bs=0x153a8e7a0)
    at block/qcow2-cluster.c:1173
#9  handle_alloc (m=<optimized out>, bytes=<synthetic pointer>, host_offset=<synthetic pointer>, guest_offset=2097152, bs=0x153a8e7a0)
    at block/qcow2-cluster.c:1276
#10 qcow2_alloc_cluster_offset (bs=0x153a8e7a0, offset=1572864, bytes=0x7fff9996faac, host_offset=0x7fff9996fab0, m=0x7fff9996fab8)
    at block/qcow2-cluster.c:1463
#11 0x000000013f50d588 in qcow2_co_pwritev (bs=0x153a8e7a0, offset=1572864, bytes=1486848, qiov=0x7fffea17ab20, flags=<optimized out>) at block/qcow2.c:1933
#12 0x000000013f54ac20 in bdrv_driver_pwritev (bs=<optimized out>, offset=<optimized out>, bytes=<optimized out>, qiov=<optimized out>, flags=16)
    at block/io.c:877
#13 0x000000013f54c580 in bdrv_aligned_pwritev (req=0x7fff9996fd48, offset=1352192, bytes=1707520, align=1, qiov=0x7fffea17ab20, flags=<optimized out>,
    child=0x153a9ff20, child=0x153a9ff20) at block/io.c:1382
#14 0x000000013f54d46c in bdrv_co_pwritev (child=0x153a9ff20, offset=1352192, bytes=<optimized out>, qiov=0x7fffea17ab20, flags=<optimized out>)
    at block/io.c:1633
#15 0x000000013f537808 in blk_co_pwritev (blk=0x153a7e4a0, offset=1352192, bytes=<optimized out>, qiov=0x7fffea17ab20, flags=BDRV_REQ_FUA)
    at block/block-backend.c:1083
#16 0x000000013f537944 in blk_write_entry (opaque=0x7fffea17ab38) at block/block-backend.c:1108
#17 0x000000013f60bc38 in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at util/coroutine-ucontext.c:79
#18 0x00007fff9d2b2b9c in makecontext () from /lib64/libc.so.6
#19 0x0000000000000000 in ?? ()
(gdb) bt full
#0  0x00007fff9d29eff0 in raise () from /lib64/libc.so.6
No symbol table info available.
#1  0x00007fff9d2a136c in abort () from /lib64/libc.so.6
No symbol table info available.
#2  0x00007fff9d294c44 in __assert_fail_base () from /lib64/libc.so.6
No symbol table info available.
#3  0x00007fff9d294d34 in __assert_fail () from /lib64/libc.so.6
No symbol table info available.
#4  0x000000013f520ca8 in qcow2_cache_entry_mark_dirty (bs=<optimized out>, c=<optimized out>, table=<optimized out>) at block/qcow2-cache.c:411
        i = <optimized out>
        __PRETTY_FUNCTION__ = "qcow2_cache_entry_mark_dirty"
#5  0x000000013f5161a0 in alloc_refcount_block (refcount_block=0x7fff9996f798, cluster_index=2, bs=0x153a8e7a0) at block/qcow2-refcount.c:416
        s = 0x153a9aa90
        refcount_table_index = 0
        ret = 0
        meta_offset = <optimized out>
        new_block = 0
        blocks_used = <optimized out>
#6  update_refcount (bs=0x153a8e7a0, offset=1048576, length=<optimized out>, addend=1, decrease=false, type=QCOW2_DISCARD_NEVER) at block/qcow2-refcount.c:833
        block_index = <optimized out>
        refcount = <optimized out>
        cluster_index = 2
        table_index = 0
        s = 0x153a9aa90
        start = <optimized out>
        last = 1048576
        cluster_offset = 1048576
        refcount_block = 0x7fff9af20000
        old_table_index = <optimized out>
        ret = <optimized out>
#7  0x000000013f516b90 in qcow2_alloc_clusters_at (bs=0x153a8e7a0, offset=1048576, nb_clusters=1) at block/qcow2-refcount.c:1015
        s = 0x153a9aa90
        cluster_index = <optimized out>
        refcount = 0
        i = 1
        ret = <optimized out>
        __PRETTY_FUNCTION__ = "qcow2_alloc_clusters_at"
#8  0x000000013f51cda4 in do_alloc_cluster_offset (nb_clusters=<synthetic pointer>, host_offset=<synthetic pointer>, guest_offset=2097152, bs=0x153a8e7a0)
    at block/qcow2-cluster.c:1173
        ret = <optimized out>
        s = 0x153a9aa90
#9  handle_alloc (m=<optimized out>, bytes=<synthetic pointer>, host_offset=<synthetic pointer>, guest_offset=2097152, bs=0x153a8e7a0)
    at block/qcow2-cluster.c:1276
        l2_index = 4
        keep_old_clusters = false
        requested_bytes = <optimized out>
        avail_bytes = <optimized out>
        nb_bytes = <optimized out>
        entry = <optimized out>
        ret = <optimized out>
---Type <return> to continue, or q <return> to quit---
        old_m = <optimized out>
        s = 0x153a9aa90
        l2_table = 0x0
        nb_clusters = 1
        alloc_cluster_offset = 1048576
#10 qcow2_alloc_cluster_offset (bs=0x153a8e7a0, offset=1572864, bytes=0x7fff9996faac, host_offset=0x7fff9996fab0, m=0x7fff9996fab8)
    at block/qcow2-cluster.c:1463
        s = 0x153a9aa90
        start = 2097152
        remaining = <optimized out>
        cluster_offset = <optimized out>
        cur_bytes = 962560
        __PRETTY_FUNCTION__ = "qcow2_alloc_cluster_offset"
#11 0x000000013f50d588 in qcow2_co_pwritev (bs=0x153a8e7a0, offset=1572864, bytes=1486848, qiov=0x7fffea17ab20, flags=<optimized out>) at block/qcow2.c:1933
        s = 0x153a9aa90
        offset_in_cluster = 0
        ret = <optimized out>
        cur_bytes = 1486848
        cluster_offset = 524288
        hd_qiov = {iov = 0x153a57d50, niov = 1, nalloc = 1, size = 220672}
        bytes_done = 220672
        cluster_data = 0x0
        l2meta = 0x0
        __PRETTY_FUNCTION__ = "qcow2_co_pwritev"
#12 0x000000013f54ac20 in bdrv_driver_pwritev (bs=<optimized out>, offset=<optimized out>, bytes=<optimized out>, qiov=<optimized out>, flags=16)
    at block/io.c:877
        drv = <optimized out>
        sector_num = <optimized out>
        nb_sectors = <optimized out>
        ret = <optimized out>
        __PRETTY_FUNCTION__ = "bdrv_driver_pwritev"
#13 0x000000013f54c580 in bdrv_aligned_pwritev (req=0x7fff9996fd48, offset=1352192, bytes=1707520, align=1, qiov=0x7fffea17ab20, flags=<optimized out>,
    child=0x153a9ff20, child=0x153a9ff20) at block/io.c:1382
        bs = 0x153a8e7a0
        drv = 0x13f692a10 <bdrv_qcow2>
        waited = <optimized out>
        ret = <optimized out>
        start_sector = 2641
        end_sector = 5976
        bytes_remaining = 1707520
        max_transfer = <optimized out>
#14 0x000000013f54d46c in bdrv_co_pwritev (child=0x153a9ff20, offset=1352192, bytes=<optimized out>, qiov=0x7fffea17ab20, flags=<optimized out>)
    at block/io.c:1633
        bs = 0x153a8e7a0
        req = {bs = 0x153a8e7a0, offset = 1352192, bytes = 1707520, type = BDRV_TRACKED_WRITE, serialising = false, overlap_offset = 1352192,
          overlap_bytes = 1707520, list = {le_next = 0x0, le_prev = 0x153a91a18}, co = 0x153a9f6b0, wait_queue = {entries = {sqh_first = 0x0,
              sqh_last = 0x7fff9996fd90}}, waiting_for = 0x0}
        align = 1
        head_buf = 0x0
        tail_buf = <optimized out>
---Type <return> to continue, or q <return> to quit---
        local_qiov = {iov = 0x0, niov = 1062110004, nalloc = 1, size = 0}
        use_local_qiov = <optimized out>
        ret = <optimized out>
        __PRETTY_FUNCTION__ = "bdrv_co_pwritev"
#15 0x000000013f537808 in blk_co_pwritev (blk=0x153a7e4a0, offset=1352192, bytes=<optimized out>, qiov=0x7fffea17ab20, flags=BDRV_REQ_FUA)
    at block/block-backend.c:1083
        ret = <optimized out>
        bs = 0x153a8e7a0
#16 0x000000013f537944 in blk_write_entry (opaque=0x7fffea17ab38) at block/block-backend.c:1108
        rwco = 0x7fffea17ab38
#17 0x000000013f60bc38 in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at util/coroutine-ucontext.c:79
        arg = {p = 0x153a9f6b0, i = {1403647664, 1}}
        self = 0x153a9f6b0
        co = 0x153a9f6b0
#18 0x00007fff9d2b2b9c in makecontext () from /lib64/libc.so.6
No symbol table info available.
#19 0x0000000000000000 in ?? ()
No symbol table info available.

Qemu version:
qemu-2.10.0-2.rel.gitc334a4e.el7.centos.ppc64le

Will attach the required image files.
backing_img.file.txt
test.img.txt

@nasastry
Copy link
Author

These image files created by tests/image_fuzzer code from qemu source tree.

@cdeadmin
Copy link

------- Comment From muriloo@br.ibm.com 2017-12-27 07:51:15 EDT-------
I can't reproduce this bug with HostOS QEMU 2.11.0 (commit e7153e0) from
branch hostos-release. The qemu-io program terminates gracefully:

$ ./qemu-io test.img -c &quot;write 1352192 1707520&quot;
can't open device test.img: Image does not contain a reference count table

Apparently, this was fixed by:

commit 951053a9ec1c47edf4b2549ef58d82aee8a42a7f
Author: Alberto Garcia &lt;berto@igalia.com&gt;
Date:   Fri Nov 3 16:18:53 2017 +0200

    qcow2: Don't open images with header.refcount_table_clusters == 0

This commit checks whether .refcount_table_clusters of the image is equal to 0,
terminating the program. So the program terminates before
qcow2_cache_entry_mark_dirty() is called and tries to
assert(c->entries[i].offset != 0), which caused the segfault reported here:

Thread 1 &quot;qemu-io&quot; hit Breakpoint 1, qcow2_cache_entry_mark_dirty (bs=0x10680ee0, c=0x10662350, table=0x7ffff5f70000) at /home/muriloo/hostos/qemu/block/qcow2-cache.c:410
410	    int i = qcow2_cache_get_table_idx(bs, c, table);
(gdb) n
411	    assert(c-&gt;entries[i].offset != 0);
(gdb) p i
$1 = 0
(gdb) p c-&gt;entries[i].offset != 0
$2 = 0
(gdb) n
qemu-io: /home/muriloo/hostos/qemu/block/qcow2-cache.c:411: qcow2_cache_entry_mark_dirty: Assertion `c-&gt;entries[i].offset != 0' failed.

Thread 1 &quot;qemu-io&quot; received signal SIGABRT, Aborted.
0x00007ffff79b91d8 in raise () from /lib64/libc.so.6

The commit 951053a is present in both hostos-devel and -release branches.

Cheers
Murilo

@cdeadmin
Copy link

------- Comment From muriloo@br.ibm.com 2017-12-27 14:13:03 EDT-------
The actual commit that fixes this issue is:

https://git.qemu.org/?p=qemu.git;a=commitdiff;h=6bf45d59f98c898b7d79

commit 6bf45d5
Author: Alberto Garcia <berto@igalia.com>
Date: Fri Nov 3 16:18:50 2017 +0200

qcow2: Prevent allocating refcount blocks at offset 0

@cdeadmin cdeadmin closed this as completed Jan 1, 2018
@cdeadmin
Copy link

cdeadmin commented Jan 1, 2018

------- Comment From nasastry@in.ibm.com 2018-01-01 01:02:56 EDT-------
Tested with qemu-img-2.11.0-1.rel.gite7153e0.el7.centos.ppc64le

/usr/bin/qemu-io /tmp/test.img -c "write 1352192 1707520"

can't open device /tmp/test.img: Image does not contain a reference count table

/usr/bin/qemu-io --version

qemu-io version 2.11.0
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

Reported segfault not seen. This bugzilla can be closed.

aik pushed a commit that referenced this issue Jan 31, 2018
Direct leak of 160 byte(s) in 4 object(s) allocated from:
    #0 0x55ed7678cda8 in calloc (/home/elmarco/src/qq/build/x86_64-softmmu/qemu-system-x86_64+0x797da8)
    #1 0x7f3f5e725f75 in g_malloc0 /home/elmarco/src/gnome/glib/builddir/../glib/gmem.c:124
    #2 0x55ed778aa3a7 in query_option_descs /home/elmarco/src/qq/util/qemu-config.c:60:16
    #3 0x55ed778aa307 in get_drive_infolist /home/elmarco/src/qq/util/qemu-config.c:140:19
    #4 0x55ed778a9f40 in qmp_query_command_line_options /home/elmarco/src/qq/util/qemu-config.c:254:36
    #5 0x55ed76d4868c in qmp_marshal_query_command_line_options /home/elmarco/src/qq/build/qmp-marshal.c:3078:14
    #6 0x55ed77855dd5 in do_qmp_dispatch /home/elmarco/src/qq/qapi/qmp-dispatch.c:104:5
    #7 0x55ed778558cc in qmp_dispatch /home/elmarco/src/qq/qapi/qmp-dispatch.c:131:11
    #8 0x55ed768b592f in handle_qmp_command /home/elmarco/src/qq/monitor.c:3840:11
    #9 0x55ed7786ccfe in json_message_process_token /home/elmarco/src/qq/qobject/json-streamer.c:105:5
    #10 0x55ed778fe37c in json_lexer_feed_char /home/elmarco/src/qq/qobject/json-lexer.c:323:13
    #11 0x55ed778fdde6 in json_lexer_feed /home/elmarco/src/qq/qobject/json-lexer.c:373:15
    #12 0x55ed7786cd83 in json_message_parser_feed /home/elmarco/src/qq/qobject/json-streamer.c:124:12
    #13 0x55ed768b559e in monitor_qmp_read /home/elmarco/src/qq/monitor.c:3882:5
    #14 0x55ed77714f29 in qemu_chr_be_write_impl /home/elmarco/src/qq/chardev/char.c:167:9
    #15 0x55ed77714fde in qemu_chr_be_write /home/elmarco/src/qq/chardev/char.c:179:9
    #16 0x55ed7772ffad in tcp_chr_read /home/elmarco/src/qq/chardev/char-socket.c:440:13
    #17 0x55ed7777113b in qio_channel_fd_source_dispatch /home/elmarco/src/qq/io/channel-watch.c:84:12
    #18 0x7f3f5e71d90b in g_main_dispatch /home/elmarco/src/gnome/glib/builddir/../glib/gmain.c:3182
    #19 0x7f3f5e71e7ac in g_main_context_dispatch /home/elmarco/src/gnome/glib/builddir/../glib/gmain.c:3847
    #20 0x55ed77886ffc in glib_pollfds_poll /home/elmarco/src/qq/util/main-loop.c:214:9
    #21 0x55ed778865fd in os_host_main_loop_wait /home/elmarco/src/qq/util/main-loop.c:261:5
    #22 0x55ed77886222 in main_loop_wait /home/elmarco/src/qq/util/main-loop.c:515:11
    #23 0x55ed76d2a4df in main_loop /home/elmarco/src/qq/vl.c:1995:9
    #24 0x55ed76d1cb4a in main /home/elmarco/src/qq/vl.c:4914:5
    #25 0x7f3f555f6039 in __libc_start_main (/lib64/libc.so.6+0x21039)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180104160523.22995-14-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
aik pushed a commit that referenced this issue Jan 31, 2018
Spotted thanks to ASAN:

==25226==ERROR: AddressSanitizer: global-buffer-overflow on address 0x556715a1f120 at pc 0x556714b6f6b1 bp 0x7ffcdfac1360 sp 0x7ffcdfac1350
READ of size 1 at 0x556715a1f120 thread T0
    #0 0x556714b6f6b0 in init_disasm /home/elmarco/src/qemu/disas/s390.c:219
    #1 0x556714b6fa6a in print_insn_s390 /home/elmarco/src/qemu/disas/s390.c:294
    #2 0x55671484d031 in monitor_disas /home/elmarco/src/qemu/disas.c:635
    #3 0x556714862ec0 in memory_dump /home/elmarco/src/qemu/monitor.c:1324
    #4 0x55671486342a in hmp_memory_dump /home/elmarco/src/qemu/monitor.c:1418
    #5 0x5567148670be in handle_hmp_command /home/elmarco/src/qemu/monitor.c:3109
    #6 0x5567148674ed in qmp_human_monitor_command /home/elmarco/src/qemu/monitor.c:613
    #7 0x556714b00918 in qmp_marshal_human_monitor_command /home/elmarco/src/qemu/build/qmp-marshal.c:1704
    #8 0x556715138a3e in do_qmp_dispatch /home/elmarco/src/qemu/qapi/qmp-dispatch.c:104
    #9 0x556715138f83 in qmp_dispatch /home/elmarco/src/qemu/qapi/qmp-dispatch.c:131
    #10 0x55671485cf88 in handle_qmp_command /home/elmarco/src/qemu/monitor.c:3839
    #11 0x55671514e80b in json_message_process_token /home/elmarco/src/qemu/qobject/json-streamer.c:105
    #12 0x5567151bf2dc in json_lexer_feed_char /home/elmarco/src/qemu/qobject/json-lexer.c:323
    #13 0x5567151bf827 in json_lexer_feed /home/elmarco/src/qemu/qobject/json-lexer.c:373
    #14 0x55671514ee62 in json_message_parser_feed /home/elmarco/src/qemu/qobject/json-streamer.c:124
    #15 0x556714854b1f in monitor_qmp_read /home/elmarco/src/qemu/monitor.c:3881
    #16 0x556715045440 in qemu_chr_be_write_impl /home/elmarco/src/qemu/chardev/char.c:172
    #17 0x556715047184 in qemu_chr_be_write /home/elmarco/src/qemu/chardev/char.c:184
    #18 0x55671505a8e6 in tcp_chr_read /home/elmarco/src/qemu/chardev/char-socket.c:440
    #19 0x5567150943c3 in qio_channel_fd_source_dispatch /home/elmarco/src/qemu/io/channel-watch.c:84
    #20 0x7fb90292b90b in g_main_dispatch ../glib/gmain.c:3182
    #21 0x7fb90292c7ac in g_main_context_dispatch ../glib/gmain.c:3847
    #22 0x556715162eca in glib_pollfds_poll /home/elmarco/src/qemu/util/main-loop.c:214
    #23 0x556715163001 in os_host_main_loop_wait /home/elmarco/src/qemu/util/main-loop.c:261
    #24 0x5567151631fa in main_loop_wait /home/elmarco/src/qemu/util/main-loop.c:515
    #25 0x556714ad6d3b in main_loop /home/elmarco/src/qemu/vl.c:1950
    #26 0x556714ade329 in main /home/elmarco/src/qemu/vl.c:4865
    #27 0x7fb8fe5c9009 in __libc_start_main (/lib64/libc.so.6+0x21009)
    #28 0x5567147af4d9 in _start (/home/elmarco/src/qemu/build/s390x-softmmu/qemu-system-s390x+0xf674d9)

0x556715a1f120 is located 32 bytes to the left of global variable 'char_hci_type_info' defined in '/home/elmarco/src/qemu/hw/bt/hci-csr.c:493:23' (0x556715a1f140) of size 104
0x556715a1f120 is located 8 bytes to the right of global variable 's390_opcodes' defined in '/home/elmarco/src/qemu/disas/s390.c:860:33' (0x556715a15280) of size 40600

This fix is based on Andreas Arnez <arnez@linux.vnet.ibm.com> upstream
commit:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=9ace48f3d7d80ce09c5df60cccb433470410b11b

2014-08-19  Andreas Arnez  <arnez@linux.vnet.ibm.com>

       * s390-dis.c (init_disasm): Simplify initialization of
       opc_index[].  This also fixes an access after the last element
       of s390_opcodes[].

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20180104160523.22995-19-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants