diskimage-builder/elements/iso/cleanup.d/100-build-iso
Ian Wienand 672705831f Add a best-effort sudo safety check
As motivation for this; we have had two breakouts of dib in recent
memory.  One was a failure to unmount through symlinks in the core
code (I335316019ef948758392b03e91f9869102a472b9) and the other was
removing host keys on the build-system
(Ib01d71ff9415a0ae04d963f6e380aab9ac2260ce).

For the most part, dib runs unprivileged.  Bits of the core code are
hopefully well tested (modulo bugs like the first one!).  We give free
reign inside the chroot (although there is still some potential there
for adverse external affects via bind mounts).  Where we could be a
bit safer (and could have prevented at least the second of these
breakouts) is with some better checking that the "sudo" calls
*outside* the chroot at least looked sane.

This adds a basic check that we're using chroot or image paths when
calling sudo in those parts of elements that run *outside* the chroot.
Various files are updated to accomodate this check; mostly by just
ignoring it for existing code (I have not audited these calls).

Nobody is pretending this type of checking makes dib magically safe,
or removes the issues with it needing to do things as root during the
build.  But this can help find egregious errors like the key removal.

Change-Id: I161a5aea1d29dcdc7236f70d372c53246ec73749
2016-05-09 15:41:38 +10:00

182 lines
5.9 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.
# dib-lint: disable=safe_sudo
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"
#debian
elif [ $DISTRO_NAME = "debian" ]; then
EFI_BOOT_DIR="EFI/debian"
EXTRA_KERNEL_PARAMS=""
#ubuntu:
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
LDLINUX_BIN=$TMP_BOOTLOADER_DIR/ldlinux.c32
cp $ISOLINUX_BIN "$TMP_IMAGE_DIR/isolinux"
# Starting from SYSLINUX 5.00, the isolinux.bin is dependent
# on ldlinux.c32.
# http://www.syslinux.org/wiki/index.php/Library_modules
if [ -f "$LDLINUX_BIN" ]; then
cp $LDLINUX_BIN "$TMP_IMAGE_DIR/isolinux"
fi
# 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
DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS=${DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS:-}
EMITTED_KERNEL_CMDLINE_ARGS="boot_method=vmedia $DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS"
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
DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS=${DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS:-}
EMITTED_KERNEL_CMDLINE_ARGS="boot_method=vmedia $DIB_DEPLOY_ISO_KERNEL_CMDLINE_ARGS"
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