mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-07 17:17:44 +03:00
mkosi: Changes to allow booting with sanitizers in mkosi
- Extra memory because ASAN needs it
- The environment variables to make the sanitizers more useful
- LD_PRELOAD because the ASAN DSO needs to be the first in the list
- The sanitizer library packages
- Disable syscall filters because they interfere with ASAN
- Disable systemd-hwdb-update because it's super slow when systemd-hwdb
is built with sanitizers
- Take the value for meson's b_sanitize option from the SANITIZERS
environment variable
(cherry picked from commit 69d638e67e
)
This commit is contained in:
parent
db1281e12e
commit
47404f1802
@ -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
|
documentation consistency checks). Those are not useful when compiling for
|
||||||
distribution and can be disabled by setting `-Dmode=release`.
|
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
|
## Fuzzers
|
||||||
|
|
||||||
systemd includes fuzzers in `src/fuzz/` that use libFuzzer and are automatically
|
systemd includes fuzzers in `src/fuzz/` that use libFuzzer and are automatically
|
||||||
|
@ -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
|
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.
|
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
|
||||||
gcc compiles in sanitizer libraries dynamically by default, so you need to get
|
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
|
the shared libraries first - on Fedora these are shipped as a separate packages
|
||||||
|
56
mkosi.build
56
mkosi.build
@ -5,6 +5,9 @@ set -e
|
|||||||
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
|
# 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.
|
# 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
|
# On Fedora "ld" is (unfortunately — if you ask me) managed via
|
||||||
# "alternatives". Since we'd like to support building images in environments
|
# "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
|
# with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem
|
||||||
@ -60,7 +63,9 @@ if [ ! -f "$BUILDDIR"/build.ninja ] ; then
|
|||||||
-D "rootprefix=$rootprefix" \
|
-D "rootprefix=$rootprefix" \
|
||||||
-D man=false \
|
-D man=false \
|
||||||
-D translations=false \
|
-D translations=false \
|
||||||
-D version-tag="${VERSION_TAG}"
|
-D version-tag="${VERSION_TAG}" \
|
||||||
|
-D mode=developer \
|
||||||
|
-D b_sanitize="${SANITIZERS:-none}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd "$BUILDDIR"
|
cd "$BUILDDIR"
|
||||||
@ -70,7 +75,15 @@ if [ "$WITH_TESTS" = 1 ] ; then
|
|||||||
getent group $id >/dev/null || groupadd -g $id testgroup$id
|
getent group $id >/dev/null || groupadd -g $id testgroup$id
|
||||||
done
|
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
|
fi
|
||||||
cd "$SRCDIR"
|
cd "$SRCDIR"
|
||||||
|
|
||||||
@ -119,3 +132,42 @@ if [ -n "$CI_BUILD" ]; then
|
|||||||
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
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"
|
chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
|
||||||
fi
|
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,6 +6,8 @@
|
|||||||
Format=gpt_btrfs
|
Format=gpt_btrfs
|
||||||
Bootable=yes
|
Bootable=yes
|
||||||
HostonlyInitrd=yes
|
HostonlyInitrd=yes
|
||||||
|
# Prevent ASAN warnings when building the image
|
||||||
|
Environment=ASAN_OPTIONS=verify_asan_link_order=false
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
BuildDirectory=mkosi.builddir
|
BuildDirectory=mkosi.builddir
|
||||||
@ -16,6 +18,7 @@ SourceFileTransferFinal=copy-git-others
|
|||||||
[Host]
|
[Host]
|
||||||
QemuHeadless=yes
|
QemuHeadless=yes
|
||||||
NetworkVeth=yes
|
NetworkVeth=yes
|
||||||
|
QemuMem=2G
|
||||||
|
|
||||||
[Validation]
|
[Validation]
|
||||||
Password=
|
Password=
|
||||||
|
@ -78,6 +78,8 @@ Packages=
|
|||||||
e2fsprogs
|
e2fsprogs
|
||||||
# xxd is provided by the vim-common package
|
# xxd is provided by the vim-common package
|
||||||
vim-common
|
vim-common
|
||||||
|
libasan
|
||||||
|
libubsan
|
||||||
# Required to run systemd-networkd-tests.py
|
# Required to run systemd-networkd-tests.py
|
||||||
python3
|
python3
|
||||||
iproute
|
iproute
|
||||||
|
@ -74,6 +74,8 @@ Packages=
|
|||||||
nano
|
nano
|
||||||
strace
|
strace
|
||||||
xxd
|
xxd
|
||||||
|
# Provides libasan/libubsan
|
||||||
|
gcc
|
||||||
# Required to run systemd-networkd-tests.py
|
# Required to run systemd-networkd-tests.py
|
||||||
python3
|
python3
|
||||||
iproute2
|
iproute2
|
||||||
|
@ -77,6 +77,9 @@ Packages=
|
|||||||
compsize
|
compsize
|
||||||
# xxd is provided by the vim-common package
|
# xxd is provided by the vim-common package
|
||||||
vim-common
|
vim-common
|
||||||
|
# Sanitizers
|
||||||
|
libasan
|
||||||
|
libubsan
|
||||||
# Required to run systemd-networkd-tests.py
|
# Required to run systemd-networkd-tests.py
|
||||||
python
|
python
|
||||||
iproute
|
iproute
|
||||||
|
@ -75,3 +75,5 @@ Packages=
|
|||||||
util-linux
|
util-linux
|
||||||
# xxd is provided by the vim package
|
# xxd is provided by the vim package
|
||||||
vim
|
vim
|
||||||
|
# Provides libasan/libubsan
|
||||||
|
gcc
|
||||||
|
@ -72,6 +72,8 @@ Packages=
|
|||||||
nano
|
nano
|
||||||
strace
|
strace
|
||||||
xxd
|
xxd
|
||||||
|
# Provides libasan/libubsan
|
||||||
|
gcc
|
||||||
# Required to run systemd-networkd-tests.py
|
# Required to run systemd-networkd-tests.py
|
||||||
python3
|
python3
|
||||||
iproute2
|
iproute2
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
if [ "$1" = "final" ] && command -v bootctl > /dev/null; then
|
if [ "$1" = "final" ]; then
|
||||||
bootctl install
|
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
|
fi
|
||||||
|
|
||||||
# Temporary workaround until https://github.com/openSUSE/suse-module-tools/commit/158643414ddb8d8208016a5f03a4484d58944d7a
|
# Temporary workaround until https://github.com/openSUSE/suse-module-tools/commit/158643414ddb8d8208016a5f03a4484d58944d7a
|
||||||
|
Loading…
Reference in New Issue
Block a user