Merge branch 'gh-actions-bionic' of https://github.com/mrc0mmand/util-linux
* 'gh-actions-bionic' of https://github.com/mrc0mmand/util-linux: ci: run the build test for each pull request ci: build both w/ and w/o sanitizers on GH Actions ci: code cleanup ci: deal with uninstrumented binaries using instrumented libs text-utils: correctly detect ASan under clang ci: use the correct compiler version ci: 'downgrade' Ubuntu version to Bionic
This commit is contained in:
commit
ec89bec1cd
|
@ -2,40 +2,47 @@
|
|||
|
||||
PHASES=(${@:-CONFIGURE MAKE INSTALL CHECK DISTCHECK})
|
||||
COMPILER="${COMPILER:?}"
|
||||
COMPILER_VERSION="${COMPILER_VERSION:?}"
|
||||
COMPILER_VERSION="${COMPILER_VERSION}"
|
||||
CFLAGS=(-O1 -g)
|
||||
CXXFLAGS=(-O1 -g)
|
||||
|
||||
if [[ "$COMPILER" == clang ]]; then
|
||||
CC="clang"
|
||||
CXX="clang++"
|
||||
CC="clang${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
CXX="clang++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
elif [[ "$COMPILER" == gcc ]]; then
|
||||
CC="gcc"
|
||||
CXX="g++"
|
||||
CC="gcc${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
CXX="g++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
export CC="$CC"
|
||||
export CXX="$CXX"
|
||||
|
||||
for phase in "${PHASES[@]}"; do
|
||||
case $phase in
|
||||
CONFIGURE)
|
||||
opts="--disable-use-tty-group \
|
||||
--disable-makeinstall-chown \
|
||||
--enable-all-programs \
|
||||
--enable-asan \
|
||||
--enable-ubsan \
|
||||
--without-python \
|
||||
--enable-werror"
|
||||
opts=(
|
||||
--disable-use-tty-group
|
||||
--disable-makeinstall-chown
|
||||
--enable-all-programs
|
||||
--without-python
|
||||
--enable-werror
|
||||
)
|
||||
|
||||
if [[ "$COMPILER" == clang ]]; then
|
||||
opts="$opts --enable-fuzzing-engine"
|
||||
if [[ "$SANITIZE" == "yes" ]]; then
|
||||
opts+=(--enable-asan --enable-ubsan)
|
||||
CFLAGS+=(-fno-omit-frame-pointer)
|
||||
CXXFLAGS+=(-fno-omit-frame-pointer)
|
||||
fi
|
||||
|
||||
if [[ "$COMPILER" == clang* && "$SANITIZE" == "yes" ]]; then
|
||||
opts+=(--enable-fuzzing-engine)
|
||||
CFLAGS+=(-shared-libasan)
|
||||
CXXFLAGS+=(-shared-libasan)
|
||||
fi
|
||||
|
||||
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
|
||||
|
@ -45,6 +52,36 @@ for phase in "${PHASES[@]}"; do
|
|||
make install DESTDIR=/tmp/dest
|
||||
;;
|
||||
CHECK)
|
||||
if [[ "$SANITIZE" == "yes" ]]; then
|
||||
# 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
|
||||
fi
|
||||
|
||||
./tests/run.sh --show-diff
|
||||
;;
|
||||
DISTCHECK)
|
||||
|
@ -56,5 +93,3 @@ for phase in "${PHASES[@]}"; do
|
|||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
name: Build test
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'Documentation/**'
|
||||
- 'lib*/docs/**'
|
||||
push:
|
||||
branches:
|
||||
- 'cibuild'
|
||||
|
@ -12,13 +16,15 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
env:
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "10" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "10" }
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "10", SANITIZE: "yes" }
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "10", SANITIZE: "no" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "10", SANITIZE: "yes" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "10", SANITIZE: "no" }
|
||||
env: ${{ matrix.env }}
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
|
|
17
include/c.h
17
include/c.h
|
@ -411,6 +411,23 @@ static inline int xusleep(useconds_t usec)
|
|||
#define stringify_value(s) stringify(s)
|
||||
#define stringify(s) #s
|
||||
|
||||
/* Detect if we're compiled with Address Sanitizer
|
||||
* - gcc (__SANITIZE_ADDRESS__)
|
||||
* - clang (__has_feature(address_sanitizer))
|
||||
*/
|
||||
#if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
|
||||
# ifdef __SANITIZE_ADDRESS__
|
||||
# define HAS_FEATURE_ADDRESS_SANITIZER 1
|
||||
# elif defined(__has_feature)
|
||||
# if __has_feature(address_sanitizer)
|
||||
# define HAS_FEATURE_ADDRESS_SANITIZER 1
|
||||
# endif
|
||||
# endif
|
||||
# if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
|
||||
# define HAS_FEATURE_ADDRESS_SANITIZER 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
|
||||
* instrumentation shipped with Clang and GCC) to not instrument the
|
||||
|
|
|
@ -83,7 +83,7 @@ close_stdout_atexit(void)
|
|||
/*
|
||||
* Note that close stdout at exit disables ASAN to report memory leaks
|
||||
*/
|
||||
#if !defined(__SANITIZE_ADDRESS__)
|
||||
#if !HAS_FEATURE_ADDRESS_SANITIZER
|
||||
atexit(close_stdout);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ nodist_EXTRA_test_fdisk_script_fuzz_SOURCES = dummy.cxx
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ test_mount_fuzz_SOURCES = libmount/src/fuzz.c
|
|||
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
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ nodist_EXTRA_test_last_fuzz_SOURCES = dummy.cxx
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -1078,3 +1078,17 @@ function ts_has_ncurses_support {
|
|||
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
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ ts_init "$*"
|
|||
|
||||
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
|
||||
|
@ -59,6 +60,13 @@ function deinit_device {
|
|||
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
|
||||
|
|
|
@ -20,6 +20,9 @@ ts_init "$*"
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ ts_init "$*"
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ ts_init "$*"
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "closestream.h"
|
||||
#include "nls.h"
|
||||
#include "optutils.h"
|
||||
|
@ -89,7 +90,7 @@
|
|||
/* number of lines to allocate */
|
||||
#define NALLOC 64
|
||||
|
||||
#if defined(__SANITIZE_ADDRESS__) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
#if HAS_FEATURE_ADDRESS_SANITIZER || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
# define COL_DEALLOCATE_ON_EXIT
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue