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 27here=`pwd` 28status=1 # failure is the default! 29 30_cleanup() 31{ 32 rm -f $TEST_IMG.snap 33 _cleanup_test_img 34} 35trap "_cleanup; exit \$status" 0 1 2 3 15 36 37# get standard environment, filters and checks 38. ./common.rc 39. ./common.filter 40 41_supported_fmt qcow2 42_supported_proto file 43_supported_os Linux 44# Internal snapshots are (currently) impossible with refcount_bits=1 45_unsupported_imgopts 'refcount_bits=1[^0-9]' 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 ==" 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_size" "\x10\x00\x00\x00" 178{ $QEMU_IMG convert -s test $TEST_IMG $TEST_IMG.snap; } 2>&1 | _filter_testdir 179 180# success, all done 181echo "*** done" 182rm -f $seq.full 183status=0 184