summaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
Diffstat (limited to 'test/py')
-rw-r--r--test/py/tests/fs_helper.py95
-rw-r--r--test/py/tests/test_cat.py27
-rw-r--r--test/py/tests/test_efi_bootmgr.py38
-rw-r--r--test/py/tests/test_efi_fit.py2
-rw-r--r--test/py/tests/test_efi_loader.py2
-rw-r--r--test/py/tests/test_fpga.py4
-rw-r--r--test/py/tests/test_fs/conftest.py198
-rw-r--r--test/py/tests/test_net.py2
-rw-r--r--test/py/tests/test_scsi.py10
-rw-r--r--test/py/tests/test_ut.py190
-rw-r--r--test/py/tests/test_vboot.py10
-rw-r--r--test/py/tests/test_xxd.py28
-rw-r--r--test/py/tests/vboot_evil.py65
13 files changed, 368 insertions, 303 deletions
diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py
index 800376b1e7d..ee779474ce6 100644
--- a/test/py/tests/fs_helper.py
+++ b/test/py/tests/fs_helper.py
@@ -66,8 +66,9 @@ class FsHelper:
"""Make a new filesystem and copy in the files"""
self.setup()
self._do_cleanup = True
+ src_dir = self.srcdir if os.listdir(self.srcdir) else None
self.fs_img = mk_fs(self.config, self.fs_type, self.size_mb << 20,
- self.prefix, self.srcdir, quiet=self.quiet)
+ self.prefix, src_dir, quiet=self.quiet)
def setup(self):
"""Set up the srcdir ready to receive files"""
@@ -97,6 +98,98 @@ class FsHelper:
self.cleanup()
+class DiskHelper:
+ """Helper class for creating disk images containing filesytems
+
+ Usage:
+ with DiskHelper(ubman.config, 0, 'mmc') as img, \
+ FsHelper(ubman.config, 'ext1', 1, 'mmc') as fsh:
+ # Write files to fsh.srcdir
+ ...
+
+ # Create the filesystem
+ fsh.mk_fs()
+
+ # Add this filesystem to the disk
+ img.add_fs(fsh, DiskHelper.VFAT)
+
+ # Add more filesystems as needed (add another 'with' clause)
+ ...
+
+ # Get the final disk image
+ data = img.create()
+ """
+
+ # Partition-type codes
+ VFAT = 0xc
+ EXT4 = 0x83
+
+ def __init__(self, config, devnum, prefix, cur_dir=False):
+ """Set up a new disk image
+
+ Args:
+ config (u_boot_config): U-Boot configuration
+ devnum (int): Device number (for filename)
+ prefix (str): Prefix string of volume's file name
+ cur_dir (bool): True to put the file in the current directory,
+ instead of the persistent-data directory
+ """
+ self.fs_list = []
+ self.fname = os.path.join('' if cur_dir else config.persistent_data_dir,
+ f'{prefix}{devnum}.img')
+
+ def add_fs(self, fs_img, part_type, bootable=False):
+ """Add a new filesystem
+
+ Args:
+ fs_img (FsHelper): Filesystem to add
+ part_type (DiskHelper.FAT or DiskHelper.EXT4): Partition type
+ bootable (bool): True to set the 'bootable' flat
+ """
+ self.fs_list.append([fs_img, part_type, bootable])
+
+ def create(self):
+ """Create the disk image
+
+ Create an image with a partition table and the filesystems
+ """
+ spec = ''
+ pos = 1 # Reserve 1MB for the partition table itself
+ for fsi, part_type, bootable in self.fs_list:
+ if spec:
+ spec += '\n'
+ spec += f'type={part_type:x}, size={fsi.size_mb}M, start={pos}M'
+ if bootable:
+ spec += ', bootable'
+ pos += fsi.size_mb
+
+ img_size = pos
+ try:
+ check_call(f'qemu-img create {self.fname} {img_size}M', shell=True)
+ check_call(f'printf "{spec}" | sfdisk {self.fname}', shell=True)
+ except CalledProcessError:
+ os.remove(self.fname)
+ raise
+
+ pos = 1 # Reserve 1MB for the partition table itself
+ for fsi, part_type, bootable in self.fs_list:
+ check_call(
+ f'dd if={fsi.fs_img} of={self.fname} bs=1M seek={pos} conv=notrunc',
+ shell=True)
+ pos += fsi.size_mb
+ return self.fname
+
+ def cleanup(self, remove_full_img=False):
+ """Remove created file"""
+ os.remove(self.fname)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, extype, value, traceback):
+ self.cleanup()
+
+
def mk_fs(config, fs_type, size, prefix, src_dir=None, fs_img=None, quiet=False):
"""Create a file system volume
diff --git a/test/py/tests/test_cat.py b/test/py/tests/test_cat.py
index 252c3d50a02..f793b9fe0a1 100644
--- a/test/py/tests/test_cat.py
+++ b/test/py/tests/test_cat.py
@@ -4,8 +4,7 @@
"""
import pytest
-from subprocess import call, check_call, CalledProcessError
-from tests import fs_helper
+from tests.fs_helper import FsHelper
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_cat')
@@ -15,23 +14,11 @@ def test_cat(ubman):
Args:
ubman -- U-Boot console
"""
- try:
- scratch_dir = ubman.config.persistent_data_dir + '/scratch'
+ with FsHelper(ubman.config, 'vfat', 1, 'test_cat') as fsh:
+ with open(f'{fsh.srcdir}/hello', 'w', encoding = 'ascii') as outf:
+ outf.write('hello world\n')
+ fsh.mk_fs()
- check_call('mkdir -p %s' % scratch_dir, shell=True)
-
- with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n')
-
- cat_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
- 'test_cat', scratch_dir)
- response = ubman.run_command_list([ f'host bind 0 {cat_data}',
- 'cat host 0 hello'])
+ response = ubman.run_command_list([f'host bind 0 {fsh.fs_img}',
+ 'cat host 0 hello'])
assert 'hello world' in response
- except CalledProcessError as err:
- pytest.skip('Preparing test_cat image failed')
- call('rm -f %s' % cat_data, shell=True)
- return
- finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % cat_data, shell=True)
diff --git a/test/py/tests/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr.py
index 4c10cbdf17d..7d1f3f16d00 100644
--- a/test/py/tests/test_efi_bootmgr.py
+++ b/test/py/tests/test_efi_bootmgr.py
@@ -5,7 +5,7 @@
import shutil
import pytest
from subprocess import call, check_call, CalledProcessError
-from tests import fs_helper
+from tests.fs_helper import DiskHelper, FsHelper
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_efidebug')
@@ -20,22 +20,19 @@ def test_efi_bootmgr(ubman):
Args:
ubman -- U-Boot console
"""
- try:
- efi_bootmgr_data, mnt = fs_helper.setup_image(ubman, 0, 0xc,
- basename='test_efi_bootmgr')
-
- with open(mnt + '/initrd-1.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 1")
-
- with open(mnt + '/initrd-2.img', 'w', encoding = 'ascii') as file:
- file.write("initrd 2")
-
- shutil.copyfile(ubman.config.build_dir + '/lib/efi_loader/initrddump.efi',
- mnt + '/initrddump.efi')
-
- fsfile = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
- 'test_efi_bootmgr', mnt)
- check_call(f'dd if={fsfile} of={efi_bootmgr_data} bs=1M seek=1', shell=True)
+ with DiskHelper(ubman.config, 0, 'test_efi_bootmgr') as img, \
+ FsHelper(ubman.config, 'vfat', 1, 'test_efi_bootmgr') as fsh:
+ with open(f'{fsh.srcdir}/initrd-1.img', 'w', encoding = 'ascii') as outf:
+ outf.write("initrd 1")
+ with open(f'{fsh.srcdir}/initrd-2.img', 'w', encoding = 'ascii') as outf:
+ outf.write("initrd 2")
+ shutil.copyfile(
+ ubman.config.build_dir + '/lib/efi_loader/initrddump.efi',
+ f'{fsh.srcdir}/initrddump.efi')
+ fsh.mk_fs()
+
+ img.add_fs(fsh, DiskHelper.VFAT)
+ efi_bootmgr_data = img.create()
ubman.run_command(cmd = f'host bind 0 {efi_bootmgr_data}')
@@ -61,10 +58,3 @@ def test_efi_bootmgr(ubman):
ubman.run_command(cmd = 'efidebug boot rm 0001')
ubman.run_command(cmd = 'efidebug boot rm 0002')
- except CalledProcessError as err:
- pytest.skip('Preparing test_efi_bootmgr image failed')
- call('rm -f %s' % efi_bootmgr_data, shell=True)
- return
- finally:
- call('rm -rf %s' % mnt, shell=True)
- call('rm -f %s' % efi_bootmgr_data, shell=True)
diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
index 63ee8e6cef2..409cfdfd56f 100644
--- a/test/py/tests/test_efi_fit.py
+++ b/test/py/tests/test_efi_fit.py
@@ -225,7 +225,7 @@ def test_efi_fit_launch(ubman):
has_dhcp = ubman.config.buildconfig.get('config_cmd_dhcp', 'n') == 'y'
if not has_dhcp:
- ubman.log.warning('CONFIG_NET != y: Skipping static network setup')
+ ubman.log.warning('CONFIG_NET_LEGACY != y: Skipping static network setup')
return False
env_vars = ubman.config.env.get('env__net_static_env_vars', None)
diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
index dc58c0d4dbd..91f151d09cd 100644
--- a/test/py/tests/test_efi_loader.py
+++ b/test/py/tests/test_efi_loader.py
@@ -98,7 +98,7 @@ def test_efi_setup_dhcp(ubman):
global net_set_up
net_set_up = True
[email protected]('net', 'net_lwip')
def test_efi_setup_static(ubman):
"""Set up the network using a static IP configuration.
diff --git a/test/py/tests/test_fpga.py b/test/py/tests/test_fpga.py
index 299a8653f74..74cd42b910e 100644
--- a/test/py/tests/test_fpga.py
+++ b/test/py/tests/test_fpga.py
@@ -506,7 +506,7 @@ def test_fpga_loadfs(ubman):
@pytest.mark.buildconfigspec('cmd_fpga_load_secure')
@pytest.mark.buildconfigspec('cmd_net')
@pytest.mark.buildconfigspec('cmd_dhcp')
[email protected]('net', 'net_lwip')
def test_fpga_secure_bit_auth(ubman):
test_net.test_net_dhcp(ubman)
@@ -534,7 +534,7 @@ def test_fpga_secure_bit_auth(ubman):
@pytest.mark.buildconfigspec('cmd_fpga_load_secure')
@pytest.mark.buildconfigspec('cmd_net')
@pytest.mark.buildconfigspec('cmd_dhcp')
[email protected]('net', 'net_lwip')
def test_fpga_secure_bit_img_auth_kup(ubman):
test_net.test_net_dhcp(ubman)
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index 0205048e73a..ba125cc7073 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -9,7 +9,7 @@ import re
from subprocess import call, check_call, check_output, CalledProcessError
from fstest_defs import *
# pylint: disable=E0611
-from tests import fs_helper
+from tests.fs_helper import FsHelper
supported_fs_basic = ['fat16', 'fat32', 'exfat', 'ext4', 'fs_generic']
supported_fs_ext = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
@@ -200,33 +200,26 @@ def fs_obj_basic(request, u_boot_config):
fs_type = request.param
fs_cmd_prefix = fstype_to_prefix(fs_type)
fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
- scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
-
- small_file = scratch_dir + '/' + SMALL_FILE
- big_file = scratch_dir + '/' + BIG_FILE
-
+ fsh = FsHelper(u_boot_config, fs_type, 3072, '3GB')
try:
- check_call('mkdir -p %s' % scratch_dir, shell=True)
- except CalledProcessError as err:
- pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
- call('rm -f %s' % fs_img, shell=True)
- return
+ fsh.setup()
+
+ small_file = fsh.srcdir + '/' + SMALL_FILE
+ big_file = fsh.srcdir + '/' + BIG_FILE
- try:
# Create a subdirectory.
- check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
+ check_call('mkdir %s/SUBDIR' % fsh.srcdir, shell=True)
# Create big file in this image.
# Note that we work only on the start 1MB, couple MBs in the 2GB range
# and the last 1 MB of the huge 2.5GB file.
# So, just put random values only in those areas.
check_call('dd if=/dev/urandom of=%s bs=1M count=1'
- % big_file, shell=True)
+ % big_file, shell=True)
check_call('dd if=/dev/urandom of=%s bs=1M count=2 seek=2047'
% big_file, shell=True)
check_call('dd if=/dev/urandom of=%s bs=1M count=1 seek=2499'
@@ -234,65 +227,54 @@ def fs_obj_basic(request, u_boot_config):
# Create a small file in this image.
check_call('dd if=/dev/urandom of=%s bs=1M count=1'
- % small_file, shell=True)
-
- # Delete the small file copies which possibly are written as part of a
- # previous test.
- # check_call('rm -f "%s.w"' % MB1, shell=True)
- # check_call('rm -f "%s.w2"' % MB1, shell=True)
+ % small_file, shell=True)
# Generate the md5sums of reads that we will test against small file
out = check_output(
'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
- % small_file, shell=True).decode()
+ % small_file, shell=True).decode()
md5val = [ out.split()[0] ]
# Generate the md5sums of reads that we will test against big file
# One from beginning of file.
out = check_output(
'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum'
- % big_file, shell=True).decode()
+ % big_file, shell=True).decode()
md5val.append(out.split()[0])
# One from end of file.
out = check_output(
'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum'
- % big_file, shell=True).decode()
+ % big_file, shell=True).decode()
md5val.append(out.split()[0])
# One from the last 1MB chunk of 2GB
out = check_output(
'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum'
- % big_file, shell=True).decode()
+ % big_file, shell=True).decode()
md5val.append(out.split()[0])
# One from the start 1MB chunk from 2GB
out = check_output(
'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum'
- % big_file, shell=True).decode()
+ % big_file, shell=True).decode()
md5val.append(out.split()[0])
# One 1MB chunk crossing the 2GB boundary
out = check_output(
'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum'
- % big_file, shell=True).decode()
+ % big_file, shell=True).decode()
md5val.append(out.split()[0])
- try:
- # 3GiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0xc0000000, '3GB', scratch_dir)
- except CalledProcessError as err:
- pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
- return
+ fsh.mk_fs()
except CalledProcessError as err:
pytest.skip('Setup failed for filesystem: ' + fs_type + '. {}'.format(err))
return
else:
- yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
+ yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fsh.fs_img, md5val]
finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % fs_img, shell=True)
+ fsh.cleanup()
#
# Fixture for extended fs test
@@ -312,26 +294,19 @@ def fs_obj_ext(request, u_boot_config):
fs_type = request.param
fs_cmd_prefix = fstype_to_prefix(fs_type)
fs_cmd_write = 'save' if fs_type == 'fs_generic' or fs_type == 'exfat' else 'write'
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
- scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
-
- min_file = scratch_dir + '/' + MIN_FILE
- tmp_file = scratch_dir + '/tmpfile'
-
+ fsh = FsHelper(u_boot_config, fs_type, 128, '128MB')
try:
- check_call('mkdir -p %s' % scratch_dir, shell=True)
- except CalledProcessError as err:
- pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
- call('rm -f %s' % fs_img, shell=True)
- return
+ fsh.setup()
+
+ min_file = fsh.srcdir + '/' + MIN_FILE
+ tmp_file = fsh.srcdir + '/tmpfile'
- try:
# Create a test directory
- check_call('mkdir %s/dir1' % scratch_dir, shell=True)
+ check_call('mkdir %s/dir1' % fsh.srcdir, shell=True)
# Create a small file and calculate md5
check_call('dd if=/dev/urandom of=%s bs=1K count=20'
@@ -370,21 +345,15 @@ def fs_obj_ext(request, u_boot_config):
check_call('rm %s' % tmp_file, shell=True)
- try:
- # 128MiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
- except CalledProcessError as err:
- pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
- return
+ fsh.mk_fs()
except CalledProcessError:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fs_img, md5val]
+ yield [fs_ubtype, fs_cmd_prefix, fs_cmd_write, fsh.fs_img, md5val]
finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % fs_img, shell=True)
+ fsh.cleanup()
#
# Fixture for mkdir test
@@ -403,20 +372,19 @@ def fs_obj_mkdir(request, u_boot_config):
"""
fs_type = request.param
fs_cmd_prefix = fstype_to_prefix(fs_type)
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
+ fsh = FsHelper(u_boot_config, fs_type, 128, '128MB')
try:
- # 128MiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', None)
+ fsh.mk_fs()
except:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_cmd_prefix, fs_img]
- call('rm -f %s' % fs_img, shell=True)
+ yield [fs_ubtype, fs_cmd_prefix, fsh.fs_img]
+ fsh.cleanup()
#
# Fixture for unlink test
@@ -435,57 +403,44 @@ def fs_obj_unlink(request, u_boot_config):
"""
fs_type = request.param
fs_cmd_prefix = fstype_to_prefix(fs_type)
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
- scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
-
+ fsh = FsHelper(u_boot_config, fs_type, 128, '128MB')
try:
- check_call('mkdir -p %s' % scratch_dir, shell=True)
- except CalledProcessError as err:
- pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
- call('rm -f %s' % fs_img, shell=True)
- return
+ fsh.setup()
- try:
# Test Case 1 & 3
- check_call('mkdir %s/dir1' % scratch_dir, shell=True)
+ check_call('mkdir %s/dir1' % fsh.srcdir, shell=True)
check_call('dd if=/dev/urandom of=%s/dir1/file1 bs=1K count=1'
- % scratch_dir, shell=True)
+ % fsh.srcdir, shell=True)
check_call('dd if=/dev/urandom of=%s/dir1/file2 bs=1K count=1'
- % scratch_dir, shell=True)
+ % fsh.srcdir, shell=True)
# Test Case 2
- check_call('mkdir %s/dir2' % scratch_dir, shell=True)
+ check_call('mkdir %s/dir2' % fsh.srcdir, shell=True)
for i in range(0, 20):
check_call('mkdir %s/dir2/0123456789abcdef%02x'
- % (scratch_dir, i), shell=True)
+ % (fsh.srcdir, i), shell=True)
# Test Case 4
- check_call('mkdir %s/dir4' % scratch_dir, shell=True)
+ check_call('mkdir %s/dir4' % fsh.srcdir, shell=True)
# Test Case 5, 6 & 7
- check_call('mkdir %s/dir5' % scratch_dir, shell=True)
+ check_call('mkdir %s/dir5' % fsh.srcdir, shell=True)
check_call('dd if=/dev/urandom of=%s/dir5/file1 bs=1K count=1'
- % scratch_dir, shell=True)
+ % fsh.srcdir, shell=True)
- try:
- # 128MiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', scratch_dir)
- except CalledProcessError as err:
- pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
- return
+ fsh.mk_fs()
except CalledProcessError:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_cmd_prefix, fs_img]
+ yield [fs_ubtype, fs_cmd_prefix, fsh.fs_img]
finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % fs_img, shell=True)
+ fsh.cleanup()
#
# Fixture for symlink fs test
@@ -503,26 +458,19 @@ def fs_obj_symlink(request, u_boot_config):
volume file name and a list of MD5 hashes.
"""
fs_type = request.param
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
- scratch_dir = u_boot_config.persistent_data_dir + '/scratch'
-
- small_file = scratch_dir + '/' + SMALL_FILE
- medium_file = scratch_dir + '/' + MEDIUM_FILE
-
+ fsh = FsHelper(u_boot_config, fs_type, 1024, '1GB')
try:
- check_call('mkdir -p %s' % scratch_dir, shell=True)
- except CalledProcessError as err:
- pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
- call('rm -f %s' % fs_img, shell=True)
- return
+ fsh.setup()
+
+ small_file = fsh.srcdir + '/' + SMALL_FILE
+ medium_file = fsh.srcdir + '/' + MEDIUM_FILE
- try:
# Create a subdirectory.
- check_call('mkdir %s/SUBDIR' % scratch_dir, shell=True)
+ check_call('mkdir %s/SUBDIR' % fsh.srcdir, shell=True)
# Create a small file in this image.
check_call('dd if=/dev/urandom of=%s bs=1M count=1'
@@ -542,21 +490,15 @@ def fs_obj_symlink(request, u_boot_config):
% medium_file, shell=True).decode()
md5val.extend([out.split()[0]])
- try:
- # 1GiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x40000000, '1GB', scratch_dir)
- except CalledProcessError as err:
- pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
- return
+ fsh.mk_fs()
except CalledProcessError:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img, md5val]
+ yield [fs_ubtype, fsh.fs_img, md5val]
finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % fs_img, shell=True)
+ fsh.cleanup()
#
# Fixture for rename test
@@ -584,21 +526,15 @@ def fs_obj_rename(request, u_boot_config):
return out.decode().split()[0]
fs_type = request.param
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
- mount_dir = u_boot_config.persistent_data_dir + '/scratch'
-
+ fsh = FsHelper(u_boot_config, fs_type, 128, '128MB')
try:
- check_call('mkdir -p %s' % mount_dir, shell=True)
- except CalledProcessError as err:
- pytest.skip('Preparing mount folder failed for filesystem: ' + fs_type + '. {}'.format(err))
- call('rm -f %s' % fs_img, shell=True)
- return
+ fsh.setup()
+ mount_dir = fsh.srcdir
- try:
md5val = {}
# Test Case 1
check_call('mkdir %s/test1' % mount_dir, shell=True)
@@ -657,21 +593,15 @@ def fs_obj_rename(request, u_boot_config):
new_rand_file('%s/test11/dir1/file1' % mount_dir)
md5val['test11'] = file_hash('%s/test11/dir1/file1' % mount_dir)
- try:
- # 128MiB volume
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, 0x8000000, '128MB', mount_dir)
- except CalledProcessError as err:
- pytest.skip('Creating failed for filesystem: ' + fs_type + '. {}'.format(err))
- return
+ fsh.mk_fs()
except CalledProcessError:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img, md5val]
+ yield [fs_ubtype, fsh.fs_img, md5val]
finally:
- call('rm -rf %s' % mount_dir, shell=True)
- call('rm -f %s' % fs_img, shell=True)
+ fsh.cleanup()
#
# Fixture for fat test
@@ -697,19 +627,19 @@ def fs_obj_fat(request, u_boot_config):
MIN_FAT16_SIZE = 8208 * 1024
fs_type = request.param
- fs_img = ''
fs_ubtype = fstype_to_ubname(fs_type)
check_ubconfig(u_boot_config, fs_ubtype)
fs_size = MAX_FAT12_SIZE if fs_type == 'fat12' else MIN_FAT16_SIZE
+ size_mb = (fs_size + (1 << 20) - 1) >> 20
+ fsh = FsHelper(u_boot_config, fs_type, size_mb, f'{fs_size}')
try:
- # the volume size depends on the filesystem
- fs_img = fs_helper.mk_fs(u_boot_config, fs_type, fs_size, f'{fs_size}', None, 1024)
+ fsh.mk_fs()
except:
pytest.skip('Setup failed for filesystem: ' + fs_type)
return
else:
- yield [fs_ubtype, fs_img]
- call('rm -f %s' % fs_img, shell=True)
+ yield [fs_ubtype, fsh.fs_img]
+ fsh.cleanup()
diff --git a/test/py/tests/test_net.py b/test/py/tests/test_net.py
index 6ef02e53389..27cdd73fd49 100644
--- a/test/py/tests/test_net.py
+++ b/test/py/tests/test_net.py
@@ -201,7 +201,7 @@ def test_net_dhcp6(ubman):
global net6_set_up
net6_set_up = True
[email protected]('net', 'net_lwip')
def test_net_setup_static(ubman):
"""Set up a static IP configuration.
diff --git a/test/py/tests/test_scsi.py b/test/py/tests/test_scsi.py
index 2a35e47e558..4390ff65845 100644
--- a/test/py/tests/test_scsi.py
+++ b/test/py/tests/test_scsi.py
@@ -39,16 +39,6 @@ def scsi_setup(ubman):
return dev_num, dev_type, dev_size
@pytest.mark.buildconfigspec('cmd_scsi')
-def test_scsi_reset(ubman):
- dev_num, dev_type, dev_size = scsi_setup(ubman)
- output = ubman.run_command('scsi reset')
- assert f'Device {dev_num}:' in output
- assert f'Type: {dev_type}' in output
- assert f'Capacity: {dev_size}' in output
- output = ubman.run_command('echo $?')
- assert output.endswith('0')
-
[email protected]('cmd_scsi')
def test_scsi_info(ubman):
dev_num, dev_type, dev_size = scsi_setup(ubman)
output = ubman.run_command('scsi info')
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index 98641a46c1d..dce5a37dd35 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -17,6 +17,7 @@ import pytest
import utils
# pylint: disable=E0611
from tests import fs_helper
+from fs_helper import DiskHelper, FsHelper
from test_android import test_abootimg
def mkdir_cond(dirname):
@@ -45,7 +46,6 @@ def setup_bootmenu_image(ubman):
This is modelled on Armbian 22.08 Jammy
"""
mmc_dev = 4
- fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0x83)
script = '''# DO NOT EDIT THIS FILE
#
@@ -121,7 +121,9 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
'''
- bootdir = os.path.join(mnt, 'boot')
+ fsh = FsHelper(ubman.config, 'ext4', 18, 'mmc')
+ fsh.setup()
+ bootdir = os.path.join(fsh.srcdir, 'boot')
mkdir_cond(bootdir)
cmd_fname = os.path.join(bootdir, 'boot.cmd')
scr_fname = os.path.join(bootdir, 'boot.scr')
@@ -150,36 +152,30 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
utils.run_and_log(
ubman, f'echo here {kernel} {symlink}')
os.symlink(kernel, symlink)
+ fsh.mk_fs()
+ img = DiskHelper(ubman.config, mmc_dev, 'mmc', True)
+ img.add_fs(fsh, DiskHelper.EXT4)
+ img.create()
+ fsh.cleanup()
- fsfile = 'ext18M.img'
- utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
- utils.run_and_log(ubman, f'mkfs.ext4 {fsfile} -d {mnt}')
- copy_partition(ubman, fsfile, fname)
- utils.run_and_log(ubman, f'rm -rf {mnt}')
- utils.run_and_log(ubman, f'rm -f {fsfile}')
-def setup_bootflow_image(ubman):
- """Create a 20MB disk image with a single FAT partition"""
- mmc_dev = 1
- fname, mnt = fs_helper.setup_image(ubman, mmc_dev, 0xc, second_part=True)
+def setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
+ script):
+ """Create a 20MB disk image with a single FAT partition
- vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl'
- initrd = 'initramfs-5.3.7-301.fc31.armv7hl.img'
- dtbdir = 'dtb-5.3.7-301.fc31.armv7hl'
- script = '''# extlinux.conf generated by appliance-creator
-ui menu.c32
-menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
-menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
-menu hidden
-timeout 20
-totaltimeout 600
+ Args:
+ ubman (ConsoleBase): Console to use
+ devnum (int): Device number to use, e.g. 1
+ basename (str): Base name to use in the filename, e.g. 'mmc'
+ vmlinux (str): Kernel filename
+ initrd (str): Ramdisk filename
+ dtbdir (str or None): Devicetree filename
+ script (str): Script to place in the extlinux.conf file
+ """
+ fsh = FsHelper(ubman.config, 'vfat', 18, prefix=basename)
+ fsh.setup()
-label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
- kernel /%s
- append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
- fdtdir /%s/
- initrd /%s''' % (vmlinux, dtbdir, initrd)
- ext = os.path.join(mnt, 'extlinux')
+ ext = os.path.join(fsh.srcdir, 'extlinux')
mkdir_cond(ext)
conf = os.path.join(ext, 'extlinux.conf')
@@ -191,24 +187,57 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
fd.write(gzip.compress(b'vmlinux'))
mkimage = ubman.config.build_dir + '/tools/mkimage'
utils.run_and_log(
- ubman, f'{mkimage} -f auto -d {inf} {os.path.join(mnt, vmlinux)}')
+ ubman, f'{mkimage} -f auto -d {inf} {os.path.join(fsh.srcdir, vmlinux)}')
- with open(os.path.join(mnt, initrd), 'w', encoding='ascii') as fd:
+ with open(os.path.join(fsh.srcdir, initrd), 'w', encoding='ascii') as fd:
print('initrd', file=fd)
- mkdir_cond(os.path.join(mnt, dtbdir))
+ if dtbdir:
+ mkdir_cond(os.path.join(fsh.srcdir, dtbdir))
- dtb_file = os.path.join(mnt, f'{dtbdir}/sandbox.dtb')
- utils.run_and_log(
- ubman, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
+ dtb_file = os.path.join(fsh.srcdir, f'{dtbdir}/sandbox.dtb')
+ utils.run_and_log(
+ ubman, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
+
+ fsh.mk_fs()
+
+ img = DiskHelper(ubman.config, devnum, basename, True)
+ img.add_fs(fsh, DiskHelper.VFAT, bootable=True)
+
+ ext4 = FsHelper(ubman.config, 'ext4', 1, prefix=basename)
+ ext4.setup()
+ ext4.mk_fs()
+
+ img.add_fs(ext4, DiskHelper.EXT4)
+ img.create()
+ fsh.cleanup()
+
+def setup_fedora_image(ubman, devnum, basename):
+ """Create a 20MB Fedora disk image with a single FAT partition
+
+ Args:
+ ubman (ConsoleBase): Console to use
+ devnum (int): Device number to use, e.g. 1
+ basename (str): Base name to use in the filename, e.g. 'mmc'
+ """
+ vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl'
+ initrd = 'initramfs-5.3.7-301.fc31.armv7hl.img'
+ dtbdir = 'dtb-5.3.7-301.fc31.armv7hl'
+ script = '''# extlinux.conf generated by appliance-creator
+ui menu.c32
+menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
+menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
+menu hidden
+timeout 20
+totaltimeout 600
- fsfile = 'vfat18M.img'
- utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
- utils.run_and_log(ubman, f'mkfs.vfat {fsfile}')
- utils.run_and_log(ubman, ['sh', '-c', f'mcopy -i {fsfile} {mnt}/* ::/'])
- copy_partition(ubman, fsfile, fname)
- utils.run_and_log(ubman, f'rm -rf {mnt}')
- utils.run_and_log(ubman, f'rm -f {fsfile}')
+label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
+ kernel /%s
+ append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
+ fdtdir /%s/
+ initrd /%s''' % (vmlinux, dtbdir, initrd)
+ setup_extlinux_image(ubman, devnum, basename, vmlinux, initrd, dtbdir,
+ script)
def setup_cros_image(ubman):
"""Create a 20MB disk image with ChromiumOS partitions"""
@@ -513,8 +542,8 @@ def test_ut_dm_init(ubman):
utils.run_and_log(
ubman, f'sfdisk {fn}', stdin=b'type=83')
- fs_helper.mk_fs(ubman.config, 'ext2', 0x200000, '2MB', None)
- fs_helper.mk_fs(ubman.config, 'fat32', 0x100000, '1MB', None)
+ FsHelper(ubman.config, 'ext2', 2, '2MB').mk_fs()
+ FsHelper(ubman.config, 'fat32', 1, '1MB').mk_fs()
mmc_dev = 6
fn = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
@@ -532,11 +561,9 @@ def test_ut_dm_init(ubman):
def setup_efi_image(ubman):
"""Create a 20MB disk image with an EFI app on it"""
devnum = 1
- basename = 'flash'
- fname, mnt = fs_helper.setup_image(ubman, devnum, 0xc, second_part=True,
- basename=basename)
-
- efi_dir = os.path.join(mnt, 'EFI')
+ fsh = FsHelper(ubman.config, 'vfat', 18, 'flash')
+ fsh.setup()
+ efi_dir = os.path.join(fsh.srcdir, 'EFI')
mkdir_cond(efi_dir)
bootdir = os.path.join(efi_dir, 'BOOT')
mkdir_cond(bootdir)
@@ -546,66 +573,53 @@ def setup_efi_image(ubman):
with open(efi_src, 'rb') as inf:
with open(efi_dst, 'wb') as outf:
outf.write(inf.read())
- fsfile = 'vfat18M.img'
- utils.run_and_log(ubman, f'fallocate -l 18M {fsfile}')
- utils.run_and_log(ubman, f'mkfs.vfat {fsfile}')
- utils.run_and_log(ubman, ['sh', '-c', f'mcopy -vs -i {fsfile} {mnt}/* ::/'])
- copy_partition(ubman, fsfile, fname)
- utils.run_and_log(ubman, f'rm -rf {mnt}')
- utils.run_and_log(ubman, f'rm -f {fsfile}')
+
+ fsh.mk_fs()
+
+ img = DiskHelper(ubman.config, devnum, 'flash', True)
+ img.add_fs(fsh, DiskHelper.VFAT)
+ img.create()
+ fsh.cleanup()
+
def setup_rauc_image(ubman):
"""Create a 40MB disk image with an A/B RAUC system on it"""
mmc_dev = 10
- fname = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
- mnt = ubman.config.persistent_data_dir
-
- spec = 'type=c, size=8M, start=1M, bootable\n' \
- 'type=83, size=10M\n' \
- 'type=c, size=8M, bootable\n' \
- 'type=83, size=10M'
- utils.run_and_log(ubman, f'qemu-img create {fname} 40M')
- utils.run_and_log(ubman, ['sh', '-c', f'printf "{spec}" | sfdisk {fname}'])
+ boot = FsHelper(ubman.config, 'fat32', 8, 'rauc_boot')
+ boot.setup()
# Generate boot script
script = '# dummy boot script'
- bootdir = os.path.join(mnt, 'boot')
- utils.run_and_log(ubman, f'mkdir -p {bootdir}')
- cmd_fname = os.path.join(bootdir, 'boot.cmd')
- scr_fname = os.path.join(bootdir, 'boot.scr')
+ cmd_fname = os.path.join(boot.srcdir, 'boot.cmd')
+ scr_fname = os.path.join(boot.srcdir, 'boot.scr')
with open(cmd_fname, 'w', encoding='ascii') as outf:
print(script, file=outf)
mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage')
utils.run_and_log(
ubman, f'{mkimage} -C none -A arm -T script -d {cmd_fname} {scr_fname}')
- utils.run_and_log(ubman, f'rm -f {cmd_fname}')
-
- # Generate empty rootfs
- rootdir = os.path.join(mnt, 'root')
- utils.run_and_log(ubman, f'mkdir -p {rootdir}')
-
- # Create boot filesystem image with boot script in it and copy to disk image
- fsfile = f'rauc_boot.fat32.img'
- fs_helper.mk_fs(ubman.config, 'fat32', 0x800000, fsfile.split('.')[0], bootdir)
- utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=1 conv=notrunc')
- utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=19 conv=notrunc')
- utils.run_and_log(ubman, f'rm -f {scr_fname}')
-
- # Create empty root filesystem image and copy to disk image
- fsfile = f'rauc_root.ext4.img'
- fs_helper.mk_fs(ubman.config, 'ext4', 0xa00000, fsfile.split('.')[0], rootdir)
- utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=9 conv=notrunc')
- utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=27 conv=notrunc')
- utils.run_and_log(ubman, f'rm -f {fsfile}')
+ os.remove(cmd_fname)
+ boot.mk_fs()
+
+ root = FsHelper(ubman.config, 'ext4', 10, 'rauc_root')
+ root.mk_fs()
+
+ img = DiskHelper(ubman.config, mmc_dev, 'mmc', True)
+ img.add_fs(boot, DiskHelper.VFAT, bootable=True)
+ img.add_fs(root, DiskHelper.EXT4)
+ img.add_fs(boot, DiskHelper.VFAT, bootable=True)
+ img.add_fs(root, DiskHelper.EXT4)
+ img.create()
+ boot.cleanup()
+ root.cleanup()
@pytest.mark.buildconfigspec('cmd_bootflow')
@pytest.mark.buildconfigspec('sandbox')
def test_ut_dm_init_bootstd(ubman):
"""Initialise data for bootflow tests"""
- setup_bootflow_image(ubman)
+ setup_fedora_image(ubman, 1, 'mmc')
setup_bootmenu_image(ubman)
setup_cedit_file(ubman)
setup_cros_image(ubman)
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 19f3f981379..55518bed07e 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -372,6 +372,16 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
msg = 'Signature checking prevents use of unit addresses (@) in nodes'
run_bootm(sha_algo, 'evil kernel@', msg, False, efit)
+ # Try doing a clone of the images
+ efit = '%stest.evilclone.fit' % tmpdir
+ shutil.copyfile(fit, efit)
+ vboot_evil.add_evil_node(fit, efit, evil_kernel, 'clone')
+
+ utils.run_and_log_expect_exception(
+ ubman, [fit_check_sign, '-f', efit, '-k', dtb],
+ 1, 'Failed to verify required signature')
+ run_bootm(sha_algo, 'evil clone', 'Bad Data Hash', False, efit)
+
# Create a new properly signed fit and replace header bytes
make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit(sha_algo, sign_options)
diff --git a/test/py/tests/test_xxd.py b/test/py/tests/test_xxd.py
index c457c54146c..a5f63f006fe 100644
--- a/test/py/tests/test_xxd.py
+++ b/test/py/tests/test_xxd.py
@@ -4,8 +4,7 @@
"""
import pytest
-from subprocess import call, check_call, CalledProcessError
-from tests import fs_helper
+from tests.fs_helper import FsHelper
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_xxd')
@@ -15,26 +14,13 @@ def test_xxd(ubman):
Args:
ubman -- U-Boot console
"""
- try:
- scratch_dir = ubman.config.persistent_data_dir + '/scratch'
-
- check_call('mkdir -p %s' % scratch_dir, shell=True)
-
- with open(scratch_dir + '/hello', 'w', encoding = 'ascii') as file:
- file.write('hello world\n\x00\x01\x02\x03\x04\x05')
-
- xxd_data = fs_helper.mk_fs(ubman.config, 'vfat', 0x100000,
- 'test_xxd', scratch_dir)
- response = ubman.run_command_list([ f'host bind 0 {xxd_data}',
- 'xxd host 0 hello'])
+ with FsHelper(ubman.config, 'vfat', 1, 'test_xxd') as fsh:
+ with open(f'{fsh.srcdir}/hello', 'w', encoding = 'ascii') as outf:
+ outf.write('hello world\n\x00\x01\x02\x03\x04\x05')
+ fsh.mk_fs()
+ response = ubman.run_command_list([f'host bind 0 {fsh.fs_img}',
+ 'xxd host 0 hello'])
assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
'00000010: 04 05 ..' \
in response
- except CalledProcessError as err:
- pytest.skip('Preparing test_xxd image failed')
- call('rm -f %s' % xxd_data, shell=True)
- return
- finally:
- call('rm -rf %s' % scratch_dir, shell=True)
- call('rm -f %s' % xxd_data, shell=True)
diff --git a/test/py/tests/vboot_evil.py b/test/py/tests/vboot_evil.py
index e2b0cd65468..5720631ae52 100644
--- a/test/py/tests/vboot_evil.py
+++ b/test/py/tests/vboot_evil.py
@@ -14,6 +14,7 @@ FDT_END = 0x9
FAKE_ROOT_ATTACK = 0
KERNEL_AT = 1
+IMAGE_CLONE = 2
MAGIC = 0xd00dfeed
@@ -274,6 +275,66 @@ def get_prop_value(dt_struct, dt_strings, prop_path):
return tag_data
+def image_clone_attack(dt_struct, dt_strings, kernel_content, kernel_hash):
+ # retrieve the default configuration name
+ default_conf_name = get_prop_value(
+ dt_struct, dt_strings, '/configurations/default')
+ default_conf_name = str(default_conf_name[:-1], 'utf-8')
+
+ conf_path = '/configurations/' + default_conf_name
+
+ # fetch the loaded kernel name from the default configuration
+ loaded_kernel = get_prop_value(dt_struct, dt_strings, conf_path + '/kernel')
+
+ loaded_kernel = str(loaded_kernel[:-1], 'utf-8')
+
+ # since this is the last child in images!
+ loaded_fdt_name = get_prop_value(dt_struct, dt_strings, conf_path + '/fdt')
+
+ loaded_fdt_name = str(loaded_fdt_name[:-1], 'utf-8')
+
+ # determine boundaries of the images
+ (img_node_start, img_node_end) = (determine_offset(
+ dt_struct, dt_strings, '/images'))
+ if img_node_start is None and img_node_end is None:
+ print('Fatal error, unable to find images node')
+ sys.exit()
+
+ # copy the images node
+ img_node_copy = dt_struct[img_node_start:img_node_end]
+
+ # create an additional empty node
+ empty_node = struct.pack('>I', FDT_BEGIN_NODE) + b"EMPTYNO\0" + struct.pack('>I', FDT_END_NODE)
+ # right before the end, we add it!
+ img_node_copy = img_node_copy[:-4] + empty_node + img_node_copy[-4:]
+
+ # insert the copy inside the tree
+ dt_struct = dt_struct[:img_node_end-4] + \
+ img_node_copy + empty_node + dt_struct[img_node_end-4:]
+
+ # change the content of the kernel being loaded
+ dt_struct = change_property_value(
+ dt_struct, dt_strings, '/images/' + loaded_kernel + '/data', kernel_content)
+
+ # change the content of the kernel being loaded
+ dt_struct = change_property_value(
+ dt_struct, dt_strings, '/images/' + loaded_kernel + '/hash-1/value', kernel_hash)
+
+ # finally, the main bug: change the hashed nodes to use the images clone instead!
+ hashed_nodes: bytes = get_prop_value(dt_struct, dt_strings, conf_path + '/signature/hashed-nodes')
+ print(f"got hashed nodes: {hashed_nodes}")
+ nodes = hashed_nodes.split(b"\0")
+ patched_nodes = []
+ for node in nodes:
+ new_node = node
+ if node.startswith(b"/images/"):
+ # reparent the node
+ new_node = b"/images" + node
+ patched_nodes.append(new_node)
+ hashed_nodes = b"\0".join(patched_nodes)
+ dt_struct = change_property_value(
+ dt_struct, dt_strings, conf_path + '/signature/hashed-nodes', hashed_nodes)
+ return dt_struct
def kernel_at_attack(dt_struct, dt_strings, kernel_content, kernel_hash):
"""Conduct the kernel@ attack
@@ -419,6 +480,8 @@ def add_evil_node(in_fname, out_fname, kernel_fname, attack):
attack = FAKE_ROOT_ATTACK
elif attack == 'kernel@':
attack = KERNEL_AT
+ elif attack == 'clone':
+ attack = IMAGE_CLONE
else:
raise ValueError('Unknown attack name!')
@@ -455,6 +518,8 @@ def add_evil_node(in_fname, out_fname, kernel_fname, attack):
elif attack == KERNEL_AT:
dt_struct = kernel_at_attack(dt_struct, dt_strings, kernel_content,
hash_digest)
+ elif attack == IMAGE_CLONE:
+ dt_struct = image_clone_attack(dt_struct, dt_strings, kernel_content, hash_digest)
# now rebuild the new file
size_dt_strings = len(dt_strings)