From 51b896ee7509964b97e61baaa4561b8ebc2aec3e Mon Sep 17 00:00:00 2001 From: Sebastian Mitterle Date: Mon, 18 Dec 2023 05:25:32 -0500 Subject: [PATCH] memory/secure_dump: add test for s390x SE decryption Add test case that 1. Dumps the SE memory 2. Decrypts the memory 3. Does a minimal check on the decrypted content. Signed-off-by: Sebastian Mitterle --- libvirt/tests/cfg/memory/secure_dump.cfg | 7 ++ libvirt/tests/src/memory/secure_dump.py | 83 ++++++++++++++++++++++++ spell.ignore | 3 + 3 files changed, 93 insertions(+) create mode 100644 libvirt/tests/cfg/memory/secure_dump.cfg create mode 100644 libvirt/tests/src/memory/secure_dump.py diff --git a/libvirt/tests/cfg/memory/secure_dump.cfg b/libvirt/tests/cfg/memory/secure_dump.cfg new file mode 100644 index 0000000000..46fbe9e88f --- /dev/null +++ b/libvirt/tests/cfg/memory/secure_dump.cfg @@ -0,0 +1,7 @@ +- secure_dump: + type = secure_dump + start_vm = yes + only s390-virtio + variants: + - decrypt: + comm_key = 0123456789012345678901234567890 diff --git a/libvirt/tests/src/memory/secure_dump.py b/libvirt/tests/src/memory/secure_dump.py new file mode 100644 index 0000000000..32bf9dfbc9 --- /dev/null +++ b/libvirt/tests/src/memory/secure_dump.py @@ -0,0 +1,83 @@ +import logging as log +import os + +from virttest.utils_misc import cmd_status_output +from virttest import virsh + +logging = log.getLogger('avocado.' + __name__) +cleanup = [] + + +def get_kernel_cmdline(vm): + """ + Returns /proc/cmdline + + :param vm: VM instance + """ + with vm.wait_for_login() as session: + _, o = cmd_status_output("cat /proc/cmdline", + session=session, + ignore_status=False, + shell=True) + return o.strip() + + +def decrypt(dump_file, decrypted_dump_dir, comm_key): + """ + Decrypt the dumped file with a communication key. + + :param dump_file: path to the memory dump + :param decrypted_dump_dir: where to mount the decrypted + dump + :param comm_key: string with the communication key + """ + cmd = "echo %s > %s" % (comm_key, "comm_key.txt") + cmd_status_output(cmd, ignore_status=False, shell=True) + cmd = "zgetdump -k comm_key.txt %s -m %s" % (dump_file, decrypted_dump_dir) + cmd_status_output(cmd, ignore_status=False, shell=True) + cleanup.append(lambda: cmd_status_output("umount %s" % decrypted_dump_dir)) + + +def confirm_contains(decrypted_dump_file, text, test): + """ + Confirm that given text can be found in file. + This confirms the file has been decrypted correctly. + + :param decrypted_dump_file: The path of the .elf file + of the decrypted dump + :param text: string to be found + :param test: test instance + """ + s, _ = cmd_status_output("strings -d %s|grep -m 1 '%s'" % (decrypted_dump_file, text), + shell=True) + if s: + test.fail("Couldn't find expected text in dump file.") + + +def run(test, params, env): + """ + Decrypt encrypted memory dump. + Assumes the guest is running in with + SE and has been encrypted with the tested + communication key. + """ + + vm_name = params.get('main_vm') + vm = env.get_vm(vm_name) + comm_key = params.get("comm_key") + dump_file = "/tmp/DUMP" + decrypted_dump_dir = "/mnt" + decrypted_dump_file = os.path.join(decrypted_dump_dir, "dump.elf") + + try: + cmdline = get_kernel_cmdline(vm) + virsh.dump(vm_name, dump_file, "--memory-only", + ignore_status=False, debug=True) + cleanup.append(lambda: os.remove(dump_file)) + + decrypt(dump_file, decrypted_dump_dir, comm_key) + confirm_contains(decrypted_dump_file, cmdline, test) + + finally: + for c in reversed(cleanup): + c() diff --git a/spell.ignore b/spell.ignore index b97ffbb03c..ffd6ad5ed0 100644 --- a/spell.ignore +++ b/spell.ignore @@ -180,6 +180,9 @@ datetime DAX dbus de +decrypt +decrypted +decryption deduplicate del deplist