-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcreate-image.sh
More file actions
executable file
·219 lines (193 loc) · 7.08 KB
/
create-image.sh
File metadata and controls
executable file
·219 lines (193 loc) · 7.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/env bash
# Copyright 2016 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.
# create-image.sh creates a minimal Debian Linux image suitable for syzkaller.
# @Andrea
# This script is based on:
# (*) https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh
#
# Changelog 2025-02-08
# =======
# - modified to remove selinux and other stuffs that are not relevant for
# our use-cases;
# - removed support for sudo in script commands. We are supposing to run
# this script in a container where we are already root;
# - added VMHOSTNAME;
# - removed creation of udev rule vim2m driver;
# - changed networking in the rootfs as new kernels do not use eth* names for
# devices anymore. In this case, eth* has been changed into enp* which is
# the name the kernel expects for a device like virtio-net-pci.
# Specifically, in case of a single interface and in a qemu 'user' network
# configuration, eth0 has been changed in enp0s3.
set -eux
# Create a minimal Debian distribution in a directory.
PREINSTALL_PKGS=openssh-server,curl,tar,gcc,vim,iperf3,tmux,screen,libc6-dev,time,strace,sudo,less,psmisc,debian-ports-archive-keyring
# If ADD_PACKAGE is not defined as an external environment variable, use our default packages
if [ -z ${ADD_PACKAGE+x} ]; then
ADD_PACKAGE="make,sysbench,git,vim,tmux,usbutils,tcpdump"
fi
# Variables affected by options
ARCH=$(uname -m)
RELEASE=bookworm
FEATURE=minimal
SEEK=2047
PERF=false
VMHOSTNAME=vmtest
# Display help function
display_help() {
echo "Usage: $0 [option...] " >&2
echo
echo " -a, --arch Set architecture"
echo " -d, --distribution Set on which debian distribution to create"
echo " -f, --feature Check what packages to install in the image, options are minimal, full"
echo " -s, --seek Image size (MB), default 2048 (2G)"
echo " -h, --help Display help message"
echo " -p, --add-perf Add perf support with this option enabled. Please set envrionment variable \$KERNEL at first"
echo
}
while true; do
if [ $# -eq 0 ];then
echo $#
break
fi
case "$1" in
-h | --help)
display_help
exit 0
;;
-a | --arch)
ARCH=$2
shift 2
;;
-d | --distribution)
RELEASE=$2
shift 2
;;
-f | --feature)
FEATURE=$2
shift 2
;;
-s | --seek)
SEEK=$(($2 - 1))
shift 2
;;
-p | --add-perf)
PERF=true
shift 1
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*) # No more options
break
;;
esac
done
# Handle cases where qemu and Debian use different arch names
case "$ARCH" in
ppc64le)
DEBARCH=ppc64el
;;
aarch64)
DEBARCH=arm64
;;
arm)
DEBARCH=armel
;;
x86_64)
DEBARCH=amd64
;;
*)
DEBARCH=$ARCH
;;
esac
# Foreign architecture
FOREIGN=false
if [ $ARCH != $(uname -m) ]; then
# i386 on an x86_64 host is exempted, as we can run i386 binaries natively
if [ $ARCH != "i386" -o $(uname -m) != "x86_64" ]; then
FOREIGN=true
fi
fi
if [ $FOREIGN = "true" ]; then
# Check for according qemu static binary
if ! which qemu-$ARCH-static; then
echo "Please install qemu static binary for architecture $ARCH (package 'qemu-user-static' on Debian/Ubuntu/Fedora)"
exit 1
fi
# Check for according binfmt entry
if [ ! -r /proc/sys/fs/binfmt_misc/qemu-$ARCH ]; then
echo "binfmt entry /proc/sys/fs/binfmt_misc/qemu-$ARCH does not exist"
exit 1
fi
fi
# Double check KERNEL when PERF is enabled
if [ $PERF = "true" ] && [ -z ${KERNEL+x} ]; then
echo "Please set KERNEL environment variable when PERF is enabled"
exit 1
fi
# If full feature is chosen, install more packages
if [ $FEATURE = "full" ]; then
PREINSTALL_PKGS=$PREINSTALL_PKGS","$ADD_PACKAGE
fi
DIR=$RELEASE
rm -rf $DIR
mkdir -p $DIR
chmod 0755 $DIR
# 1. debootstrap stage
DEBOOTSTRAP_PARAMS="--arch=$DEBARCH --include=$PREINSTALL_PKGS --components=main,contrib,non-free,non-free-firmware $RELEASE $DIR"
if [ $FOREIGN = "true" ]; then
DEBOOTSTRAP_PARAMS="--foreign $DEBOOTSTRAP_PARAMS"
fi
# riscv64 is hosted in the debian-ports repository
# debian-ports doesn't include non-free, so we exclude firmware-atheros
if [ $DEBARCH == "riscv64" ]; then
DEBOOTSTRAP_PARAMS="--keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg --exclude firmware-atheros $DEBOOTSTRAP_PARAMS http://deb.debian.org/debian-ports"
fi
# debootstrap may fail for EoL Debian releases
RET=0
debootstrap $DEBOOTSTRAP_PARAMS || RET=$?
if [ $RET != 0 ] && [ $DEBARCH != "riscv64" ]; then
# Try running debootstrap again using the Debian archive
DEBOOTSTRAP_PARAMS="--keyring /usr/share/keyrings/debian-archive-removed-keys.gpg $DEBOOTSTRAP_PARAMS https://archive.debian.org/debian-archive/debian/"
debootstrap $DEBOOTSTRAP_PARAMS
fi
# 2. debootstrap stage: only necessary if target != host architecture
if [ $FOREIGN = "true" ]; then
cp $(which qemu-$ARCH-static) $DIR/$(which qemu-$ARCH-static)
chroot $DIR /bin/bash -c "/debootstrap/debootstrap --second-stage"
fi
# Set some defaults and enable promtless ssh to the machine for root.
sed -i '/^root/ { s/:x:/::/ }' $DIR/etc/passwd
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | tee -a $DIR/etc/inittab
printf '\nauto enp0s3\niface enp0s3 inet dhcp\n' | tee -a $DIR/etc/network/interfaces
echo '/dev/root / ext4 defaults 0 0' | tee -a $DIR/etc/fstab
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | tee -a $DIR/etc/fstab
mkdir -p $DIR/mnt/shared && \
echo 'shared /mnt/shared 9p trans=virtio,version=9p2000.L 0 0' | tee -a $DIR/etc/fstab
echo -en "127.0.0.1\tlocalhost\n" | tee $DIR/etc/hosts
echo "nameserver 8.8.8.8" | tee $DIR/etc/resolv.conf
echo $VMHOSTNAME | tee $DIR/etc/hostname
ssh-keygen -f $RELEASE.id_rsa -t rsa -N ''
mkdir -p $DIR/root/.ssh/
cat $RELEASE.id_rsa.pub | tee $DIR/root/.ssh/authorized_keys
# Add perf support
if [ $PERF = "true" ]; then
cp -r $KERNEL $DIR/tmp/
BASENAME=$(basename $KERNEL)
chroot $DIR /bin/bash -c "apt-get update; apt-get install -y flex bison python-dev libelf-dev libunwind8-dev libaudit-dev libslang2-dev libperl-dev binutils-dev liblzma-dev libnuma-dev"
chroot $DIR /bin/bash -c "cd /tmp/$BASENAME/tools/perf/; make"
chroot $DIR /bin/bash -c "cp /tmp/$BASENAME/tools/perf/perf /usr/bin/"
rm -r $DIR/tmp/$BASENAME
fi
# Add udev rules for custom drivers.
# Create a /dev/vim2m symlink for the device managed by the vim2m driver
# echo 'ATTR{name}=="vim2m", SYMLINK+="vim2m"' | tee -a $DIR/etc/udev/rules.d/50-udev-default.rules
# Build a disk image
dd if=/dev/zero of=$RELEASE.img bs=1M seek=$SEEK count=1
mkfs.ext4 -F $RELEASE.img
mkdir -p /mnt/$DIR
mount -o loop $RELEASE.img /mnt/$DIR
cp -a $DIR/. /mnt/$DIR/.
umount /mnt/$DIR