1# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import os 7import struct 8from autotest_lib.client.common_lib import error, utils 9from autotest_lib.client.cros import verity_utils 10 11class platform_DMVerityBitCorruption(verity_utils.VerityImageTest): 12 version = 1 13 14 _adjustment = 0 15 _mask = 0x80 16 17 def mod_tweak_block(self, run_count, backing_path, block_size, 18 block_count): 19 logging.info('mod_tweak_block(%d, %s, %d, %d)' % ( 20 run_count, backing_path, block_size, block_count)) 21 run_count = run_count % block_count 22 with open(backing_path, 'r+b') as dev: 23 dev.seek(run_count * block_size + self._adjustment) 24 (byte,) = struct.unpack('B', dev.read(1)) # Get raw byte value. 25 dev.seek(run_count * block_size + self._adjustment) 26 dev.write(struct.pack('B', byte ^ self._mask)) 27 28 29 def mod_tweak_hash_block(self, run_count, backing_path, block_size, 30 block_count): 31 logging.info('mod_tweak_hash_block(%d, %s, %d, %d)' % ( 32 run_count, backing_path, block_size, block_count)) 33 with open(backing_path, 'r+b') as dev: 34 # move to the start of the appropriate hash block 35 dev.seek(block_count * block_size, os.SEEK_SET) 36 dev.seek(run_count * block_size + self._adjustment, os.SEEK_CUR) 37 (byte,) = struct.unpack('B', dev.read(1)) 38 # return to the start of the appropriate hash block 39 dev.seek(block_count * block_size, os.SEEK_SET) 40 dev.seek(run_count * block_size + self._adjustment, os.SEEK_CUR) 41 dev.write(struct.pack('B', byte ^ self._mask)) 42 43 44 def run_once(self, bit_loc='first'): 45 if bit_loc == 'first': 46 pass 47 elif bit_loc == 'last': 48 self._adjustment = verity_utils.BLOCK_SIZE - 1 49 self._mask = 0x01 50 elif bit_loc == 'middle': 51 self._adjustment = verity_utils.BLOCK_SIZE/2 52 else: 53 raise error.TestError('bit_loc must be first, last, or middle') 54 55 # Corrupt the |bit_loc| bit of each block (on a per-block basis). 56 self.mod_and_test(self.mod_tweak_block, self.image_blocks, False) 57 58 # Repeat except on each block in the hash tree data. 59 hash_blocks = (os.path.getsize(self.verity.hash_file) / 60 verity_utils.BLOCK_SIZE) 61 self.mod_and_test(self.mod_tweak_hash_block, hash_blocks, False) 62