Package: initramfs-tools Version: 0.120ubuntu5~rc2 Severity: normal When adding firmware to the initramfs we currently use copy_exec() this leads to us running ldd on the firmware, and effectivly attempting to executing the firmware. As we have no control over the actual contents of this firmware this can lead to us actually executing it; in Ubuntu we have seen this with glibc.x32 installed and cirtain firmware leading to crashes in ldd and initramfs build failures.
Additionally using copy_exec() uses cp -aL which squashes any symlinks, while this ensures the firmware is available upstream firmware is starting to use the below idiom to represent preferred versions of firmware, and we will end up with multiple versions of the actual firmware in the initramfs: -rw-rw-r-- 1 apw apw 5872 Sep 19 08:51 bxt_dmc_ver1_04.bin lrwxrwxrwx 1 apw apw 19 Sep 19 08:51 bxt_dmc_ver1.bin -> bxt_dmc_ver1_04.bin -rw-rw-r-- 1 apw apw 8380 Sep 19 08:51 skl_dmc_ver1_19.bin -rw-rw-r-- 1 apw apw 8380 Sep 19 08:51 skl_dmc_ver1_20.bin -rw-rw-r-- 1 apw apw 8824 Sep 19 08:51 skl_dmc_ver1_21.bin lrwxrwxrwx 1 apw apw 19 Sep 19 08:51 skl_dmc_ver1.bin -> skl_dmc_ver1_21.bin -rw-rw-r-- 1 apw apw 109636 Sep 19 08:51 skl_guc_ver1_1059.bin lrwxrwxrwx 1 apw apw 21 Sep 19 08:51 skl_guc_ver1.bin -> skl_guc_ver1_1059.bin In Ubuntu we are using the combination of the two attached patches to solve these issues. -apw
>From f7d9025b736edbd771fc5befc256d556a2f4204b Mon Sep 17 00:00:00 2001 From: Andy Whitcroft <a...@canonical.com> Date: Mon, 17 Feb 2014 11:51:59 +0000 Subject: [PATCH 1/2] hook-functions: when copying firmware, don't use copy_exec When copying firmware, don't use copy_exec; running ldd on random firmware files is annoying and, if libc-x32 is installed, may cause crashes due to lack of kernel support. LP: #1115875 Signed-off-by: Andy Whitcroft <a...@canonical.com> --- hook-functions | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hook-functions b/hook-functions index ee1c205..0239d8a 100644 --- a/hook-functions +++ b/hook-functions @@ -101,10 +101,16 @@ manual_add_modules() fi if [ -e "/lib/firmware/${version}/${firmware}" ]; then - copy_exec "/lib/firmware/${version}/${firmware}" + firmware="/lib/firmware/$version/$firmware" else - copy_exec "/lib/firmware/${firmware}" + firmware="/lib/firmware/$firmware" fi + + target_dir="$DESTDIR/$(dirname "$firmware")" + if ! [ -d "$target_dir" ]; then + mkdir -p "$target_dir" + fi + cp -a "$firmware" "$target_dir" if [ "${verbose}" = "y" ]; then echo "Adding firmware ${firmware}" fi -- 2.5.0
>From 18816c491ca53a13e66e1c1e2de13efcd05c23c3 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft <a...@ubuntu.com> Date: Fri, 18 Sep 2015 15:08:29 +0100 Subject: [PATCH 2/2] hook-functions: firmware -- copy symlink components into initramfs It is becoming increasingly common to use symbolic links to map preferred versions of firmware where more than one is available: -rw-rw-r-- 1 apw apw 5872 Sep 19 08:51 bxt_dmc_ver1_04.bin lrwxrwxrwx 1 apw apw 19 Sep 19 08:51 bxt_dmc_ver1.bin -> bxt_dmc_ver1_04.bin -rw-rw-r-- 1 apw apw 8380 Sep 19 08:51 skl_dmc_ver1_19.bin -rw-rw-r-- 1 apw apw 8380 Sep 19 08:51 skl_dmc_ver1_20.bin -rw-rw-r-- 1 apw apw 8824 Sep 19 08:51 skl_dmc_ver1_21.bin lrwxrwxrwx 1 apw apw 19 Sep 19 08:51 skl_dmc_ver1.bin -> skl_dmc_ver1_21.bin -rw-rw-r-- 1 apw apw 109636 Sep 19 08:51 skl_guc_ver1_1059.bin lrwxrwxrwx 1 apw apw 21 Sep 19 08:51 skl_guc_ver1.bin -> skl_guc_ver1_1059.bin Detect, follow and copy symlink chains. LP: #1496163 Signed-off-by: Andy Whitcroft <a...@ubuntu.com> --- hook-functions | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/hook-functions b/hook-functions index 0239d8a..1ee246c 100644 --- a/hook-functions +++ b/hook-functions @@ -54,6 +54,7 @@ add_modules_from_file() manual_add_modules() { local prefix kmod options firmware + local target_dir depth firmware_link if [ $# -eq 0 ]; then return @@ -106,13 +107,35 @@ manual_add_modules() firmware="/lib/firmware/$firmware" fi - target_dir="$DESTDIR/$(dirname "$firmware")" - if ! [ -d "$target_dir" ]; then - mkdir -p "$target_dir" - fi - cp -a "$firmware" "$target_dir" - if [ "${verbose}" = "y" ]; then - echo "Adding firmware ${firmware}" + depth=10 + while [ "$firmware" != '' -a "$depth" -gt 0 ] + do + target_dir="$DESTDIR/$(dirname "$firmware")" + if ! [ -d "$target_dir" ]; then + mkdir -p "$target_dir" + fi + cp -a "$firmware" "$target_dir" + + if [ -L "$firmware" ]; then + if [ "${verbose}" = "y" ]; then + echo "Adding symlink ${firmware}" + fi + + depth=$(($depth-1)) + firmware_link=$(readlink "$firmware") + case "$firmware_link" in + /*) firmware="$firmware_link" ;; + *) firmware="$(dirname "$firmware")/$firmware_link" ;; + esac + else + if [ "${verbose}" = "y" ]; then + echo "Adding firmware ${firmware}" + fi + break + fi + done + if [ -L "$firmware" -a "${verbose}" = "y" ]; then + echo "Adding firmware ${firmware} -- hanging symlink" fi done done -- 2.5.0