mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-22 22:03:43 +03:00
test: split the ASan wrapper into smaller blocks and tidy it up a bit
No functional change (hopefully), just making it easier on the eyes. (cherry picked from commit ba79e8c2ccdea132c2c0a820deb27c66a5aa6956) (cherry picked from commit 91f08ecca311bf06d2fe74e9f5c94a0dfc973637)
This commit is contained in:
parent
27fa0f4f28
commit
bf60262374
@ -291,8 +291,8 @@ IS_BUILT_WITH_COVERAGE=$(is_built_with_coverage && echo yes || echo no)
|
|||||||
|
|
||||||
if get_bool "$IS_BUILT_WITH_ASAN"; then
|
if get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||||
STRIP_BINARIES=no
|
STRIP_BINARIES=no
|
||||||
|
PATH_TO_INIT="$ROOTLIBDIR/systemd-under-asan"
|
||||||
SKIP_INITRD="${SKIP_INITRD:-yes}"
|
SKIP_INITRD="${SKIP_INITRD:-yes}"
|
||||||
PATH_TO_INIT=$ROOTLIBDIR/systemd-under-asan
|
|
||||||
QEMU_MEM="${QEMU_MEM:-2G}"
|
QEMU_MEM="${QEMU_MEM:-2G}"
|
||||||
QEMU_SMP="${QEMU_SMP:-4}"
|
QEMU_SMP="${QEMU_SMP:-4}"
|
||||||
|
|
||||||
@ -835,88 +835,96 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
create_asan_wrapper() {
|
create_asan_wrapper() {
|
||||||
local asan_wrapper="$initdir/$ROOTLIBDIR/systemd-under-asan"
|
local asan_wrapper default_asan_options default_ubsan_options default_environment
|
||||||
dinfo "Create ASan wrapper as '$asan_wrapper'"
|
|
||||||
|
|
||||||
[[ -z "$ASAN_RT_PATH" ]] && dfatal "ASAN_RT_PATH is empty, but it shouldn't be"
|
[[ -z "$ASAN_RT_PATH" ]] && dfatal "ASAN_RT_PATH is empty, but it shouldn't be"
|
||||||
|
|
||||||
# clang: install llvm-symbolizer to generate useful reports
|
default_asan_options="${ASAN_OPTIONS:-strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1}"
|
||||||
# See: https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
|
default_ubsan_options="${UBSAN_OPTIONS:-print_stacktrace=1:print_summary=1:halt_on_error=1}"
|
||||||
[[ "$ASAN_COMPILER" == "clang" ]] && image_install "llvm-symbolizer"
|
|
||||||
|
|
||||||
cat >"$asan_wrapper" <<EOF
|
if [[ "$ASAN_COMPILER" == "clang" ]]; then
|
||||||
#!/usr/bin/env bash
|
# clang: install llvm-symbolizer to generate useful reports
|
||||||
|
# See: https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
|
||||||
|
image_install "llvm-symbolizer"
|
||||||
|
|
||||||
set -x
|
# Let's add the ASan DSO's path to the dynamic linker's cache. This is pretty
|
||||||
|
# unnecessary for gcc & libasan, however, for clang this is crucial, as its
|
||||||
|
# runtime ASan DSO is in a non-standard (library) path.
|
||||||
|
mkdir -p "${initdir:?}/etc/ld.so.conf.d/"
|
||||||
|
echo "${ASAN_RT_PATH%/*}" >"${initdir:?}/etc/ld.so.conf.d/asan-path-override.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "ASan RT: $ASAN_RT_PATH"
|
# Create a simple environment file which can be included by systemd services
|
||||||
if [[ ! -e "$ASAN_RT_PATH" ]]; then
|
# that need it (i.e. services that utilize DynamicUser=true and bash, etc.)
|
||||||
echo >&2 "Couldn't find ASan RT at '$ASAN_RT_PATH', can't continue"
|
cat >"${initdir:?}/usr/lib/systemd/systemd-asan-env" <<EOF
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DEFAULT_ASAN_OPTIONS=${ASAN_OPTIONS:-strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1}
|
|
||||||
DEFAULT_UBSAN_OPTIONS=${UBSAN_OPTIONS:-print_stacktrace=1:print_summary=1:halt_on_error=1}
|
|
||||||
DEFAULT_ENVIRONMENT="ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS"
|
|
||||||
|
|
||||||
# Create a simple environment file which can be included by systemd services
|
|
||||||
# that need it (i.e. services that utilize DynamicUser=true and bash, etc.)
|
|
||||||
cat >/usr/lib/systemd/systemd-asan-env <<INNER_EOF
|
|
||||||
LD_PRELOAD=$ASAN_RT_PATH
|
LD_PRELOAD=$ASAN_RT_PATH
|
||||||
ASAN_OPTIONS=$DEFAULT_ASAN_OPTIONS
|
ASAN_OPTIONS=$default_asan_options
|
||||||
LSAN_OPTIONS=detect_leaks=0
|
LSAN_OPTIONS=detect_leaks=0
|
||||||
UBSAN_OPTIONS=$DEFAULT_UBSAN_OPTIONS
|
UBSAN_OPTIONS=$default_ubsan_options
|
||||||
INNER_EOF
|
EOF
|
||||||
|
|
||||||
# As right now bash is the PID 1, we can't expect PATH to have a sane value.
|
default_environment=(
|
||||||
# Let's make one to prevent unexpected "<bin> not found" issues in the future
|
"ASAN_OPTIONS='$default_asan_options'"
|
||||||
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
|
"UBSAN_OPTIONS='$default_ubsan_options'"
|
||||||
|
"ASAN_RT_PATH='$ASAN_RT_PATH'"
|
||||||
|
)
|
||||||
|
|
||||||
mountpoint -q /proc || mount -t proc proc /proc
|
mkdir -p "${initdir:?}/etc/systemd/system.conf.d/"
|
||||||
mountpoint -q /sys || mount -t sysfs sysfs /sys
|
cat >"${initdir:?}/etc/systemd/system.conf.d/asan.conf" <<EOF
|
||||||
mount -o remount,rw /
|
[Manager]
|
||||||
|
DefaultEnvironment=${default_environment[*]}
|
||||||
|
ManagerEnvironment=${default_environment[*]}
|
||||||
|
DefaultTimeoutStartSec=180s
|
||||||
|
DefaultStandardOutput=journal+console
|
||||||
|
EOF
|
||||||
|
|
||||||
DEFAULT_ENVIRONMENT="\$DEFAULT_ENVIRONMENT ASAN_RT_PATH=$ASAN_RT_PATH"
|
# ASAN and syscall filters aren't compatible with each other.
|
||||||
|
find "${initdir:?}" -name '*.service' -type f -print0 | xargs -0 sed -i 's/^\(MemoryDeny\|SystemCall\)/#\1/'
|
||||||
if [[ "$ASAN_COMPILER" == "clang" ]]; then
|
|
||||||
# Let's add the ASan DSO's path to the dynamic linker's cache. This is pretty
|
|
||||||
# unnecessary for gcc & libasan, however, for clang this is crucial, as its
|
|
||||||
# runtime ASan DSO is in a non-standard (library) path.
|
|
||||||
echo "${ASAN_RT_PATH%/*}" >/etc/ld.so.conf.d/asan-path-override.conf
|
|
||||||
ldconfig
|
|
||||||
fi
|
|
||||||
echo DefaultEnvironment=\$DEFAULT_ENVIRONMENT >>/etc/systemd/system.conf
|
|
||||||
echo DefaultTimeoutStartSec=180s >>/etc/systemd/system.conf
|
|
||||||
echo DefaultStandardOutput=journal+console >>/etc/systemd/system.conf
|
|
||||||
|
|
||||||
# ASAN and syscall filters aren't compatible with each other.
|
|
||||||
find / -name '*.service' -type f | xargs sed -i 's/^\\(MemoryDeny\\|SystemCall\\)/#\\1/'
|
|
||||||
|
|
||||||
|
mkdir -p "${initdir:?}/etc/systemd/system/systemd-journald.service.d/"
|
||||||
|
cat >"${initdir:?}/etc/systemd/system/systemd-journald.service.d/asan-env.conf" <<EOF
|
||||||
|
[Service]
|
||||||
# The redirection of ASAN reports to a file prevents them from ending up in /dev/null.
|
# The redirection of ASAN reports to a file prevents them from ending up in /dev/null.
|
||||||
# But, apparently, sometimes it doesn't work: https://github.com/google/sanitizers/issues/886.
|
# But, apparently, sometimes it doesn't work: https://github.com/google/sanitizers/issues/886.
|
||||||
JOURNALD_CONF_DIR=/etc/systemd/system/systemd-journald.service.d
|
Environment=ASAN_OPTIONS=$default_asan_options:log_path=/systemd-journald.asan.log UBSAN_OPTIONS=$default_ubsan_options:log_path=/systemd-journald.ubsan.log
|
||||||
mkdir -p "\$JOURNALD_CONF_DIR"
|
|
||||||
printf "[Service]\nEnvironment=ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd-journald.asan.log UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS:log_path=/systemd-journald.ubsan.log\n" >"\$JOURNALD_CONF_DIR/env.conf"
|
|
||||||
|
|
||||||
# Sometimes UBSan sends its reports to stderr regardless of what is specified in log_path
|
# Sometimes UBSan sends its reports to stderr regardless of what is specified in log_path
|
||||||
# Let's try to catch them by redirecting stderr (and stdout just in case) to a file
|
# Let's try to catch them by redirecting stderr (and stdout just in case) to a file
|
||||||
# See https://github.com/systemd/systemd/pull/12524#issuecomment-491108821
|
# See https://github.com/systemd/systemd/pull/12524#issuecomment-491108821
|
||||||
printf "[Service]\nStandardOutput=file:/systemd-journald.out\n" >"\$JOURNALD_CONF_DIR/out.conf"
|
StandardOutput=file:/systemd-journald.out
|
||||||
|
|
||||||
# 90s isn't enough for some services to finish when literally everything is run
|
|
||||||
# under ASan+UBSan in containers, which, in turn, are run in VMs.
|
|
||||||
# Let's limit which environments such services should be executed in.
|
|
||||||
mkdir -p /etc/systemd/system/systemd-hwdb-update.service.d
|
|
||||||
printf "[Unit]\nConditionVirtualization=container\n\n[Service]\nTimeoutSec=240s\n" >/etc/systemd/system/systemd-hwdb-update.service.d/env-override.conf
|
|
||||||
|
|
||||||
# Let's override another hard-coded timeout that kicks in too early
|
|
||||||
mkdir -p /etc/systemd/system/systemd-journal-flush.service.d
|
|
||||||
printf "[Service]\nTimeoutSec=180s\n" >/etc/systemd/system/systemd-journal-flush.service.d/timeout.conf
|
|
||||||
|
|
||||||
export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS
|
|
||||||
exec "$ROOTLIBDIR/systemd" "\$@"
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# 90s isn't enough for some services to finish when literally everything is run
|
||||||
|
# under ASan+UBSan in containers, which, in turn, are run in VMs.
|
||||||
|
# Let's limit which environments such services should be executed in.
|
||||||
|
mkdir -p "${initdir:?}/etc/systemd/system/systemd-hwdb-update.service.d/"
|
||||||
|
cat >"${initdir:?}/etc/systemd/system/systemd-hwdb-update.service.d/asan.conf" <<EOF
|
||||||
|
[Unit]
|
||||||
|
ConditionVirtualization=container
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
TimeoutSec=240s
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Let's override another hard-coded timeout that kicks in too early
|
||||||
|
mkdir -p "${initdir:?}/etc/systemd/system/systemd-journal-flush.service.d/"
|
||||||
|
cat >"${initdir:?}/etc/systemd/system/systemd-journal-flush.service.d/asan.conf" <<EOF
|
||||||
|
[Service]
|
||||||
|
TimeoutSec=180s
|
||||||
|
EOF
|
||||||
|
|
||||||
|
asan_wrapper="${initdir:?}/${PATH_TO_INIT:?}"
|
||||||
|
# Sanity check to make sure we don't overwrite something we shouldn't.
|
||||||
|
[[ "$asan_wrapper" =~ systemd-under-asan$ ]]
|
||||||
|
|
||||||
|
cat >"$asan_wrapper" <<EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
export ${default_environment[@]}
|
||||||
|
[[ -n "\$ASAN_OPTIONS" && -n "\$UBSAN_OPTIONS" ]]
|
||||||
|
exec "$ROOTLIBDIR/systemd" "\$@"
|
||||||
|
EOF
|
||||||
chmod 0755 "$asan_wrapper"
|
chmod 0755 "$asan_wrapper"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user