cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

112 (8324B)


      1#!/usr/bin/env bash
      2# group: rw
      3#
      4# Test cases for different refcount_bits values
      5#
      6# Copyright (C) 2015 Red Hat, Inc.
      7#
      8# This program is free software; you can redistribute it and/or modify
      9# it under the terms of the GNU General Public License as published by
     10# the Free Software Foundation; either version 2 of the License, or
     11# (at your option) any later version.
     12#
     13# This program is distributed in the hope that it will be useful,
     14# but WITHOUT ANY WARRANTY; without even the implied warranty of
     15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16# GNU General Public License for more details.
     17#
     18# You should have received a copy of the GNU General Public License
     19# along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20#
     21
     22# creator
     23owner=mreitz@redhat.com
     24
     25seq="$(basename $0)"
     26echo "QA output created by $seq"
     27
     28status=1	# failure is the default!
     29
     30_cleanup()
     31{
     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# This tests qcow2-specific low-level functionality
     41_supported_fmt qcow2
     42_supported_proto file fuse
     43# This test will set refcount_bits on its own which would conflict with the
     44# manual setting; compat will be overridden as well;
     45# and external data files do not work well with our refcount testing
     46_unsupported_imgopts refcount_bits 'compat=0.10' data_file
     47
     48print_refcount_bits()
     49{
     50    $QEMU_IMG info "$TEST_IMG" | sed -n '/refcount bits:/ s/^ *//p'
     51}
     52
     53echo
     54echo '=== refcount_bits limits ==='
     55echo
     56
     57# Must be positive (non-zero)
     58_make_test_img -o "refcount_bits=0" 64M
     59# Must be positive (non-negative)
     60_make_test_img -o "refcount_bits=-1" 64M
     61# May not exceed 64
     62_make_test_img -o "refcount_bits=128" 64M
     63# Must be a power of two
     64_make_test_img -o "refcount_bits=42" 64M
     65
     66# 1 is the minimum
     67_make_test_img -o "refcount_bits=1" 64M
     68print_refcount_bits
     69
     70# 64 is the maximum
     71_make_test_img -o "refcount_bits=64" 64M
     72print_refcount_bits
     73
     74# 16 is the default
     75_make_test_img 64M
     76print_refcount_bits
     77
     78echo
     79echo '=== refcount_bits and compat=0.10 ==='
     80echo
     81
     82# Should work
     83_make_test_img -o "compat=0.10,refcount_bits=16" 64M
     84print_refcount_bits
     85
     86# Should not work
     87_make_test_img -o "compat=0.10,refcount_bits=1" 64M
     88_make_test_img -o "compat=0.10,refcount_bits=64" 64M
     89
     90
     91echo
     92echo '=== Snapshot limit on refcount_bits=1 ==='
     93echo
     94
     95_make_test_img -o "refcount_bits=1" 64M
     96print_refcount_bits
     97
     98$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
     99
    100# Should fail for now; in the future, this might be supported by automatically
    101# copying all clusters with overflowing refcount
    102$QEMU_IMG snapshot -c foo "$TEST_IMG"
    103
    104# The new L1 table could/should be leaked
    105_check_test_img
    106
    107echo
    108echo '=== Snapshot limit on refcount_bits=2 ==='
    109echo
    110
    111_make_test_img -o "refcount_bits=2" 64M
    112print_refcount_bits
    113
    114$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
    115
    116# Should succeed
    117$QEMU_IMG snapshot -c foo "$TEST_IMG"
    118$QEMU_IMG snapshot -c bar "$TEST_IMG"
    119# Should fail (4th reference)
    120$QEMU_IMG snapshot -c baz "$TEST_IMG"
    121
    122# The new L1 table could/should be leaked
    123_check_test_img
    124
    125echo
    126echo '=== Compressed clusters with refcount_bits=1 ==='
    127echo
    128
    129_make_test_img -o "refcount_bits=1" 64M
    130print_refcount_bits
    131
    132# Both should fit into a single host cluster; instead of failing to increase the
    133# refcount of that cluster, qemu should just allocate a new cluster and make
    134# this operation succeed
    135$QEMU_IO -c 'write -P 0 -c  0  64k' \
    136         -c 'write -P 1 -c 64k 64k' \
    137         "$TEST_IMG" | _filter_qemu_io
    138
    139_check_test_img
    140
    141echo
    142echo '=== MSb set in 64 bit refcount ==='
    143echo
    144
    145_make_test_img -o "refcount_bits=64" 64M
    146print_refcount_bits
    147
    148$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
    149
    150# Set the MSb in the refblock entry of the data cluster
    151poke_file "$TEST_IMG" $((0x20028)) "\x80\x00\x00\x00\x00\x00\x00\x00"
    152
    153# Clear OFLAG_COPIED in the L2 entry of the data cluster
    154poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"
    155
    156# Try to write to that cluster (should work, even though the MSb is set)
    157$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
    158
    159echo
    160echo '=== Snapshot on maximum 64 bit refcount value ==='
    161echo
    162
    163_make_test_img -o "refcount_bits=64" 64M
    164print_refcount_bits
    165
    166$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
    167
    168# Set the refblock entry to the maximum value possible
    169poke_file "$TEST_IMG" $((0x20028)) "\xff\xff\xff\xff\xff\xff\xff\xff"
    170
    171# Clear OFLAG_COPIED in the L2 entry of the data cluster
    172poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"
    173
    174# Try a snapshot (should correctly identify the overflow; may work in the future
    175# by falling back to COW)
    176$QEMU_IMG snapshot -c foo "$TEST_IMG"
    177
    178# The new L1 table could/should be leaked; and obviously the data cluster is
    179# leaked (refcount=UINT64_MAX reference=1)
    180_check_test_img
    181
    182echo
    183echo '=== Amend from refcount_bits=16 to refcount_bits=1 ==='
    184echo
    185
    186_make_test_img 64M
    187print_refcount_bits
    188
    189$QEMU_IO -c 'write 16M 32M' "$TEST_IMG" | _filter_qemu_io
    190$QEMU_IMG amend -o refcount_bits=1 "$TEST_IMG"
    191_check_test_img
    192print_refcount_bits
    193
    194echo
    195echo '=== Amend from refcount_bits=1 to refcount_bits=64 ==='
    196echo
    197
    198$QEMU_IMG amend -o refcount_bits=64 "$TEST_IMG"
    199_check_test_img
    200print_refcount_bits
    201
    202echo
    203echo '=== Amend to compat=0.10 ==='
    204echo
    205
    206# Should not work because refcount_bits needs to be 16 for compat=0.10
    207$QEMU_IMG amend -o compat=0.10 "$TEST_IMG"
    208print_refcount_bits
    209# Should work
    210$QEMU_IMG amend -o compat=0.10,refcount_bits=16 "$TEST_IMG"
    211_check_test_img
    212print_refcount_bits
    213
    214# Get back to compat=1.1 and refcount_bits=16
    215$QEMU_IMG amend -o compat=1.1 "$TEST_IMG"
    216print_refcount_bits
    217# Should not work
    218$QEMU_IMG amend -o refcount_bits=32,compat=0.10 "$TEST_IMG"
    219print_refcount_bits
    220
    221echo
    222echo '=== Amend with snapshot ==='
    223echo
    224
    225$QEMU_IMG snapshot -c foo "$TEST_IMG"
    226# Just to have different refcounts across the image
    227$QEMU_IO -c 'write 0 16M' "$TEST_IMG" | _filter_qemu_io
    228
    229# Should not work (may work in the future by first decreasing all refcounts so
    230# they fit into the target range by copying them)
    231$QEMU_IMG amend -o refcount_bits=1 "$TEST_IMG"
    232_check_test_img
    233print_refcount_bits
    234
    235# Should work
    236$QEMU_IMG amend -o refcount_bits=2 "$TEST_IMG"
    237_check_test_img
    238print_refcount_bits
    239
    240echo
    241echo '=== Testing too many references for check ==='
    242echo
    243
    244_make_test_img -o "refcount_bits=1" 64M
    245print_refcount_bits
    246
    247# This cluster should be created at 0x50000
    248$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
    249# Now make the second L2 entry (the L2 table should be at 0x40000) point to that
    250# cluster, so we have two references
    251poke_file "$TEST_IMG" $((0x40008)) "\x80\x00\x00\x00\x00\x05\x00\x00"
    252
    253# This should say "please use amend"
    254_check_test_img -r all
    255
    256# So we do that
    257$QEMU_IMG amend -o refcount_bits=2 "$TEST_IMG"
    258print_refcount_bits
    259
    260# And try again
    261_check_test_img -r all
    262
    263echo
    264echo '=== Multiple walks necessary during amend ==='
    265echo
    266
    267_make_test_img -o "refcount_bits=1,cluster_size=512" 64k
    268
    269# Cluster 0 is the image header, clusters 1 to 4 are used by the L1 table, a
    270# single L2 table, the reftable and a single refblock. This creates 58 data
    271# clusters (actually, the L2 table is created here, too), so in total there are
    272# then 63 used clusters in the image. With a refcount width of 64, one refblock
    273# describes 64 clusters (512 bytes / 64 bits/entry = 64 entries), so this will
    274# make the first refblock in the amended image have exactly one free entry.
    275$QEMU_IO -c "write 0 $((58 * 512))" "$TEST_IMG" | _filter_qemu_io
    276
    277# Now change the refcount width; since the first new refblock will have exactly
    278# one free entry, that entry will be used to store its own reference. No other
    279# refblocks are needed, so then the new reftable will be allocated; since the
    280# first new refblock is completely filled up, this will require a new refblock
    281# which is why the refcount width changing function will need to run through
    282# everything one more time until the allocations are stable.
    283# Having more walks than usual should be visible as regressing progress (from
    284# 66.67 % (2/3 walks) to 50.00 % (2/4 walks)).
    285$QEMU_IMG amend -o refcount_bits=64 -p "$TEST_IMG" | tr '\r' '\n' \
    286                                                   | grep -A 1 '66.67'
    287print_refcount_bits
    288
    289_check_test_img
    290
    291
    292# success, all done
    293echo '*** done'
    294rm -f $seq.full
    295status=0