diskimage-builder/elements/iso/cleanup.d/100-build-iso
Shivanand Tendulker f0315b4ed4 Fix to load only signed kernel in UEFI secure boot
This fix prevents loading of unsigned ubuntu kernel in UEFI secure
boot environment when image is created using 'iso' element.

'iso' element uses 'linux' and 'initrd' modules of grub2 to load
kernel and initrd respectively. The grub2 implementation of Ubuntu
can load unsigned kernel when these modules are used.

Ubuntu has Grub2 modules 'linuxefi' and 'initrdefi' which exits
boot process if unsigned kernel is used in UEFI secure boot mode.
The 'iso' element should use these modules in grub.cfg to prevent
loading of unsigned kernel when node is booted in the UEFI secure
boot environment.

'linuxefi' and 'initrdefi' works seamlessly when node is booted in
normal UEFI boot mode (non-secure).

Fedora do not have this issue. This fix has been tested in Fedora
environment. It works fine.

Closes-Bug: 1443114
Change-Id: If256ba1f7d7c149482d0f37fabcdfa8ed22e3f91
2015-04-13 13:20:12 +00:00

165 lines
5.3 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
if [ ${DIB_DEBUG_TRACE:-1} -gt 0 ]; then
set -x
fi
set -eu
set -o pipefail
function build_efiboot_img() {
# Signed bootloader files are saved at tmp/bootloader_files during
# post-install stage needs to copy them into image.
# Signed bootloader packages used are:-
# Ubuntu: grub-efi-amd64-signed and shim-signed
# Fedora: grub2-efi and shim
if [ $DISTRO_NAME = "fedora" ]; then
cp $TMP_BOOTLOADER_DIR/shim.efi $TMP_BUILD_DIR/bootx64.efi
cp $TMP_BOOTLOADER_DIR/grubx64.efi $TMP_BUILD_DIR/grubx64.efi
else
cp $TMP_BOOTLOADER_DIR/shim.efi.signed $TMP_BUILD_DIR/bootx64.efi
cp $TMP_BOOTLOADER_DIR/grubx64.efi.signed $TMP_BUILD_DIR/grubx64.efi
fi
dd if=/dev/zero of=$TMP_BUILD_DIR/efiboot.img bs=1K count=5760
mkdosfs -F 12 $TMP_BUILD_DIR/efiboot.img
# Create a temporary mount point:
MOUNTPOINT=$TMP_BUILD_DIR/tmpmount
mkdir $MOUNTPOINT
sudo mount -o loop $TMP_BUILD_DIR/efiboot.img $MOUNTPOINT
sudo mkdir -p $MOUNTPOINT/EFI/BOOT
sudo cp $TMP_BUILD_DIR/bootx64.efi $MOUNTPOINT/EFI/BOOT
sudo cp $TMP_BUILD_DIR/grubx64.efi $MOUNTPOINT/EFI/BOOT
sudo umount $MOUNTPOINT
rmdir $MOUNTPOINT
cp $TMP_BUILD_DIR/efiboot.img $TMP_IMAGE_DIR/isolinux
}
function build_iso() {
KERNEL=$1
INITRD=$2
KERNEL_CMDLINE_ARGS=$3
OUTPUT_FILENAME=$4
SCRIPTNAME=$(basename $0)
SCRIPTDIR=$(dirname $0)
MKISOFS="/usr/bin/mkisofs"
if [ $DISTRO_NAME = "fedora" ]; then
EFI_BOOT_DIR="EFI/fedora"
EXTRA_KERNEL_PARAMS="usbcore.autosuspend=-1"
else
EFI_BOOT_DIR="EFI/ubuntu"
EXTRA_KERNEL_PARAMS=""
fi
# Create a temporary build directory for holiding the contents of iso
TMP_IMAGE_DIR="$TMP_BUILD_DIR/image"
echo "Creating temporary directory $TMP_IMAGE_DIR"
mkdir -p "$TMP_IMAGE_DIR"
# Copy isolinux bin to the isolinux directory
mkdir -p "$TMP_IMAGE_DIR/isolinux"
echo "Copying isolinux.bin"
ISOLINUX_BIN=$TMP_BOOTLOADER_DIR/isolinux.bin
cp $ISOLINUX_BIN "$TMP_IMAGE_DIR/isolinux"
# Copy initrd, kernel
echo "Copying kernel to $TMP_IMAGE_DIR/vmlinuz"
cp $KERNEL "$TMP_IMAGE_DIR/vmlinuz"
echo "Copying initrd to $TMP_IMAGE_DIR/initrd"
cp $INITRD "$TMP_IMAGE_DIR/initrd"
# Generate isolinux.cfg for default booting
echo "Generating isolinux.cfg"
cat > "$TMP_IMAGE_DIR/isolinux/isolinux.cfg" << END_CONFIG
DEFAULT install
LABEL install
menu label "Install image"
kernel /vmlinuz
append initrd=/initrd $KERNEL_CMDLINE_ARGS --
TIMEOUT 5
PROMPT 0
END_CONFIG
echo "Creating EFI/ubuntu directory"
mkdir -p "$TMP_IMAGE_DIR/$EFI_BOOT_DIR"
# Generate grub.cfg for default booting
echo "Generating grub.cfg"
cat > "$TMP_IMAGE_DIR/$EFI_BOOT_DIR/grub.cfg" << END_CONFIG
set default="0"
set timeout="5"
set hidden_timeout_quiet=false
menuentry "install" {
search --set=root --label VMEDIA_BOOT_ISO
linuxefi /vmlinuz $EXTRA_KERNEL_PARAMS $KERNEL_CMDLINE_ARGS --
initrdefi /initrd
}
END_CONFIG
build_efiboot_img
# Create the ISO
echo "Generating the ISO"
$MKISOFS -r -V "VMEDIA_BOOT_ISO" -cache-inodes -J -l \
-b isolinux/isolinux.bin -no-emul-boot \
-boot-load-size 4 -boot-info-table \
-eltorito-alt-boot -e isolinux/efiboot.img \
-no-emul-boot -o $OUTPUT_FILENAME $TMP_IMAGE_DIR
}
IMAGE_NAME=${IMAGE_NAME:-'image'}
if echo $IMAGE_ELEMENT | grep -q '\bramdisk\b'; then
EMITTED_KERNEL=$IMAGE_NAME.kernel
EMITTED_RAMDISK=$IMAGE_NAME.initramfs
EMITTED_KERNEL_CMDLINE_ARGS="boot_method=vmedia"
EMITTED_ISO_FILENAME=$IMAGE_NAME.iso
elif echo $IMAGE_ELEMENT | grep -q '\bironic-agent\b'; then
EMITTED_KERNEL=$IMAGE_NAME.vmlinuz
EMITTED_RAMDISK=$IMAGE_NAME.initramfs
EMITTED_KERNEL_CMDLINE_ARGS="boot_method=vmedia"
EMITTED_ISO_FILENAME=$IMAGE_NAME.iso
elif echo $IMAGE_ELEMENT | grep -q '\bbaremetal\b'; then
EMITTED_KERNEL=${IMAGE_NAME}.vmlinuz
EMITTED_RAMDISK=${IMAGE_NAME}.initrd
EMITTED_KERNEL_CMDLINE_ARGS="root=UUID=$DIB_IMAGE_ROOT_FS_UUID"
DIB_BOOT_ISO_KERNEL_CMDLINE_ARGS=${DIB_BOOT_ISO_KERNEL_CMDLINE_ARGS:-}
if [ -n "$DIB_BOOT_ISO_KERNEL_CMDLINE_ARGS" ]; then
EMITTED_KERNEL_CMDLINE_ARGS="$EMITTED_KERNEL_CMDLINE_ARGS $DIB_BOOT_ISO_KERNEL_CMDLINE_ARGS"
fi
export EMITTED_ISO_FILENAME="$IMAGE_NAME-boot.iso"
else
echo "Cannot find the kernel/ramdisk to build the iso image. "
echo "Please use 'iso' element with either 'baremetal' or 'ramdisk' elements"
fi
export TMP_BOOTLOADER_DIR=$TARGET_ROOT/tmp/bootloader_files
build_iso "$EMITTED_KERNEL" "$EMITTED_RAMDISK" "$EMITTED_KERNEL_CMDLINE_ARGS" \
"$EMITTED_ISO_FILENAME"
# Clean-up the bootloaders directory
sudo rm -fr $TMP_BOOTLOADER_DIR