if [[ "$COMPILER" == clang ]]; then
CC="clang${COMPILER_VERSION:+-$COMPILER_VERSION}"
CXX="clang++${COMPILER_VERSION:+-$COMPILER_VERSION}"
+ CFLAGS="-shared-libasan -O1 -g -fno-omit-frame-pointer"
+ CXXFLAGS="-shared-libasan -O1 -g -fno-omit-frame-pointer"
elif [[ "$COMPILER" == gcc ]]; then
CC="gcc${COMPILER_VERSION:+-$COMPILER_VERSION}"
CXX="g++${COMPILER_VERSION:+-$COMPILER_VERSION}"
+ CFLAGS="-O1 -g -fno-omit-frame-pointer"
+ CXXFLAGS="-O1 -g -fno-omit-frame-pointer"
fi
set -ex
sudo -E git clean -xdf
./autogen.sh
- CC=$CC CXX=$CXX ./configure $opts
+ CC=$CC CXX=$CXX CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ./configure $opts
;;
MAKE)
make -j
make install DESTDIR=/tmp/dest
;;
CHECK)
+ # All the following black magic is to make test/eject/umount work, since
+ # eject execl()s the uninstrumented /bin/umount binary, which confuses
+ # ASan. The workaround for this is to set $LD_PRELOAD to the ASan's
+ # runtime DSO, which works well with gcc without any additional hassle.
+ # However, since clang, by default, links ASan statically, we need to
+ # explicitly state we want dynamic linking (see -shared-libasan above).
+ # That, however, introduces another issue - clang's ASan runtime is in
+ # a non-standard path, so all binaries compiled in such way refuse
+ # to start. That's what the following blob of code is for - it detects
+ # the ASan's runtime path and adds the respective directory to
+ # the dynamic linker cache.
+ #
+ # The actual $LD_PRELOAD sheanigans are done directly in
+ # tests/ts/eject/umount.
+ asan_rt_name="$(ldd ./kill | awk '/lib.+asan.*.so/ {print $1; exit}')"
+ asan_rt_path="$($CC --print-file-name "$asan_rt_name")"
+ echo "Detected ASan runtime: $asan_rt_name ($asan_rt_path)"
+ if [[ -z "$asan_rt_name" || -z "$asan_rt_path" ]]; then
+ echo >&2 "Couldn't detect ASan runtime, can't continue"
+ exit 1
+ fi
+
+ if [[ "$COMPILER" == clang* ]]; then
+ mkdir -p /etc/ld.so.conf.d/
+ echo "${asan_rt_path%/*}" > /etc/ld.so.conf.d/99-clang-libasan.conf
+ ldconfig
+ fi
+
./tests/run.sh --show-diff
;;
DISTCHECK)
test_fdisk_script_fuzz_SOURCES = libfdisk/src/script.c
test_fdisk_script_fuzz_CFLAGS = -DFUZZ_TARGET $(libfdisk_la_CFLAGS) $(NO_UNUSED_WARN_CFLAGS)
-test_fdisk_script_fuzz_LDFLAGS = $(libfdisk_tests_ldflags)
+test_fdisk_script_fuzz_LDFLAGS = $(libfdisk_tests_ldflags) -lpthread
test_fdisk_script_fuzz_LDADD = $(libfdisk_tests_ldadd) $(LIB_FUZZING_ENGINE)
endif
nodist_EXTRA_test_mount_fuzz_SOURCES = dummy.cxx
test_mount_fuzz_CFLAGS = $(libmount_tests_cflags)
-test_mount_fuzz_LDFLAGS = $(libmount_tests_ldflags)
+test_mount_fuzz_LDFLAGS = $(libmount_tests_ldflags) -lpthread
test_mount_fuzz_LDADD = $(libmount_tests_ldadd) $(LIB_FUZZING_ENGINE)
endif
test_last_fuzz_SOURCES = login-utils/last.c
test_last_fuzz_CFLAGS = $(AM_CFLAGS) -DFUZZ_TARGET
+test_last_fuzz_LDFLAGS = -lpthread
test_last_fuzz_LDADD = $(LDADD) libcommon.la $(LIB_FUZZING_ENGINE)
endif
echo "no"
fi
}
+
+# Get path to the ASan runtime DSO the given binary was compiled with
+function ts_get_asan_rt_path {
+ local binary="${1?}"
+ local rt_path
+
+ ts_check_prog "ldd"
+ ts_check_prog "awk"
+
+ rt_path="$(ldd "$binary" | awk '/lib.+asan.*.so/ {print $3; exit}')"
+ if [ -n "$rt_path" -a -f "$rt_path" ]; then
+ echo "$rt_path"
+ fi
+}
ts_check_test_command "$TS_CMD_FDISK"
ts_check_test_command "$TS_CMD_EJECT"
+ts_check_test_command "$TS_CMD_KILL"
ts_check_test_command "$TS_CMD_MOUNT"
ts_skip_nonroot
ts_scsi_debug_rmmod
}
+# As the eject binary execl()s an uninstrumented /bin/umount binary, we need
+# to explicitly $LD_PRELOAD the ASan's runtime DSO, otherwise ASan will complain.
+# Since all three utilities used by this test (eject, fdisk, mount) are just
+# libtool wrappers, let's check the kill binary instead, which should have
+# the needed DSO information.
+ASAN_RT_PATH="$(ts_get_asan_rt_path "$TS_CMD_KILL")"
+[ -n "$ASAN_RT_PATH" ] && export LD_PRELOAD="$ASAN_RT_PATH:$LD_PRELOAD"
ts_init_subtest "by-disk"
init_device
ts_check_test_command "$TS_HELPER_LIBFDISK_SCRIPT_FUZZ"
+ASAN_RT_PATH="$(ts_get_asan_rt_path "$TS_HELPER_LIBFDISK_SCRIPT_FUZZ")"
+[ -n "$ASAN_RT_PATH" ] && export LD_PRELOAD="$ASAN_RT_PATH:$LD_PRELOAD"
+
mkdir -p ${TS_OUTPUT}_workdir
ts_run $TS_HELPER_LIBFDISK_SCRIPT_FUZZ ${TS_OUTPUT}_workdir ${TS_SCRIPT}_files -max_total_time=10 >$TS_OUTPUT 2>$TS_ERRLOG
ts_check_test_command "$TS_HELPER_LAST_FUZZ"
+ASAN_RT_PATH="$(ts_get_asan_rt_path "$TS_HELPER_LAST_FUZZ")"
+[ -n "$ASAN_RT_PATH" ] && export LD_PRELOAD="$ASAN_RT_PATH:$LD_PRELOAD"
+
mkdir -p ${TS_OUTPUT}_workdir
ts_run $TS_HELPER_LAST_FUZZ ${TS_OUTPUT}_workdir ${TS_SCRIPT}_files -max_total_time=10 >$TS_OUTPUT 2>$TS_ERRLOG
ts_check_test_command "$TS_HELPER_LIBMOUNT_FUZZ"
+ASAN_RT_PATH="$(ts_get_asan_rt_path "$TS_HELPER_LIBMOUNT_FUZZ")"
+[ -n "$ASAN_RT_PATH" ] && export LD_PRELOAD="$ASAN_RT_PATH:$LD_PRELOAD"
+
mkdir -p ${TS_OUTPUT}_workdir
ts_run $TS_HELPER_LIBMOUNT_FUZZ ${TS_OUTPUT}_workdir ${TS_SCRIPT}_files -max_total_time=10 >$TS_OUTPUT 2>$TS_ERRLOG