Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add path excludes, kernel module allowlisting #1

Merged
merged 8 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 118 additions & 98 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,65 +11,67 @@ source config
CONFIGURATION_FOLDER="${CONFIGURATION_ROOT}"$1

export OUT_DIR=$PWD/out_image
source ${CONFIGURATION_FOLDER}/build.parameters
source ${CONFIGURATION_FOLDER}/components.parameters
source "${CONFIGURATION_FOLDER}"/build.parameters
source "${CONFIGURATION_FOLDER}"/components.parameters

echo ${CONFIGURATION_FOLDER}
echo ${TARGET_DEVICE}
echo "${CONFIGURATION_FOLDER}"
echo "${TARGET_DEVICE}"

rm -rf build
rm initramfs
rm -rf $OUT_DIR
mkdir -p build
mkdir $OUT_DIR

export OUT_DIR=$PWD/out_image
rm -rf build
rm -f initramfs
rm -rf $OUT_DIR
mkdir -p build
mkdir $OUT_DIR
rm -rf "${OUT_DIR}"
mkdir "${OUT_DIR}"

mkdir -p build/usr/bin
mkdir -p build/usr/lib
cd build
cd build || exit
ln -s usr/bin bin
ln -s usr/lib lib
cd ..
export ROOTFS_DIR=$PWD/build
export DPKG_ROOT=$ROOTFS_DIR
export TOP="${PWD}"

sed "s%PWD%${PWD}%" cfg/apt.cfg > apt.cfg
sed --in-place "s%REALROOTREL%$(realpath -s --relative-to=$PWD /)/%" apt.cfg
export APT_CONFIG=$PWD/apt.cfg
# export DPKG_EXTRA_ARGS="--instdir=${DPKG_ROOT}"
# Relies on GNU sed extension (/dev/stdin file for 'r' command)
sed '/^#/d;s/^/ "--/;s/$/";/' cfg/dpkg_extra_args | \
sed "
s%PWD%${PWD}%
s%REALROOTREL%$(realpath -s --relative-to="$PWD" /)/%
/DPKG_EXTRA_ARGS/{r /dev/stdin
d}" cfg/apt.cfg > apt.cfg

KERNEL_VERSION_STR="6.6.31+rpt-rpi-v8"
export APT_CONFIG=$PWD/apt.cfg
DPKG_EXTRA_ARGS="$(sed '/^#/d;s/^/--/' "${CONFIGURATION_FOLDER}"/dpkg_extra_args | xargs)"

apt_download() {
apt-get install --download-only $@
apt-get install --download-only "$@"
}

# Can't use install until it's possible to chroot
apt_install() {
apt-get install $@ --no-install-recommends
apt-get install "$@" --no-install-recommends
}

get_package_path() {
# Not fully URL-encoded (no spec found)
PKG_VERSION=$(apt-cache policy "$1" | grep -oP 'Candidate: \K.*' | sed 's/:/%3a/')
echo "$(find apt/cache/archives/ -name ${1}_${PKG_VERSION}*)"
find apt/cache/archives/ -name "${1}_${PKG_VERSION}*"
}

dpkg_unpack() {
apt_download $1
dpkg ${DPKG_EXTRA_ARGS} --no-triggers --unpack $(get_package_path $1)
apt_download "$1"
set -o noglob
# shellcheck disable=SC2086
dpkg ${DPKG_EXTRA_ARGS} --no-triggers --unpack "$(get_package_path $1)"
set +o noglob
}

dpkg_install() {
apt_download $1
dpkg ${DPKG_EXTRA_ARGS} --install $(get_package_path $1)
apt_download "$1"
set -o noglob
# shellcheck disable=SC2086
dpkg ${DPKG_EXTRA_ARGS} --install "$(get_package_path $1)"
set +o noglob
}

apt-get update
Expand All @@ -82,25 +84,27 @@ PACKAGE_PATH="$(get_package_path libc6-udeb)"
EXTRACT_DIR="$(mktemp --directory --tmpdir deb-extract.XXX)"
dpkg-deb --raw-extract "${PACKAGE_PATH}" "${EXTRACT_DIR}"
rm "${PACKAGE_PATH}"
LIBC_VERSION="$(grep -oP '^Version:\s*\K.*' ${EXTRACT_DIR}/DEBIAN/control)"
LIBC_VERSION="$(grep -oP '^Version:\s*\K.*' "${EXTRACT_DIR}"/DEBIAN/control)"
sed --in-place "/^Provides:/s/libc6,/libc6 (= ${LIBC_VERSION}),/" "${EXTRACT_DIR}/DEBIAN/control"
echo "Replaces: libc6 (= ${LIBC_VERSION})
Conflicts: libc6 (= ${LIBC_VERSION})" >> "${EXTRACT_DIR}/DEBIAN/control"
dpkg-deb --build "${EXTRACT_DIR}" "${PACKAGE_PATH}"
rm -rf "${EXTRACT_DIR}"
set -o noglob
# shellcheck disable=SC2086
dpkg ${DPKG_EXTRA_ARGS} --install "${PACKAGE_PATH}"
set +o noglob

dpkg_install busybox

pushd build
cd bin
cd build/bin || exit
ln -s busybox sh
ln -s mawk awk
echo '#!/bin/sh' > update-alternatives
echo 'return 0' >> update-alternatives
chmod +x update-alternatives
cp update-alternatives dpkg-trigger
popd
cd - || exit

# awk is Pre-Depends of base-files (unfortunately)
dpkg_install mawk
Expand Down Expand Up @@ -147,7 +151,7 @@ apt_install openssl
# Tiny debconf for libpam0g (systemd dep)
apt_install cdebconf-udeb cdebconf-text-udeb
sed --in-place 's/newt/text/g' build/etc/cdebconf.conf
if [ ${SSH} = 1 ]
if [ "${SSH}" = 1 ]
then
echo "Installing SSH!"
apt_install dropbear-bin
Expand All @@ -164,23 +168,21 @@ apt_install systemd-sysv
rm build/bin/dpkg-maintscript-helper
rm build/bin/dpkg

IFS=', ' read -r -a array <<< "$(cat ${CONFIGURATION_FOLDER}/packages.list | tr '\n' ', ')"
echo ${array}
IFS=', ' read -r -a array <<< "$(< "${CONFIGURATION_FOLDER}"/packages.list tr '\n' ', ')"

for package in "${array[@]}"
do
echo "Installing $package"
#dpkg ${DPKG_EXTRA_ARGS} --install $package
apt_install $package
echo "Installing ${package}"
apt_install "${package}"
done

pushd ${CONFIGURATION_FOLDER}
cd "${CONFIGURATION_FOLDER}" || exit
./installer_scripts.list
popd
cd "${TOP}" || exit

apt_install kmod

if [ ${UDEV} = 1 ]
if [ "${UDEV}" = 1 ]
then
echo "Installing UDEV!"
# libc-bin required for passwd postinst
Expand All @@ -200,9 +202,9 @@ then
apt-get --fix-broken install
fi

if [ ${NETWORK} = 1 ]
if [ "${NETWORK}" = 1 ]
then
if [ ${UDEV} = 1 ]
if [ "${UDEV}" = 1 ]
then
echo "Installing & Enabling networking"
cp prebuilts/20-wired.network build/etc/systemd/network/20-wired.network
Expand All @@ -220,10 +222,11 @@ fi
# Symlink to regular /sbin/init
# ln -s /sbin/init build/init

if [ ${AUTOLOGIN} = 1 ]
if [ "${AUTOLOGIN}" = 1 ]
then
# Ensure getty on tty1 is autologin
mkdir -p build/etc/systemd/system/getty@tty1.service.d
# shellcheck disable=SC2028
echo "[Service]
ExecStart=
ExecStart=-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin root %I \$TERM
Expand Down Expand Up @@ -261,40 +264,86 @@ apt-get --fix-broken install

apt_download raspi-firmware
RASPI_FIRMWARE_TMPDIR=$(mktemp -d)
cd "${RASPI_FIRMWARE_TMPDIR}"
ar -x $(find ${TOP}/apt/cache/archives/ -name raspi-firmware* | sort | tail -1)
cd "${RASPI_FIRMWARE_TMPDIR}" || exit
ar -x "$(find "${TOP}"/apt/cache/archives/ -name 'raspi-firmware*' | sort | tail -1)"
tar xvf data.tar.xz ./
mv ./usr/lib/raspi-firmware/* ${DPKG_ROOT}/boot/
cd -
mv ./usr/lib/raspi-firmware/* "${DPKG_ROOT}"/boot/
cd - || exit
rm -rf "${RASPI_FIRMWARE_TMPDIR}"

# Find kernel
KERNEL_META=linux-image-rpi-v8
apt_download $KERNEL
apt_download "${KERNEL}"
KERNEL_PACKAGE=$(apt-cache depends $KERNEL_META | grep -oP 'Depends: \K.*')
KERNEL_VERSION_STR=${KERNEL_PACKAGE#linux-image-}

# TODO: This leaves apt in a broken state, see what we can do here.
dpkg_unpack ${KERNEL_PACKAGE}
KPKG_EXTRACT="$(mktemp --directory --tmpdir kernel_package.XXX)"
dpkg-deb --raw-extract "$(get_package_path "${KERNEL_PACKAGE}")" "${KPKG_EXTRACT}"

# Copy requested kernel modules (+deps) into image and generate module dependencies
depmod --basedir "${KPKG_EXTRACT}" "${KERNEL_VERSION_STR}"
cd "${KPKG_EXTRACT}" >/dev/null || exit
module_paths=()
get_deps() {
local module_name=$1

# shellcheck disable=SC2046
readarray -t file_deps <<<$(modinfo --basedir . -k "${KERNEL_VERSION_STR}" "${module_name}" | grep -oP '^(?:filename|depends):\s+\K.*')
module_paths+=("${file_deps[0]}")

if [ ${#file_deps[@]} -eq "2" ]
then
# shellcheck disable=SC2086
readarray -t -d , deps <<<${file_deps[1]}
for dep in "${deps[@]}"
do
# shellcheck disable=SC2086
get_deps $dep
done
fi
}
for dep in $(sed '/^#/d' "${CONFIGURATION_FOLDER}"/kernel_modules.list | xargs)
do
# shellcheck disable=SC2086
get_deps $dep
done
cd - || exit
printf "
${KPKG_EXTRACT}/./lib/modules/${KERNEL_VERSION_STR}/modules.order
${KPKG_EXTRACT}/./lib/modules/${KERNEL_VERSION_STR}/modules.builtin
${KPKG_EXTRACT}/./lib/modules/${KERNEL_VERSION_STR}/modules.builtin.modinfo
%s
" "${module_paths[@]}" | sort | uniq | \
rsync \
--perms \
--times \
--group \
--owner \
--acls \
--xattrs \
--files-from=- \
/ \
"${ROOTFS_DIR}/"
depmod --basedir "${ROOTFS_DIR}" "${KERNEL_VERSION_STR}"

# Manually form-up the kernel and bootfs
mkdir -p ${OUT_DIR}/overlays
mkdir -p "${OUT_DIR}"/overlays
# mv ${DPKG_ROOT}/boot/vmlinuz-${KERNEL_VERSION_STR} ${OUT_DIR}/zImage
mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/broadcom/*.dtb ${OUT_DIR}/
mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/overlays/*.dtb* ${OUT_DIR}/overlays/
mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/overlays/README ${OUT_DIR}/overlays/
mv ${DPKG_ROOT}/boot/* ${OUT_DIR}/
mv "${DPKG_ROOT}"/usr/lib/linux-image-"${KERNEL_VERSION_STR}"/broadcom/*.dtb "${OUT_DIR}"/
mv "${DPKG_ROOT}"/usr/lib/linux-image-"${KERNEL_VERSION_STR}"/overlays/*.dtb* "${OUT_DIR}"/overlays/
mv "${DPKG_ROOT}"/usr/lib/linux-image-"${KERNEL_VERSION_STR}"/overlays/README "${OUT_DIR}"/overlays/
mv "${DPKG_ROOT}"/boot/* "${OUT_DIR}"/

mkdir build/data/
cp prebuilts/config.txt ${OUT_DIR}/config.txt
cp prebuilts/cmdline.txt ${OUT_DIR}/cmdline.txt
cp prebuilts/config.txt "${OUT_DIR}"/config.txt
cp prebuilts/cmdline.txt "${OUT_DIR}"/cmdline.txt
# apt_install debconf

dpkg_unpack linux-image-${KERNEL_VERSION_STR}
dpkg_unpack linux-image-"${KERNEL_VERSION_STR}"

# # Manually form-up the kernel and bootfs
# mkdir -p ${OUT_DIR}/overlays
mv ${DPKG_ROOT}/boot/vmlinuz-${KERNEL_VERSION_STR} ${OUT_DIR}/kernel8.img
mv "${DPKG_ROOT}"/boot/vmlinuz-"${KERNEL_VERSION_STR}" "${OUT_DIR}"/kernel8.img
# mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/broadcom/*.dtb ${OUT_DIR}/
# mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/overlays/*.dtb* ${OUT_DIR}/overlays/
# mv ${DPKG_ROOT}/usr/lib/linux-image-${KERNEL_VERSION_STR}/overlays/README ${OUT_DIR}/overlays/
Expand All @@ -312,7 +361,7 @@ cp -r packages/built/bin/* build/usr/bin/
# Copy init
cp prebuilts/init build/init
# ln build/usr/sbin /sbin
cd build/sbin
cd build/sbin || exit
rm init

ln -s /usr/lib/systemd/systemd init
Expand All @@ -321,56 +370,27 @@ ln -s /bin/udevadm /lib/systemd/systemd-udevd
cd ..

mkdir build/data/
cp prebuilts/config.txt ${OUT_DIR}/config.txt
cp prebuilts/cmdline.txt ${OUT_DIR}/cmdline.txt
cp prebuilts/config.txt "${OUT_DIR}"/config.txt
cp prebuilts/cmdline.txt "${OUT_DIR}"/cmdline.txt
cp prebuilts/cryptkey-fetch build/bin/
cp prebuilts/vcmailbox build/bin/
cp prebuilts/vcgencmd build/bin/
mkdir build/usr/local/bin
cp prebuilts/rpi-otp-private-key build/usr/local/bin

mkdir build/usr/share/udhcpc/
cp prebuilts/network.script build/usr/share/udhcpc/network.script




# Copy staged modules
# pushd /mnt/src/debian/systemd-252.26/
# sudo ./build_and_copy.sh
# popd

# cp -r staged_build/* build

# Copy modules.dep
# cp -r prebuilts/lib/. build/lib/
# cp -r prebuilts/usr build/
# cp -r prebuilts/etc/* build/etc/

# rm build/usr/lib/systemd/system/systemd-firstboot.service
# rm build/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service
# cp prebuilts/getty@.service build/usr/lib/systemd/system/getty@.service
# cp prebuilts/serial-getty@.service build/usr/lib/systemd/system/serial-getty@.service
# cp prebuilts/serial-getty@.service build/etc/systemd/system/serial-getty@.service
cp prebuilts/vcmailbox build/sbin/vcmailbox
cp prebuilts/vcgenmd build/sbin/vcgenmd

## Fix up systemd-modules-load
cp prebuilts/load_modules.sh build/usr/local/bin/load_modules
cp prebuilts/systemd-modules-load.service build/etc/systemd/system/systemd-modules-load.service


echo "SSH VARIABLE WAS $SSH"

if [ ${SSH} = 1 ]
if [ "${SSH}" = 1 ]
then
echo "Installing SSH!"
mkdir -p build/root/.ssh
echo $(cat prebuilts/authorized_keys) > build/root/.ssh/authorized_keys
cat prebuilts/authorized_keys > build/root/.ssh/authorized_keys
chmod 0600 build/root/.ssh/authorized_keys
mkdir build/dev/pts
fi
echo $(cat prebuilts/authorized_keys) > build/root/.ssh/authorized_keys
cat prebuilts/authorized_keys > build/root/.ssh/authorized_keys
chmod 0600 build/root/.ssh/authorized_keys
mkdir build/dev/pts

Expand All @@ -382,12 +402,12 @@ systemd-timesync:x:107:
kvm:*:1023" >> build/etc/group

# Package initramfs
cd build
cd build || exit
find . -print0 | cpio --null -ov --format=newc > ../initramfs.cpio 2>/dev/null
cd ..
zstd --no-progress --rm -15 initramfs.cpio -o ${OUT_DIR}/rootfs.cpio.zst
zstd --no-progress --rm -15 initramfs.cpio -o "${OUT_DIR}"/rootfs.cpio.zst

echo "Making boot img"
echo "Out directory = ${OUT_DIR}"
mkdir -p ${OUT_DIR}
make-boot-image -d ${OUT_DIR}/ -o ${OUT_IMAGE_NAME} -a ${KERNEL_BIT_SIZE}
mkdir -p "${OUT_DIR}"
make-boot-image -d "${OUT_DIR}"/ -o "${OUT_IMAGE_NAME}" -a "${KERNEL_BIT_SIZE}"
8 changes: 1 addition & 7 deletions cfg/apt.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,7 @@ DPkg
{
Options {
"--root=PWD/build";
"--path-exclude=*/share/doc/*";
"--path-include=*/share/doc/*/copyright";
"--path-exclude=*/share/man/*";
"--path-exclude=*/share/groff/*";
"--path-exclude=*/share/info/*";
"--path-exclude=*/share/lintian/*";
"--path-exclude=*/share/linda/*";
DPKG_EXTRA_ARGS
}
Chroot-Directory "REALROOTREL";
Run-Directory "REALROOTREL";
Expand Down
Loading