test: wrap binaries using systemd DSOs when running w/ ASan

Let's detect & wrap binaries which are linked against systemd DSOs and
we're running under ASan, since otherwise running such binaries ends
with:

```
==633==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
```
This commit is contained in:
Frantisek Sumsal 2022-06-14 22:54:39 +02:00
parent aca811544e
commit 3917534d62

View file

@ -2440,6 +2440,9 @@ inst_binary() {
local file line
local so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)'
# DSOs provided by systemd
local systemd_so_regex='/(libudev|libsystemd.*|.+[\-_]systemd([\-_].+)?|libnss_(mymachines|myhostname|resolve)).so'
local wrap_binary=0
# I love bash!
while read -r line; do
[[ "$line" = 'not a dynamic executable' ]] && break
@ -2448,6 +2451,12 @@ inst_binary() {
# by ldd attempting to use the unprefixed RPATH.
[[ "$line" =~ libsystemd.*\ not\ found ]] && continue
# We're built with ASan and the target binary loads one of the systemd's
# DSOs, so we need to tweak the environment before executing the binary
if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$line" =~ $systemd_so_regex ]]; then
wrap_binary=1
fi
if [[ "$line" =~ $so_regex ]]; then
file="${BASH_REMATCH[1]}"
[[ -e "${initdir}/$file" ]] && continue
@ -2463,7 +2472,36 @@ inst_binary() {
exit 1
fi
done < <(LC_ALL=C ldd "$bin" 2>/dev/null)
inst_simple "$bin" "$target"
# Same as above, but we need to wrap certain libraries unconditionally
#
# login - dlopen()s (not only) systemd's PAM modules
# tar - called by machinectl in TEST-25
if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(login|tar)$ ]]; then
wrap_binary=1
fi
if get_bool "$wrap_binary"; then
dinfo "Creating ASan-compatible wrapper for binary '$target'"
# Install the target binary with a ".orig" suffix
inst_simple "$bin" "${target}.orig"
# Create a simple shell wrapper in place of the target binary, which
# sets necessary ASan-related env variables and then exec()s the
# suffixed target binary
cat >"$initdir/$target" <<EOF
#!/bin/bash
# Preload the ASan runtime DSO, otherwise ASAn will complain
export LD_PRELOAD="$ASAN_RT_PATH"
# Disable LSan to speed things up, since we don't care about leak reports
# from 'external' binaries
export ASAN_OPTIONS=detect_leaks=0
# Set argv[0] to the original binary name without the ".orig" suffix
exec -a "\$0" -- "${target}.orig" "\$@"
EOF
chmod +x "$initdir/$target"
else
inst_simple "$bin" "$target"
fi
}
# same as above, except for shell scripts.