diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 15db0bf1..a09c354b 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -878,6 +878,8 @@ typedef struct { int boot_dfd; char *kernel_srcpath; char *kernel_namever; + char *kernel_hmac_srcpath; + char *kernel_hmac_namever; char *initramfs_srcpath; char *initramfs_namever; char *devicetree_srcpath; @@ -890,6 +892,8 @@ _ostree_kernel_layout_free (OstreeKernelLayout *layout) glnx_close_fd (&layout->boot_dfd); g_free (layout->kernel_srcpath); g_free (layout->kernel_namever); + g_free (layout->kernel_hmac_srcpath); + g_free (layout->kernel_hmac_namever); g_free (layout->initramfs_srcpath); g_free (layout->initramfs_namever); g_free (layout->devicetree_srcpath); @@ -1032,6 +1036,16 @@ get_kernel_from_tree_usrlib_modules (int deployment_dfd, g_clear_object (&in); glnx_close_fd (&fd); + /* And finally, look for any HMAC file. This is needed for FIPS mode on some distros. */ + if (!glnx_fstatat_allow_noent (ret_layout->boot_dfd, ".vmlinuz.hmac", NULL, 0, error)) + return FALSE; + if (errno == 0) + { + ret_layout->kernel_hmac_srcpath = g_strdup (".vmlinuz.hmac"); + /* Name it as dracut expects it: https://github.com/dracutdevs/dracut/blob/225e4b94cbdb702cf512490dcd2ad9ca5f5b22c1/modules.d/01fips/fips.sh#L129 */ + ret_layout->kernel_hmac_namever = g_strdup_printf (".%s.hmac", ret_layout->kernel_namever); + } + char hexdigest[OSTREE_SHA256_STRING_LEN+1]; ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); ret_layout->bootcsum = g_strdup (hexdigest); @@ -1686,6 +1700,20 @@ install_deployment_kernel (OstreeSysroot *sysroot, } } + if (kernel_layout->kernel_hmac_srcpath) + { + if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->kernel_hmac_namever, &stbuf, 0, error)) + return FALSE; + if (errno == ENOENT) + { + if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath, + bootcsum_dfd, kernel_layout->kernel_hmac_namever, + sysroot->debug_flags, + cancellable, error)) + return FALSE; + } + } + g_autofree char *contents = NULL; if (!glnx_fstatat_allow_noent (deployment_dfd, "usr/lib/os-release", &stbuf, 0, error)) return FALSE; diff --git a/tests/libtest.sh b/tests/libtest.sh index 8832e63c..ba00073a 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -395,6 +395,8 @@ setup_os_repository () { mkdir -p usr/bin ${bootdir} usr/lib/modules/${kver} usr/share usr/etc kernel_path=${bootdir}/vmlinuz initramfs_path=${bootdir}/initramfs.img + # the HMAC file is only in /usr/lib/modules + hmac_path=usr/lib/modules/${kver}/.vmlinuz.hmac # /usr/lib/modules just uses "vmlinuz", since the version is in the module # directory name. if [[ $bootdir != usr/lib/modules/* ]]; then @@ -403,6 +405,7 @@ setup_os_repository () { fi echo "a kernel" > ${kernel_path} echo "an initramfs" > ${initramfs_path} + echo "an hmac file" > ${hmac_path} bootcsum=$(cat ${kernel_path} ${initramfs_path} | sha256sum | cut -f 1 -d ' ') export bootcsum # Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not diff --git a/tests/test-admin-deploy-none.sh b/tests/test-admin-deploy-none.sh index 66a1491f..09dee624 100755 --- a/tests/test-admin-deploy-none.sh +++ b/tests/test-admin-deploy-none.sh @@ -43,6 +43,7 @@ ${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os testos assert_file_has_content out.txt "Bootloader updated.*" assert_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'options.* root=LABEL=MOO' assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel' +assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/.vmlinuz-3.6.0.hmac 'an hmac file' assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0.img 'an initramfs' echo "ok generate bls config on first deployment"