github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/create-gce-image.sh (about) 1 #!/usr/bin/env bash 2 # Copyright 2016 syzkaller project authors. All rights reserved. 3 # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 4 5 # create-gce-image.sh creates a minimal bootable image suitable for syzkaller/GCE in ./disk.raw file. 6 # The script can also create/delete temp files in the current dir. 7 # 8 # Prerequisites: 9 # - you need a user-space system, a basic Debian system can be created with: 10 # sudo debootstrap --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc,selinux-utils,policycoreutils,checkpolicy,selinux-policy-default,firmware-atheros --components=main,contrib,non-free stable debian 11 # - you need kernel to use with image (e.g. arch/x86/boot/bzImage) 12 # note: kernel modules are not supported 13 # - you need grub: 14 # sudo apt-get install grub-efi 15 # 16 # Usage: 17 # ./create-gce-image.sh /dir/with/user/space/system /path/to/{zImage,bzImage} [arch] 18 # 19 # If SYZ_SYSCTL_FILE env var is set and points to a file, 20 # then its contents will be appended to the image /etc/sysctl.conf. 21 # If SYZ_CMDLINE_FILE env var is set and points to a file, 22 # then its contents will be appended to the kernel command line. 23 # If MKE2FS_CONFIG env var is set, it will affect invoked mkfs.ext4. 24 # 25 # The image then needs to be compressed with: 26 # tar -Sczf disk.tar.gz disk.raw 27 # and uploaded to GCS with: 28 # gsutil cp disk.tar.gz gs://my-images/image.tar.gz 29 # finally, my-images/image.tar.gz can be used to create a new GCE image. 30 # 31 # The image can be tested locally with e.g.: 32 # qemu-system-x86_64 -hda disk.raw -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 \ 33 # -net nic -enable-kvm -m 2G -display none -serial stdio 34 # once the kernel boots, you can ssh into it with: 35 # ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -p 10022 root@localhost 36 37 set -eux 38 39 CLEANUP="" 40 trap 'eval " $CLEANUP"' EXIT 41 42 IMG_ARCH="${3:-amd64}" 43 44 if [ ! -e $1/sbin/init ]; then 45 echo "usage: create-gce-image.sh /dir/with/user/space/system /path/to/bzImage [arch]" 46 exit 1 47 fi 48 49 case "$IMG_ARCH" in 50 386|amd64|s390x) 51 KERNEL_IMAGE_BASENAME=bzImage 52 ;; 53 ppc64le) 54 KERNEL_IMAGE_BASENAME=zImage.pseries 55 ;; 56 esac 57 58 if [ "$(basename $2)" != "$KERNEL_IMAGE_BASENAME" ]; then 59 echo "usage: create-gce-image.sh /dir/with/user/space/system /path/to/bzImage [arch]" 60 exit 1 61 fi 62 63 # qemu-nbd is broken on Debian with: 64 # Calling ioctl() to re-read partition table. 65 # Re-reading the partition table failed.: Invalid argument 66 # The kernel still uses the old table. The new table will be used at the 67 # next reboot or after you run partprobe(8) or kpartx(8). 68 # losetup is broken on Ubuntu with some other error. 69 # Try to figure out what will work. 70 BLOCK_DEVICE="loop" 71 if [ "$(uname -a | grep Ubuntu)" != "" ]; then 72 BLOCK_DEVICE="nbd" 73 fi 74 75 # Clean up after previous unsuccessful run. 76 sudo umount disk.mnt || true 77 if [ "$BLOCK_DEVICE" == "loop" ]; then 78 : 79 elif [ "$BLOCK_DEVICE" == "nbd" ]; then 80 sudo modprobe nbd 81 sudo qemu-nbd -d /dev/nbd0 || true 82 fi 83 rm -rf disk.mnt disk.raw || true 84 85 fallocate -l 2G disk.raw 86 if [ "$BLOCK_DEVICE" == "loop" ]; then 87 DISKDEV="$(sudo losetup -f --show -P disk.raw)" 88 CLEANUP="sudo losetup -d $DISKDEV; $CLEANUP" 89 elif [ "$BLOCK_DEVICE" == "nbd" ]; then 90 DISKDEV="/dev/nbd0" 91 sudo qemu-nbd -c $DISKDEV --format=raw disk.raw 92 CLEANUP="sudo qemu-nbd -d $DISKDEV; $CLEANUP" 93 fi 94 95 case "$IMG_ARCH" in 96 386|amd64|s390x) 97 echo -en "o\nn\np\n1\n\n\na\nw\n" | sudo fdisk $DISKDEV 98 PARTDEV=$DISKDEV"p1" 99 ;; 100 ppc64le) 101 # Create a small PowerPC PReP boot partition, and a Linux partition for the rest 102 echo -en "o\nn\np\n1\n2048\n16383\na\nt\n41\nn\np\n2\n\n\nw\n" | sudo fdisk $DISKDEV 103 PARTDEV=$DISKDEV"p2" 104 ;; 105 esac 106 107 until [ -e $PARTDEV ]; do sleep 1; done 108 sudo -E mkfs.ext4 -O ^resize_inode,^has_journal,ext_attr,extents,huge_file,flex_bg,dir_nlink,sparse_super $PARTDEV 109 mkdir -p disk.mnt 110 CLEANUP="rm -rf disk.mnt; $CLEANUP" 111 sudo mount $PARTDEV disk.mnt 112 CLEANUP="sudo umount disk.mnt; $CLEANUP" 113 sudo cp -a $1/. disk.mnt/. 114 sudo cp $2 disk.mnt/vmlinuz 115 sudo sed -i "/^root/ { s/:x:/::/ }" disk.mnt/etc/passwd 116 echo "T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100" | sudo tee -a disk.mnt/etc/inittab 117 echo -en "auto lo\niface lo inet loopback\nauto eth0\niface eth0 inet dhcp\n" | sudo tee disk.mnt/etc/network/interfaces 118 echo '/dev/root / ext4 defaults 0 0' | sudo tee -a disk.mnt/etc/fstab 119 echo "debugfs /sys/kernel/debug debugfs defaults 0 0" | sudo tee -a disk.mnt/etc/fstab 120 echo "securityfs /sys/kernel/security securityfs defaults 0 0" | sudo tee -a disk.mnt/etc/fstab 121 echo "configfs /sys/kernel/config/ configfs defaults 0 0" | sudo tee -a disk.mnt/etc/fstab 122 echo 'binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0' | sudo tee -a disk.mnt/etc/fstab 123 for i in {0..31}; do 124 echo "KERNEL==\"binder$i\", NAME=\"binder$i\", MODE=\"0666\"" | \ 125 sudo tee -a disk.mnt/etc/udev/50-binder.rules 126 done 127 128 # Add udev rules for custom drivers. 129 # Create a /dev/vim2m symlink for the device managed by the vim2m driver 130 echo 'ATTR{name}=="vim2m", SYMLINK+="vim2m"' | sudo tee -a disk.mnt/etc/udev/rules.d/50-udev-default.rules 131 132 # Create a /dev/i915 symlink to /dev/dri/card# if i915 driver is in use. 133 echo 'SUBSYSTEMS=="pci", DRIVERS=="i915", SYMLINK+="i915"' | sudo tee -a disk.mnt/etc/udev/rules.d/60-drm.rules 134 135 # sysctls 136 SYZ_SYSCTL_FILE="${SYZ_SYSCTL_FILE:-}" 137 if [ "$SYZ_SYSCTL_FILE" != "" ]; then 138 cat $SYZ_SYSCTL_FILE | sudo tee -a disk.mnt/etc/sysctl.conf 139 fi 140 141 echo -en "127.0.0.1\tlocalhost\n" | sudo tee disk.mnt/etc/hosts 142 echo "nameserver 8.8.8.8" | sudo tee -a disk.mnt/etc/resolve.conf 143 echo "syzkaller" | sudo tee disk.mnt/etc/hostname 144 sudo mkdir -p disk.mnt/boot/grub 145 146 # Setup ssh without key/password. 147 cat << EOF | sudo tee disk.mnt/etc/ssh/sshd_config 148 PermitRootLogin yes 149 PasswordAuthentication yes 150 PermitEmptyPasswords yes 151 ClientAliveInterval 420 152 Subsystem sftp /usr/lib/openssh/sftp-server 153 EOF 154 # Reset root password. 155 sudo sed -i "s#^root:\*:#root::#g" disk.mnt/etc/shadow 156 157 CMDLINE="" 158 SYZ_CMDLINE_FILE="${SYZ_CMDLINE_FILE:-}" 159 if [ "$SYZ_CMDLINE_FILE" != "" ]; then 160 CMDLINE=$(awk '{printf("%s ", $0)}' $SYZ_CMDLINE_FILE) 161 fi 162 163 case "$IMG_ARCH" in 164 386|amd64) 165 cat << EOF | sudo tee disk.mnt/boot/grub/grub.cfg 166 terminal_input console 167 terminal_output console 168 set timeout=0 169 # vsyscall=native: required to run x86_64 executables on android kernels 170 # (for some reason they disable VDSO by default) 171 # panic=86400: prevents kernel from rebooting so that we don't get reboot output in all crash reports 172 # debug is not set as it produces too much output 173 menuentry 'linux' --class gnu-linux --class gnu --class os { 174 insmod vbe 175 insmod vga 176 insmod video_bochs 177 insmod video_cirrus 178 insmod gzio 179 insmod part_msdos 180 insmod ext2 181 set root='(hd0,1)' 182 linux /vmlinuz root=/dev/sda1 console=ttyS0 earlyprintk=serial vsyscall=native net.ifnames=0 sysctl.kernel.hung_task_all_cpu_backtrace=1 $CMDLINE 183 } 184 EOF 185 sudo grub-install --target=i386-pc --boot-directory=disk.mnt/boot --no-floppy $DISKDEV 186 ;; 187 ppc64le) 188 cat << EOF | sudo tee disk.mnt/boot/grub/grub.cfg 189 terminal_input console 190 terminal_output console 191 set timeout=0 192 # panic=86400: prevents kernel from rebooting so that we don't get reboot output in all crash reports 193 # debug is not set as it produces too much output 194 menuentry 'linux' --class gnu-linux --class gnu --class os { 195 insmod gzio 196 insmod part_msdos 197 insmod ext2 198 search -f --set /vmlinuz 199 linux /vmlinuz root=/dev/sda2 rootwait console=ttyS0 earlyprintk=serial oops=panic panic_on_warn=1 nmi_watchdog=panic panic=60 net.ifnames=0 $CMDLINE 200 } 201 EOF 202 sudo grub-install --target=powerpc-ieee1275 --boot-directory=disk.mnt/boot $DISKDEV"p1" 203 ;; 204 s390x) 205 sudo zipl -V -t disk.mnt/boot -i disk.mnt/vmlinuz \ 206 -P "root=/dev/vda1 console=ttyS0 earlyprintk=serial oops=panic panic_on_warn=1 nmi_watchdog=panic panic=86400 net.ifnames=0 sysctl.kernel.hung_task_all_cpu_backtrace=1 net.ifnames=0 biosdevname=0 $CMDLINE" \ 207 --targetbase=$DISKDEV --targettype=SCSI --targetblocksize=512 --targetoffset=2048 208 ;; 209 esac