qcow2: Validate snapshot table offset/size (CVE-2014-0144)

This avoid unbounded memory allocation and fixes a potential buffer
overflow on 32 bit hosts.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Kevin Wolf 2014-03-26 13:05:45 +01:00 committed by Stefan Hajnoczi
parent 8c7de28305
commit ce48f2f441
5 changed files with 91 additions and 26 deletions

View file

@ -47,6 +47,8 @@ header_size=104
offset_backing_file_offset=8
offset_refcount_table_offset=48
offset_refcount_table_clusters=56
offset_nb_snapshots=60
offset_snapshots_offset=64
offset_header_size=100
offset_ext_magic=$header_size
offset_ext_size=$((header_size + 4))
@ -90,6 +92,31 @@ poke_file "$TEST_IMG" "$offset_refcount_table_offset" "\xff\xff\xff\xff\xff\xff\
poke_file "$TEST_IMG" "$offset_refcount_table_clusters" "\x00\x00\x00\x7f"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Invalid snapshot table =="
_make_test_img 64M
poke_file "$TEST_IMG" "$offset_nb_snapshots" "\xff\xff\xff\xff"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x7f\xff\xff\xff"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_snapshots_offset" "\xff\xff\xff\xff\xff\xff\x00\x00"
poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x00\xff\xff"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_snapshots_offset" "\x12\x34\x56\x78\x90\xab\xcd\xef"
poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x00\x00\x00"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
echo
echo "== Hitting snapshot table size limit =="
_make_test_img 64M
# Put the refcount table in a more or less safe place (16 MB)
poke_file "$TEST_IMG" "$offset_snapshots_offset" "\x00\x00\x00\x00\x01\x00\x00\x00"
poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x01\x00\x00"
{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_testdir
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
# success, all done
echo "*** done"
rm -f $seq.full

View file

@ -30,4 +30,21 @@ no file open, try 'help open'
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid reference count table offset
no file open, try 'help open'
== Invalid snapshot table ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Too many snapshots
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Too many snapshots
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset
no file open, try 'help open'
== Hitting snapshot table size limit ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: Could not create snapshot 'test': -27 (File too large)
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done