mirror of
https://github.com/systemd/systemd.git
synced 2025-03-23 10:50:16 +03:00
Merge pull request #24025 from DaanDeMeyer/mkosi-sanitizers
mkosi: Changes to allow booting with sanitizers in mkosi
This commit is contained in:
commit
e99e4e4fec
@ -66,7 +66,7 @@ reuse the host's package cache. To do this, create a mkosi override file in
|
||||
mkosi.default.d/ (e.g 20-local.conf) and add the following contents:
|
||||
|
||||
```
|
||||
[Packages]
|
||||
[Content]
|
||||
Cache=<full-path-to-package-manager-cache> # (e.g. /var/cache/dnf)
|
||||
```
|
||||
|
||||
@ -140,6 +140,11 @@ enabled that are suitable when hacking on systemd (such as internal
|
||||
documentation consistency checks). Those are not useful when compiling for
|
||||
distribution and can be disabled by setting `-Dmode=release`.
|
||||
|
||||
## Sanitizers in mkosi
|
||||
|
||||
See [Testing systemd using sanitizers](TESTING_WITH_SANITIZERS.md) for more information
|
||||
on how to build with sanitizers enabled in mkosi.
|
||||
|
||||
## Fuzzers
|
||||
|
||||
systemd includes fuzzers in `src/fuzz/` that use libFuzzer and are automatically
|
||||
@ -224,7 +229,7 @@ mkosi's config. The easiest way to set the option is to create a file 20-local.c
|
||||
add the following contents:
|
||||
|
||||
```
|
||||
[Packages]
|
||||
[Content]
|
||||
IncludeDirectory=mkosi.includedir
|
||||
```
|
||||
|
||||
@ -233,7 +238,7 @@ We already configured clangd to map any paths in /usr/include in the build image
|
||||
host in the mkosi-clangd.sh script.
|
||||
|
||||
We also need to make sure clangd is installed in the build image. To have mkosi install clangd in the build
|
||||
image, edit the 20-local.conf file we created earlier and add the following contents under the `[Packages]`
|
||||
image, edit the 20-local.conf file we created earlier and add the following contents under the `[Content]`
|
||||
section:
|
||||
|
||||
```
|
||||
|
@ -13,6 +13,22 @@ This is mostly done automagically by various CI systems for each PR, but you may
|
||||
want to do it locally as well. The process slightly varies depending on the
|
||||
compiler you want to use and which part of the test suite you want to run.
|
||||
|
||||
## mkosi
|
||||
|
||||
To build with sanitizers in mkosi, create a file 20-local.conf in mkosi.default.d/ and add the following
|
||||
contents:
|
||||
|
||||
```
|
||||
[Content]
|
||||
Environment=SANITIZERS=address,undefined
|
||||
```
|
||||
|
||||
The value of `SANITIZERS` is passed directly to meson's `b_sanitize` option, See
|
||||
https://mesonbuild.com/Builtin-options.html#base-options for the format expected by the option. Currently,
|
||||
only the sanitizers supported by gcc can be used, which are `address` and `undefined`.
|
||||
|
||||
Note that this will only work with a recent version of mkosi (>= 14 or by running mkosi directly from source).
|
||||
|
||||
## gcc
|
||||
gcc compiles in sanitizer libraries dynamically by default, so you need to get
|
||||
the shared libraries first - on Fedora these are shipped as a separate packages
|
||||
|
94
mkosi.build
94
mkosi.build
@ -5,6 +5,9 @@ set -e
|
||||
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
|
||||
# Simply invoke "mkosi" in the project directory to build an OS image.
|
||||
|
||||
ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1
|
||||
UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
|
||||
|
||||
# On Fedora "ld" is (unfortunately — if you ask me) managed via
|
||||
# "alternatives". Since we'd like to support building images in environments
|
||||
# with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem
|
||||
@ -49,10 +52,10 @@ if [ ! -f "$BUILDDIR"/build.ninja ] ; then
|
||||
|
||||
init_path=$(realpath /sbin/init 2>/dev/null)
|
||||
if [ -z "$init_path" ] ; then
|
||||
rootprefix=""
|
||||
rootprefix=""
|
||||
else
|
||||
rootprefix=${init_path%/lib/systemd/systemd}
|
||||
rootprefix=/${rootprefix#/}
|
||||
rootprefix=${init_path%/lib/systemd/systemd}
|
||||
rootprefix=/${rootprefix#/}
|
||||
fi
|
||||
|
||||
meson "$BUILDDIR" \
|
||||
@ -60,7 +63,9 @@ if [ ! -f "$BUILDDIR"/build.ninja ] ; then
|
||||
-D "rootprefix=$rootprefix" \
|
||||
-D man=false \
|
||||
-D translations=false \
|
||||
-D version-tag="${VERSION_TAG}"
|
||||
-D version-tag="${VERSION_TAG}" \
|
||||
-D mode=developer \
|
||||
-D b_sanitize="${SANITIZERS:-none}"
|
||||
fi
|
||||
|
||||
cd "$BUILDDIR"
|
||||
@ -70,7 +75,15 @@ if [ "$WITH_TESTS" = 1 ] ; then
|
||||
getent group $id >/dev/null || groupadd -g $id testgroup$id
|
||||
done
|
||||
|
||||
ninja test
|
||||
if [ -n "$SANITIZERS" ]; then
|
||||
export ASAN_OPTIONS="$ASAN_OPTIONS"
|
||||
export UBSAN_OPTIONS="$UBSAN_OPTIONS"
|
||||
TIMEOUT_MULTIPLIER=3
|
||||
else
|
||||
TIMEOUT_MULTIPLIER=1
|
||||
fi
|
||||
|
||||
meson test --timeout-multiplier=$TIMEOUT_MULTIPLIER
|
||||
fi
|
||||
cd "$SRCDIR"
|
||||
|
||||
@ -90,32 +103,71 @@ Kernel \r on an \m (\l)
|
||||
EOF
|
||||
|
||||
if [ -n "$IMAGE_ID" ] ; then
|
||||
mkdir -p "$DESTDIR"/usr/lib
|
||||
sed -n \
|
||||
-e '/^IMAGE_ID=/!p' \
|
||||
-e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release"
|
||||
mkdir -p "$DESTDIR"/usr/lib
|
||||
sed -n \
|
||||
-e '/^IMAGE_ID=/!p' \
|
||||
-e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release"
|
||||
|
||||
OSRELEASEFILE="$DESTDIR"/usr/lib/os-release
|
||||
OSRELEASEFILE="$DESTDIR"/usr/lib/os-release
|
||||
else
|
||||
OSRELEASEFILE=/usr/lib/os-release
|
||||
OSRELEASEFILE=/usr/lib/os-release
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$IMAGE_VERSION" ] ; then
|
||||
mkdir -p "$DESTDIR"/usr/lib
|
||||
sed -n \
|
||||
-e '/^IMAGE_VERSION=/!p' \
|
||||
-e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp"
|
||||
mkdir -p "$DESTDIR"/usr/lib
|
||||
sed -n \
|
||||
-e '/^IMAGE_VERSION=/!p' \
|
||||
-e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp"
|
||||
|
||||
cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release
|
||||
rm /tmp/os-release.tmp
|
||||
cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release
|
||||
rm /tmp/os-release.tmp
|
||||
fi
|
||||
|
||||
# If $CI_BUILD is set, copy over the CI service which executes a service check
|
||||
# after boot and then shuts down the machine
|
||||
if [ -n "$CI_BUILD" ]; then
|
||||
mkdir -p "$DESTDIR/usr/lib/systemd/system"
|
||||
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service"
|
||||
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
||||
chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
||||
mkdir -p "$DESTDIR/usr/lib/systemd/system"
|
||||
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service"
|
||||
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
||||
chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
||||
fi
|
||||
|
||||
if [ -n "$SANITIZERS" ]; then
|
||||
LD_PRELOAD=$(ldd $BUILDDIR/systemd | grep libasan.so | awk '{print $3}')
|
||||
|
||||
mkdir -p "$DESTDIR/etc/systemd/system.conf.d"
|
||||
|
||||
cat > "$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF
|
||||
[Manager]
|
||||
ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
|
||||
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
|
||||
LD_PRELOAD=$LD_PRELOAD
|
||||
DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
|
||||
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
|
||||
LD_PRELOAD=$LD_PRELOAD
|
||||
EOF
|
||||
|
||||
# ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
|
||||
# all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any
|
||||
# sanitizer failures appear directly on the user's console.
|
||||
mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d"
|
||||
|
||||
cat > "$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF
|
||||
[Service]
|
||||
StandardOutput=tty
|
||||
EOF
|
||||
|
||||
# Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users.
|
||||
# This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As
|
||||
# a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login
|
||||
# from calling vhangup() so that journald's ASAN logs correctly end up in the console.
|
||||
|
||||
mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d"
|
||||
|
||||
cat > "$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF
|
||||
[Service]
|
||||
TTYVHangup=no
|
||||
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
|
||||
EOF
|
||||
fi
|
||||
|
@ -6,8 +6,10 @@
|
||||
Format=gpt_btrfs
|
||||
Bootable=yes
|
||||
HostonlyInitrd=yes
|
||||
# Prevent ASAN warnings when building the image
|
||||
Environment=ASAN_OPTIONS=verify_asan_link_order=false
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildDirectory=mkosi.builddir
|
||||
Cache=mkosi.cache
|
||||
InstallDirectory=mkosi.installdir
|
||||
@ -15,7 +17,8 @@ SourceFileTransferFinal=copy-git-others
|
||||
|
||||
[Host]
|
||||
QemuHeadless=yes
|
||||
NetworkVeth=yes
|
||||
Netdev=yes
|
||||
QemuMem=2G
|
||||
|
||||
[Validation]
|
||||
Password=
|
||||
|
@ -8,7 +8,7 @@
|
||||
[Distribution]
|
||||
Distribution=arch
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
acl
|
||||
bzip2
|
||||
@ -63,6 +63,8 @@ Packages=
|
||||
# For testing systemd's zsh completion scripts
|
||||
# Run `autoload -Uz compinit; compinit` from a zsh shell in the booted image to enable completions.
|
||||
zsh
|
||||
# xxd is provided by the vim package
|
||||
vim
|
||||
# Required to run systemd-networkd-tests.py
|
||||
python
|
||||
iproute
|
||||
|
@ -10,7 +10,7 @@ Distribution=centos_epel
|
||||
Format=gpt_xfs
|
||||
HostonlyInitrd=no
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
diffutils
|
||||
docbook-style-xsl
|
||||
@ -76,6 +76,10 @@ Packages=
|
||||
less
|
||||
netcat
|
||||
e2fsprogs
|
||||
# xxd is provided by the vim-common package
|
||||
vim-common
|
||||
libasan
|
||||
libubsan
|
||||
# Required to run systemd-networkd-tests.py
|
||||
python3
|
||||
iproute
|
||||
|
@ -7,7 +7,7 @@
|
||||
Distribution=debian
|
||||
Release=testing
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
acl
|
||||
clang
|
||||
@ -73,6 +73,9 @@ Packages=
|
||||
locales
|
||||
nano
|
||||
strace
|
||||
xxd
|
||||
# Provides libasan/libubsan
|
||||
gcc
|
||||
# Required to run systemd-networkd-tests.py
|
||||
python3
|
||||
iproute2
|
||||
|
@ -7,7 +7,7 @@
|
||||
Distribution=fedora
|
||||
Release=36
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
diffutils
|
||||
docbook-style-xsl
|
||||
@ -75,6 +75,11 @@ Packages=
|
||||
netcat
|
||||
e2fsprogs
|
||||
compsize
|
||||
# xxd is provided by the vim-common package
|
||||
vim-common
|
||||
# Sanitizers
|
||||
libasan
|
||||
libubsan
|
||||
# Required to run systemd-networkd-tests.py
|
||||
python
|
||||
iproute
|
||||
|
@ -7,7 +7,7 @@
|
||||
Distribution=opensuse
|
||||
Release=tumbleweed
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
docbook-xsl-stylesheets
|
||||
fdupes
|
||||
@ -73,3 +73,7 @@ Packages=
|
||||
nano
|
||||
strace
|
||||
util-linux
|
||||
# xxd is provided by the vim package
|
||||
vim
|
||||
# Provides libasan/libubsan
|
||||
gcc
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
[Distribution]
|
||||
Distribution=ubuntu
|
||||
Release=focal
|
||||
Release=jammy
|
||||
Repositories=main,universe
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
acl
|
||||
docbook-xml
|
||||
@ -71,6 +71,9 @@ Packages=
|
||||
locales
|
||||
nano
|
||||
strace
|
||||
xxd
|
||||
# Provides libasan/libubsan
|
||||
gcc
|
||||
# Required to run systemd-networkd-tests.py
|
||||
python3
|
||||
iproute2
|
||||
|
@ -1,8 +1,18 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if [ "$1" = "final" ] && command -v bootctl > /dev/null; then
|
||||
bootctl install
|
||||
if [ "$1" = "final" ]; then
|
||||
if command -v bootctl > /dev/null && [ -d "/efi" ]; then
|
||||
bootctl install
|
||||
fi
|
||||
|
||||
if [ -n "$SANITIZERS" ]; then
|
||||
# ASAN and syscall filters aren't compatible with each other.
|
||||
find / -name '*.service' -type f -exec sed -i 's/^\(MemoryDeny\|SystemCall\)/# \1/' {} +
|
||||
|
||||
# `systemd-hwdb update` takes > 50s when built with sanitizers so let's not run it by default.
|
||||
systemctl mask systemd-hwdb-update.service
|
||||
fi
|
||||
fi
|
||||
|
||||
# Temporary workaround until https://github.com/openSUSE/suse-module-tools/commit/158643414ddb8d8208016a5f03a4484d58944d7a
|
||||
|
@ -21,7 +21,7 @@ Output=networkd-test.raw
|
||||
[Partitions]
|
||||
RootSize=3G
|
||||
|
||||
[Packages]
|
||||
[Content]
|
||||
BuildPackages=
|
||||
audit-libs-devel
|
||||
bzip2-devel
|
||||
|
Loading…
x
Reference in New Issue
Block a user