From 2cf343764c53f2e9c189104f56b19727bad0effb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 18 Aug 2022 01:03:07 +0200 Subject: [PATCH 1/2] mkinitramfs: Put file copying in helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Ådahl --- virtme/mkinitramfs.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/virtme/mkinitramfs.py b/virtme/mkinitramfs.py index 1a21c9b..6980e7a 100644 --- a/virtme/mkinitramfs.py +++ b/virtme/mkinitramfs.py @@ -28,9 +28,12 @@ def make_dev_nodes(cw): cw.mkchardev(b'dev/kmsg', (1, 11), mode=0o666) cw.mkchardev(b'dev/console', (5, 1), mode=0o660) +def copy(cw, src, dst, mode): + with open(src, 'rb') as f: + cw.write_file(name=dst, body=f, mode=mode) + def install_busybox(cw, config): - with open(config.busybox, 'rb') as busybox: - cw.write_file(name=b'bin/busybox', body=busybox, mode=0o755) + copy(cw, config.busybox, b'bin/busybox', 0o755) for tool in ('sh', 'mount', 'umount', 'switch_root', 'sleep', 'mkdir', 'mknod', 'insmod', 'cp', 'cat'): From 3942705f2b8c7bc031286598a43529545948ec10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 18 Aug 2022 01:12:32 +0200 Subject: [PATCH 2/2] mkinitramfs: Copy DT_NEEDED files if any too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes using busybox installations that aren't really static, e.g. the one in Fedora 36 and 37, since they still need /lib/ld-musl-x86_64.so.1 to run. This uses elftools to parse. Signed-off-by: Jonas Ådahl --- virtme/mkinitramfs.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/virtme/mkinitramfs.py b/virtme/mkinitramfs.py index 6980e7a..71f27fe 100644 --- a/virtme/mkinitramfs.py +++ b/virtme/mkinitramfs.py @@ -14,6 +14,32 @@ import itertools from . import cpiowriter from . import util +from elftools.elf.elffile import ELFFile +from elftools.elf.dynamic import DynamicSection + +ld_paths = ['/lib', '/lib64', '/usr/lib', '/usr/lib64'] + +def is_dt_needed(tag): + return tag.entry.d_tag == 'DT_NEEDED' + +def find_library_path(needed): + for ld_path in ld_paths: + ld_path = os.path.join(ld_path, needed) + if os.path.isfile(ld_path): + return (ld_path, ld_path.lstrip('/')) + +def find_needed_paths(executable): + with open(executable, 'rb') as f: + elffile = ELFFile(f) + + dynamic = elffile.get_section_by_name('.dynamic') + if not dynamic: + return [] + + tags = dynamic.iter_tags() + neededs = [tag.needed for tag in tags if is_dt_needed(tag)] + + return [find_library_path(needed) for needed in neededs] def make_base_layout(cw): for dir in (b'lib', b'bin', b'var', b'etc', b'newroot', b'dev', b'proc', @@ -35,6 +61,9 @@ def copy(cw, src, dst, mode): def install_busybox(cw, config): copy(cw, config.busybox, b'bin/busybox', 0o755) + for (needed_path, target_path) in find_needed_paths(config.busybox): + copy(cw, needed_path, target_path.encode('ascii'), 0o755) + for tool in ('sh', 'mount', 'umount', 'switch_root', 'sleep', 'mkdir', 'mknod', 'insmod', 'cp', 'cat'): cw.symlink(b'busybox', ('bin/%s' % tool).encode('ascii'))