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) (cherry picked from commit bf60262374a6300651659ae5e5c02e36776f29fd)
This commit is contained in:
parent
61d72099d7
commit
30767c809c
@ -255,8 +255,8 @@ IS_BUILT_WITH_COVERAGE=$(is_built_with_coverage && echo yes || echo no)
|
||||
|
||||
if get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||
STRIP_BINARIES=no
|
||||
PATH_TO_INIT="$ROOTLIBDIR/systemd-under-asan"
|
||||
SKIP_INITRD="${SKIP_INITRD:-yes}"
|
||||
PATH_TO_INIT=$ROOTLIBDIR/systemd-under-asan
|
||||
QEMU_MEM="${QEMU_MEM:-2G}"
|
||||
QEMU_SMP="${QEMU_SMP:-4}"
|
||||
|
||||
@ -782,88 +782,96 @@ EOF
|
||||
}
|
||||
|
||||
create_asan_wrapper() {
|
||||
local asan_wrapper="$initdir/$ROOTLIBDIR/systemd-under-asan"
|
||||
dinfo "Create ASan wrapper as '$asan_wrapper'"
|
||||
local asan_wrapper default_asan_options default_ubsan_options default_environment
|
||||
|
||||
[[ -z "$ASAN_RT_PATH" ]] && dfatal "ASAN_RT_PATH is empty, but it shouldn't be"
|
||||
|
||||
# clang: install llvm-symbolizer to generate useful reports
|
||||
# See: https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
|
||||
[[ "$ASAN_COMPILER" == "clang" ]] && image_install "llvm-symbolizer"
|
||||
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}"
|
||||
|
||||
cat >"$asan_wrapper" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
if [[ "$ASAN_COMPILER" == "clang" ]]; then
|
||||
# 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"
|
||||
if [[ ! -e "$ASAN_RT_PATH" ]]; then
|
||||
echo >&2 "Couldn't find ASan RT at '$ASAN_RT_PATH', can't continue"
|
||||
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
|
||||
# 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 >"${initdir:?}/usr/lib/systemd/systemd-asan-env" <<EOF
|
||||
LD_PRELOAD=$ASAN_RT_PATH
|
||||
ASAN_OPTIONS=$DEFAULT_ASAN_OPTIONS
|
||||
ASAN_OPTIONS=$default_asan_options
|
||||
LSAN_OPTIONS=detect_leaks=0
|
||||
UBSAN_OPTIONS=$DEFAULT_UBSAN_OPTIONS
|
||||
INNER_EOF
|
||||
UBSAN_OPTIONS=$default_ubsan_options
|
||||
EOF
|
||||
|
||||
# As right now bash is the PID 1, we can't expect PATH to have a sane value.
|
||||
# Let's make one to prevent unexpected "<bin> not found" issues in the future
|
||||
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
default_environment=(
|
||||
"ASAN_OPTIONS='$default_asan_options'"
|
||||
"UBSAN_OPTIONS='$default_ubsan_options'"
|
||||
"ASAN_RT_PATH='$ASAN_RT_PATH'"
|
||||
)
|
||||
|
||||
mountpoint -q /proc || mount -t proc proc /proc
|
||||
mountpoint -q /sys || mount -t sysfs sysfs /sys
|
||||
mount -o remount,rw /
|
||||
mkdir -p "${initdir:?}/etc/systemd/system.conf.d/"
|
||||
cat >"${initdir:?}/etc/systemd/system.conf.d/asan.conf" <<EOF
|
||||
[Manager]
|
||||
DefaultEnvironment=${default_environment[*]}
|
||||
ManagerEnvironment=${default_environment[*]}
|
||||
DefaultTimeoutStartSec=180s
|
||||
DefaultStandardOutput=journal+console
|
||||
EOF
|
||||
|
||||
DEFAULT_ENVIRONMENT="\$DEFAULT_ENVIRONMENT ASAN_RT_PATH=$ASAN_RT_PATH"
|
||||
|
||||
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/'
|
||||
# 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/'
|
||||
|
||||
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.
|
||||
# But, apparently, sometimes it doesn't work: https://github.com/google/sanitizers/issues/886.
|
||||
JOURNALD_CONF_DIR=/etc/systemd/system/systemd-journald.service.d
|
||||
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"
|
||||
Environment=ASAN_OPTIONS=$default_asan_options:log_path=/systemd-journald.asan.log UBSAN_OPTIONS=$default_ubsan_options:log_path=/systemd-journald.ubsan.log
|
||||
|
||||
# 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
|
||||
# See https://github.com/systemd/systemd/pull/12524#issuecomment-491108821
|
||||
printf "[Service]\nStandardOutput=file:/systemd-journald.out\n" >"\$JOURNALD_CONF_DIR/out.conf"
|
||||
|
||||
# 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" "\$@"
|
||||
StandardOutput=file:/systemd-journald.out
|
||||
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"
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user