]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: wrap binaries using systemd DSOs when running w/ ASan
authorFrantisek Sumsal <frantisek@sumsal.cz>
Tue, 14 Jun 2022 20:54:39 +0000 (22:54 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Wed, 15 Jun 2022 22:02:35 +0000 (00:02 +0200)
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.
```

test/test-functions

index 71413624f9e036246a023592e24c4dce00b077be..67019acf4395377c88ae67c9e760e319420cc86b 100644 (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.