Skip to content

Commit

Permalink
tools: add script for building of buildroot images
Browse files Browse the repository at this point in the history
We used to use Debian-based images, but they have several issues:
1. They boot too slowly (we don't need full systemd power).
2. Systemd mounts cgroup controllers so that we can't use them during fuzzing
   (can be mounted only once).
3. We have poor control over contents of the image.

This script creates lightweight buildroot-based images that boot fast.
  • Loading branch information
dvyukov authored and a-nogikh committed Oct 18, 2021
1 parent 0c5d941 commit 24dc29d
Showing 1 changed file with 221 additions and 0 deletions.
221 changes: 221 additions & 0 deletions tools/create-buildroot-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#!/usr/bin/env bash
# Copyright 2021 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

# This script builds a buildroot-based Linux image.
# It should be run from a buildroot checkout (git://git.buildroot.net/buildroot) as:
# TARGETARCH={amd64,arm64,arm,riscv64,s390x,mips64le,ppc64le} [NOMAKE=yes] create-buildroot-image.sh
# If no NOMAKE=yes is specified, then it will just prepare the buildroot config,
# but will not run the final make.
# For amd64 it creates a bootable image with root partition
# on /dev/sda1 in output/images/disk.img file.
# For other architectures it creates a non-bootable disk
# suitable qemu injected boot with root partition on /dev/sda
# in output/images/rootfs.ext4 file.
# Note: the image requires at least kernel v4.19
# (otherwise glibc complains about unsupported kernel version).

set -eux

NOMAKE="${NOMAKE:-}"
TARGETARCH="${TARGETARCH:-amd64}"
case "$TARGETARCH" in
amd64)
DEFCONFIG="pc_x86_64_bios_defconfig";;
arm64)
DEFCONFIG="qemu_aarch64_virt_defconfig";;
arm)
DEFCONFIG="qemu_arm_vexpress_defconfig";;
riscv64)
DEFCONFIG="qemu_riscv64_virt_defconfig";;
s390x)
DEFCONFIG="qemu_s390x_defconfig";;
mips64le)
DEFCONFIG="qemu_mips64r6el_malta_defconfig";;
ppc64le)
DEFCONFIG="qemu_ppc64le_pseries_defconfig";;
*)
echo "unsupported TARGETARCH=${TARGETARCH}"
exit 1;;
esac

git fetch origin
git checkout 2021.08.x

make "${DEFCONFIG}"

# Common configs for all architectures.
cat >>.config <<EOF
BR2_TARGET_GENERIC_HOSTNAME="syzkaller"
BR2_TARGET_GENERIC_ISSUE="syzkaller"
BR2_ROOTFS_POST_FAKEROOT_SCRIPT="./rootfs_script.sh"
BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
BR2_PACKAGE_DHCPCD=y
BR2_PACKAGE_OPENSSH=y
# This slows down boot.
# BR2_PACKAGE_URANDOM_SCRIPTS is not set
BR2_TARGET_ROOTFS_EXT2_SIZE="1G"
# Slightly more interesting and realistic options.
BR2_TARGET_ROOTFS_EXT2_MKFS_OPTIONS="-O 64bit,ext_attr,encrypt,verity,extents,huge_file,flex_bg,dir_nlink,sparse_super,resize_inode,has_journal"
# Install firmware for USB devices we can connect during fuzzing.
BR2_PACKAGE_LINUX_FIRMWARE=y
BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7650=y
BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E=y
BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E=y
BR2_PACKAGE_LINUX_FIRMWARE_AR3012_USB=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX=y
BR2_PACKAGE_LINUX_FIRMWARE_LIBERTAS_USB8388_V9=y
BR2_PACKAGE_LINUX_FIRMWARE_LIBERTAS_USB8388_OLPC=y
BR2_PACKAGE_LINUX_FIRMWARE_LIBERTAS_USB_THINFIRM=y
BR2_PACKAGE_LINUX_FIRMWARE_MWIFIEX_USB8797=y
BR2_PACKAGE_LINUX_FIRMWARE_MWIFIEX_USB8801=y
BR2_PACKAGE_LINUX_FIRMWARE_MWIFIEX_USB8897=y
BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT61=y
BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT73=y
BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y
BR2_PACKAGE_LINUX_FIRMWARE_AS102=y
BR2_PACKAGE_LINUX_FIRMWARE_DIB0700=y
BR2_PACKAGE_LINUX_FIRMWARE_ITETECH_IT9135=y
BR2_PACKAGE_LINUX_FIRMWARE_CX231XX=y
BR2_PACKAGE_LINUX_FIRMWARE_QUALCOMM_WIL6210=y
# This one we could use, but it breaks buildroot:
# Makefile.legacy:9: *** You have legacy configuration in your .config! Please check your configuration.
# BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_10K_QCA6174=y
BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_10K_QCA998X=y
BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_10K_QCA9377=y
BR2_PACKAGE_ZD1211_FIRMWARE=y
# These packages seem to enable rfkill (and are unnecessary).
# BR2_PACKAGE_CONNMAN is not set
# BR2_PACKAGE_WPA_SUPPLICANT is not set
# These packages enable SELinux policy.
BR2_PACKAGE_LIBSELINUX=y
BR2_PACKAGE_REFPOLICY=y
BR2_PACKAGE_REFPOLICY_POLICY_STATE_PERMISSIVE=y
# BR2_PACKAGE_REFPOLICY_POLICY_STATE_ENFORCING is not set
# BR2_PACKAGE_REFPOLICY_POLICY_STATE_DISABLED is not set
EOF

# Per-arch config fragments.
case "$TARGETARCH" in
amd64)
cat >>.config <<EOF
BR2_TARGET_GENERIC_GETTY_PORT="ttyS0"
BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="board/qemu/x86_64/linux.config"
# This is used to create some device links in devfs (see udev rules below),
# but this is too slow for emulated architectures.
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
EOF
;;
arm64)
cat >>.config <<EOF
BR2_cortex_a57=y
# Kernel is not needed for non-bootable images.
# BR2_LINUX_KERNEL is not set
EOF
;;
arm)
cat >>.config <<EOF
BR2_cortex_a57=y
# BR2_LINUX_KERNEL is not set
EOF
;;
s390x)
cat >>.config <<EOF
# BR2_LINUX_KERNEL is not set
EOF
;;
mips64le)
cat >>.config <<EOF
# BR2_LINUX_KERNEL is not set
EOF
;;
ppc64le)
cat >>.config <<EOF
# BR2_LINUX_KERNEL is not set
EOF
;;
riscv64)
cat >>.config <<EOF
# BR2_LINUX_KERNEL is not set
EOF
;;
esac

# This script modifies the target root filesystem
# before it's packed into the final image.
# This part is common for all architectures.
cat >rootfs_script.sh <<'EOFEOF'
set -eux
# Mount debugfs for KCOV and other filesystems.
cat >>$1/etc/fstab <<EOF
debugfs /sys/kernel/debug debugfs defaults 0 0
securityfs /sys/kernel/security securityfs defaults 0 0
configfs /sys/kernel/config/ configfs defaults 0 0
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0
smackfs /sys/fs/smackfs smackfs defaults 0 0
selinuxfs /sys/fs/selinux selinuxfs defaults 0 0
fusectl /sys/fs/fuse/connections fusectl defaults 0 0
pstore /sys/fs/pstore pstore defaults 0 0
bpf /sys/fs/bpf bpf defaults 0 0
mqueue /dev/mqueue mqueue defaults 0 0
hugetlbfs /dev/hugepages hugetlbfs defaults 0 0
tracefs /sys/kernel/tracing tracefs defaults 0 0
fuse.lxcfs /var/lib/lxcfs fuse.lxcfs defaults 0 0
EOF
# Setup ssh without key/password.
cat >$1/etc/ssh/sshd_config <<EOF
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords yes
ClientAliveInterval 420
EOF
# Generate sshd host keys.
ssh-keygen -A -f $1
mkdir -p $1/var/db/dhcpcd
EOFEOF

# Per-arch part of the rootfs script.
case "$TARGETARCH" in
amd64)
cat >>rootfs_script.sh <<'EOFEOF'
# Write udev rules.
cat >$1/etc/udev/rules.d/50-syzkaller.rules <<EOF
ATTR{name}=="vim2m", SYMLINK+="vim2m"
SUBSYSTEMS=="pci", DRIVERS=="i915", SYMLINK+="i915"
EOF
for i in {0..31}; do
echo "KERNEL==\"binder$i\", NAME=\"binder$i\", MODE=\"0666\"" >> $1/etc/udev/rules.d/50-syzkaller.rules
done
# Override default grub config with timeout 0.
cat >$1/boot/grub/grub.cfg <<EOF
set default="0"
set timeout="0"
menuentry "syzkaller" {
linux /boot/bzImage root=/dev/sda1 console=ttyS0
}
EOF
EOFEOF
;;
esac

chmod u+x rootfs_script.sh

make olddefconfig

if [[ "$NOMAKE" == "" ]]; then
make
fi

0 comments on commit 24dc29d

Please sign in to comment.