dcavalca / rpms / systemd

Forked from rpms/systemd 6 months ago
Clone
8d419f
From 75037db319f9eb240d73186eee457f62d4b16c7d Mon Sep 17 00:00:00 2001
8d419f
From: Frantisek Sumsal <frantisek@sumsal.cz>
8d419f
Date: Tue, 14 Jun 2022 22:54:39 +0200
8d419f
Subject: [PATCH] test: wrap binaries using systemd DSOs when running w/ ASan
8d419f
8d419f
Let's detect & wrap binaries which are linked against systemd DSOs and
8d419f
we're running under ASan, since otherwise running such binaries ends
8d419f
with:
8d419f
8d419f
```
8d419f
==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.
8d419f
```
8d419f
8d419f
(cherry picked from commit 3917534d620c2b358a196431b9e2593218ba1ac9)
8d419f
8d419f
Related: #2087652
8d419f
---
8d419f
 test/test-functions | 40 +++++++++++++++++++++++++++++++++++++++-
8d419f
 1 file changed, 39 insertions(+), 1 deletion(-)
8d419f
8d419f
diff --git a/test/test-functions b/test/test-functions
8d419f
index a0ad8b2fb1..34aeac339f 100644
8d419f
--- a/test/test-functions
8d419f
+++ b/test/test-functions
8d419f
@@ -2426,6 +2426,9 @@ inst_binary() {
8d419f
 
8d419f
     local file line
8d419f
     local so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)'
8d419f
+    # DSOs provided by systemd
8d419f
+    local systemd_so_regex='/(libudev|libsystemd.*|.+[\-_]systemd([\-_].+)?|libnss_(mymachines|myhostname|resolve)).so'
8d419f
+    local wrap_binary=0
8d419f
     # I love bash!
8d419f
     while read -r line; do
8d419f
         [[ "$line" = 'not a dynamic executable' ]] && break
8d419f
@@ -2434,6 +2437,12 @@ inst_binary() {
8d419f
         # by ldd attempting to use the unprefixed RPATH.
8d419f
         [[ "$line" =~ libsystemd.*\ not\ found ]] && continue
8d419f
 
8d419f
+        # We're built with ASan and the target binary loads one of the systemd's
8d419f
+        # DSOs, so we need to tweak the environment before executing the binary
8d419f
+        if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$line" =~ $systemd_so_regex ]]; then
8d419f
+            wrap_binary=1
8d419f
+        fi
8d419f
+
8d419f
         if [[ "$line" =~ $so_regex ]]; then
8d419f
             file="${BASH_REMATCH[1]}"
8d419f
             [[ -e "${initdir}/$file" ]] && continue
8d419f
@@ -2449,7 +2458,36 @@ inst_binary() {
8d419f
             exit 1
8d419f
         fi
8d419f
     done < <(LC_ALL=C ldd "$bin" 2>/dev/null)
8d419f
-    inst_simple "$bin" "$target"
8d419f
+
8d419f
+    # Same as above, but we need to wrap certain libraries unconditionally
8d419f
+    #
8d419f
+    # login - dlopen()s (not only) systemd's PAM modules
8d419f
+    # tar - called by machinectl in TEST-25
8d419f
+    if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(login|tar)$ ]]; then
8d419f
+        wrap_binary=1
8d419f
+    fi
8d419f
+
8d419f
+    if get_bool "$wrap_binary"; then
8d419f
+        dinfo "Creating ASan-compatible wrapper for binary '$target'"
8d419f
+        # Install the target binary with a ".orig" suffix
8d419f
+        inst_simple "$bin" "${target}.orig"
8d419f
+        # Create a simple shell wrapper in place of the target binary, which
8d419f
+        # sets necessary ASan-related env variables and then exec()s the
8d419f
+        # suffixed target binary
8d419f
+        cat >"$initdir/$target" <
8d419f
+#!/bin/bash
8d419f
+# Preload the ASan runtime DSO, otherwise ASAn will complain
8d419f
+export LD_PRELOAD="$ASAN_RT_PATH"
8d419f
+# Disable LSan to speed things up, since we don't care about leak reports
8d419f
+# from 'external' binaries
8d419f
+export ASAN_OPTIONS=detect_leaks=0
8d419f
+# Set argv[0] to the original binary name without the ".orig" suffix
8d419f
+exec -a "\$0" -- "${target}.orig" "\$@"
8d419f
+EOF
8d419f
+        chmod +x "$initdir/$target"
8d419f
+    else
8d419f
+        inst_simple "$bin" "$target"
8d419f
+    fi
8d419f
 }
8d419f
 
8d419f
 # same as above, except for shell scripts.