Bug 491943

Summary: qemu-img crashes creating 5TB qcow2 file
Product: [Fedora] Fedora Reporter: Daniel Berrangé <berrange>
Component: qemuAssignee: Glauber Costa <gcosta>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: rawhideCC: chrisw, dwmw2, gcosta, markmc, virt-maint
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-04-05 19:03:28 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
make enough refcount blocks for large (>2TB) images none

Description Daniel Berrangé 2009-03-24 18:43:20 UTC
Description of problem:
I wanted to create a stupidly large disk image for some testing purposes. qemu-img crashed & burned

$ qemu-img create -f qcow2 foo.cow 5000G
Formatting 'foo.cow', fmt=qcow2, size=5242880000 kB
Segmentation fault


If 5 T is beyond the allowed limits for qcow2 it should tell me upfront, otherwise it should not crash.

Version-Release number of selected component (if applicable):
qemu-0.10-0.9.kvm20090310git.fc11.x86_64

How reproducible:
Always

Steps to Reproduce:
1. qemu-img create -f qcow2 foo.cow 5000G
2.
3.
  
Actual results:
SEGV

Expected results:
File created, or error message given upfront.


Additional info:

Comment 1 Chris Wright 2009-03-24 18:54:09 UTC
Also...

No package qemu-img-debuginfo available.
$ rpm -ql qemu-debuginfo | grep img
$

Missing debug info.

$ gdb -q qemu-img
(no debugging symbols found)
(gdb) set args create -f qcow2 foo.cow 5000G
(gdb) run
Starting program: /usr/bin/qemu-img create -f qcow2 foo.cow 5000G
[Thread debugging using libthread_db enabled]
Formatting 'foo.cow', fmt=qcow2, size=5242880000 kB
[New Thread 0x7ffff7fdf6f0 (LWP 14932)]

Program received signal SIGSEGV, Segmentation fault.
0x00000031f2479e88 in _int_free (av=0x31f276da00, mem=0x620010)
    at malloc.c:4726
4726		unlink(nextchunk, bck, fwd);

Comment 2 Daniel Berrangé 2009-03-24 18:56:08 UTC
qemu-debugiunfo is missing the qemu-img binary so GDB can't resolve symbols :-(

Compiling from scratch gives this:

Program received signal SIGSEGV, Segmentation fault.
0x00000030bac77218 in _int_free () from /lib64/libc.so.6
(gdb) bt
#0  0x00000030bac77218 in _int_free () from /lib64/libc.so.6
#1  0x00000030bac79a4f in free () from /lib64/libc.so.6
#2  0x0000000000412823 in qcow_create (filename=<value optimized out>, total_size=<value optimized out>, backing_file=0x7fffffffe2f8 "", 
    flags=<value optimized out>) at block-qcow2.c:1542
#3  0x0000000000403ac8 in img_create (argv=<value optimized out>, argc=<value optimized out>) at qemu-img.c:289
#4  main (argv=<value optimized out>, argc=<value optimized out>) at qemu-img.c:870

Comment 3 Daniel Berrangé 2009-03-24 19:07:32 UTC
Looks like it is overflowing some arrays...


==22600== Invalid read of size 2
==22600==    at 0x417CD5: create_refcount_update (block-qcow2.c:1459)
==22600==    by 0x418028: qcow_create (block-qcow2.c:1522)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c29060 is 0 bytes after a block of size 4,096 alloc'd
==22600==    at 0x4A0763E: malloc (vg_replace_malloc.c:207)
==22600==    by 0x404DC2: qemu_malloc (qemu-malloc.c:46)
==22600==    by 0x404E2D: qemu_mallocz (qemu-malloc.c:60)
==22600==    by 0x417F7F: qcow_create (block-qcow2.c:1509)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600== 
==22600== Invalid write of size 2
==22600==    at 0x417CFD: create_refcount_update (block-qcow2.c:1461)
==22600==    by 0x418028: qcow_create (block-qcow2.c:1522)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c29060 is 0 bytes after a block of size 4,096 alloc'd
==22600==    at 0x4A0763E: malloc (vg_replace_malloc.c:207)
==22600==    by 0x404DC2: qemu_malloc (qemu-malloc.c:46)
==22600==    by 0x404E2D: qemu_mallocz (qemu-malloc.c:60)
==22600==    by 0x417F7F: qcow_create (block-qcow2.c:1509)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600== 
==22600== Invalid read of size 2
==22600==    at 0x417CD5: create_refcount_update (block-qcow2.c:1459)
==22600==    by 0x418048: qcow_create (block-qcow2.c:1523)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c2a772 is not stack'd, malloc'd or (recently) free'd
==22600== 
==22600== Invalid write of size 2
==22600==    at 0x417CFD: create_refcount_update (block-qcow2.c:1461)
==22600==    by 0x418048: qcow_create (block-qcow2.c:1523)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c2a772 is not stack'd, malloc'd or (recently) free'd
==22600== 
==22600== Invalid read of size 2
==22600==    at 0x417CD5: create_refcount_update (block-qcow2.c:1459)
==22600==    by 0x418068: qcow_create (block-qcow2.c:1524)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c2a774 is not stack'd, malloc'd or (recently) free'd
==22600== 
==22600== Invalid write of size 2
==22600==    at 0x417CFD: create_refcount_update (block-qcow2.c:1461)
==22600==    by 0x418068: qcow_create (block-qcow2.c:1524)
==22600==    by 0x41C8B1: bdrv_create (block.c:182)
==22600==    by 0x402E4B: img_create (qemu-img.c:289)
==22600==    by 0x4042E5: main (qemu-img.c:870)
==22600==  Address 0x4c2a774 is not stack'd, malloc'd or (recently) free'd

Comment 4 Mark McLoughlin 2009-03-25 09:44:56 UTC
Filed the debuginfo issue as bug #492075

Comment 5 Chris Wright 2009-03-26 01:10:58 UTC
Created attachment 336733 [details]
make enough refcount blocks for large (>2TB) images

We are overflowing the refcount_block[] array.  Simply make sure we allocate enough refcount blocks on image creation.

Comment 6 Glauber Costa 2009-03-28 15:06:08 UTC
Chris, did you send this patch upstream?

Please not that gcc issues a warning at this line:

ref_clusters = (tmp >> s->cluster_bits - REFCOUNT_SHIFT) + 1;

Comment 7 Chris Wright 2009-04-03 21:21:30 UTC
Was just waiting for an ACK that it worked as a guest image since I had only
verified that create and info worked properly.  Thanks for testing, I'll send it now (yes, saw the gcc warning and fixed it).