1#!/bin/bash 2# 3# qcow2 format input validation tests 4# 5# Copyright (C) 2013 Red Hat, Inc. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20 21# creator 22owner=kwolf@redhat.com 23 24seq=`basename $0` 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 rm -f $TEST_IMG.snap 32 _cleanup_test_img 33} 34trap "_cleanup; exit \$status" 0 1 2 3 15 35 36# get standard environment, filters and checks 37. ./common.rc 38. ./common.filter 39 40_supported_fmt qcow2 41_supported_proto file 42_supported_os Linux 43# - Internal snapshots are (currently) impossible with refcount_bits=1 44# - This is generally a test for compat=1.1 images 45_unsupported_imgopts 'refcount_bits=1[^0-9]' 'compat=0.10' 46 47header_size=104 48 49offset_backing_file_offset=8 50offset_backing_file_size=16 51offset_l1_size=36 52offset_l1_table_offset=40 53offset_refcount_table_offset=48 54offset_refcount_table_clusters=56 55offset_nb_snapshots=60 56offset_snapshots_offset=64 57offset_header_size=100 58offset_ext_magic=$header_size 59offset_ext_size=$((header_size + 4)) 60 61offset_l2_table_0=$((0x40000)) 62 63offset_snap1=$((0x70000)) 64offset_snap1_l1_offset=$((offset_snap1 + 0)) 65offset_snap1_l1_size=$((offset_snap1 + 8)) 66 67echo 68echo "== Huge header size ==" 69_make_test_img 64M 70poke_file "$TEST_IMG" "$offset_header_size" "\xff\xff\xff\xff" 71{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 72poke_file "$TEST_IMG" "$offset_header_size" "\x7f\xff\xff\xff" 73{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 74 75echo 76echo "== Huge unknown header extension ==" 77_make_test_img 64M 78poke_file "$TEST_IMG" "$offset_backing_file_offset" "\xff\xff\xff\xff\xff\xff\xff\xff" 79poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78" 80poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff" 81{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 82poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x$(printf %x $offset_ext_size)" 83{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 84poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00" 85{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 86 87echo 88echo "== Huge refcount table size ==" 89_make_test_img 64M 90poke_file "$TEST_IMG" "$offset_refcount_table_clusters" "\xff\xff\xff\xff" 91{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 92poke_file "$TEST_IMG" "$offset_refcount_table_clusters" "\x00\x02\x00\x01" 93{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 94 95echo 96echo "== Misaligned refcount table ==" 97_make_test_img 64M 98poke_file "$TEST_IMG" "$offset_refcount_table_offset" "\x12\x34\x56\x78\x90\xab\xcd\xef" 99{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 100 101echo 102echo "== Huge refcount offset ==" 103_make_test_img 64M 104poke_file "$TEST_IMG" "$offset_refcount_table_offset" "\xff\xff\xff\xff\xff\xff\x00\x00" 105poke_file "$TEST_IMG" "$offset_refcount_table_clusters" "\x00\x00\x00\x7f" 106{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 107 108echo 109echo "== Invalid snapshot table ==" 110_make_test_img 64M 111poke_file "$TEST_IMG" "$offset_nb_snapshots" "\xff\xff\xff\xff" 112{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 113poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x7f\xff\xff\xff" 114{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 115 116poke_file "$TEST_IMG" "$offset_snapshots_offset" "\xff\xff\xff\xff\xff\xff\x00\x00" 117poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x00\xff\xff" 118{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 119 120poke_file "$TEST_IMG" "$offset_snapshots_offset" "\x12\x34\x56\x78\x90\xab\xcd\xef" 121poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x00\x00\x00" 122{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 123 124echo 125echo "== Hitting snapshot table size limit ==" 126_make_test_img 64M 127# Put the refcount table in a more or less safe place (16 MB) 128poke_file "$TEST_IMG" "$offset_snapshots_offset" "\x00\x00\x00\x00\x01\x00\x00\x00" 129poke_file "$TEST_IMG" "$offset_nb_snapshots" "\x00\x01\x00\x00" 130{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_testdir 131{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 132 133echo 134echo "== Invalid L1 table ==" 135_make_test_img 64M 136poke_file "$TEST_IMG" "$offset_l1_size" "\xff\xff\xff\xff" 137{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 138poke_file "$TEST_IMG" "$offset_l1_size" "\x7f\xff\xff\xff" 139{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 140 141poke_file "$TEST_IMG" "$offset_l1_table_offset" "\x7f\xff\xff\xff\xff\xff\x00\x00" 142poke_file "$TEST_IMG" "$offset_l1_size" "\x00\x00\xff\xff" 143{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 144 145poke_file "$TEST_IMG" "$offset_l1_table_offset" "\x12\x34\x56\x78\x90\xab\xcd\xef" 146poke_file "$TEST_IMG" "$offset_l1_size" "\x00\x00\x00\x01" 147{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 148 149echo 150echo "== Invalid L1 table (with internal snapshot in the image) ==" 151_make_test_img 64M 152{ $QEMU_IMG snapshot -c foo $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 153poke_file "$TEST_IMG" "$offset_l1_size" "\x00\x00\x00\x00" 154_img_info 155 156echo 157echo "== Invalid backing file size ==" 158_make_test_img 64M 159poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x10\x00" 160poke_file "$TEST_IMG" "$offset_backing_file_size" "\xff\xff\xff\xff" 161{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 162 163echo 164echo "== Invalid L2 entry (huge physical offset) ==" 165_make_test_img 64M 166{ $QEMU_IO -c "write 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 167poke_file "$TEST_IMG" "$offset_l2_table_0" "\xbf\xff\xff\xff\xff\xff\x00\x00" 168{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 169poke_file "$TEST_IMG" "$offset_l2_table_0" "\x80\x00\x00\xff\xff\xff\x00\x00" 170{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 171 172echo 173echo "== Invalid snapshot L1 table offset ==" 174_make_test_img 64M 175{ $QEMU_IO -c "write 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 176{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_testdir 177poke_file "$TEST_IMG" "$offset_snap1_l1_offset" "\x00\x00\x00\x00\x00\x40\x02\x00" 178{ $QEMU_IMG convert -l test $TEST_IMG $TEST_IMG.snap; } 2>&1 | _filter_testdir 179{ $QEMU_IMG amend -o compat=0.10 $TEST_IMG; } 2>&1 | _filter_testdir 180{ $QEMU_IO -c "open -o overlap-check.inactive-l2=on $TEST_IMG" \ 181 -c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir 182{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir 183{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir 184_check_test_img 185 186echo 187echo "== Invalid snapshot L1 table size ==" 188_make_test_img 64M 189{ $QEMU_IO -c "write 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir 190{ $QEMU_IMG snapshot -c test $TEST_IMG; } 2>&1 | _filter_testdir 191poke_file "$TEST_IMG" "$offset_snap1_l1_size" "\x10\x00\x00\x00" 192{ $QEMU_IMG convert -l test $TEST_IMG $TEST_IMG.snap; } 2>&1 | _filter_testdir 193{ $QEMU_IMG amend -o compat=0.10 $TEST_IMG; } 2>&1 | _filter_testdir 194{ $QEMU_IO -c "open -o overlap-check.inactive-l2=on $TEST_IMG" \ 195 -c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir 196{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir 197{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir 198_check_test_img 199 200# success, all done 201echo "*** done" 202rm -f $seq.full 203status=0 204