Skip to content

Commit

Permalink
[build] Add annobin build/check support
Browse files Browse the repository at this point in the history
the annobin check is enabled only if all compiler flags, linker flags
and annocheck binary are available.

the build will use as many of the hardening options required to pass
the annocheck regardless.

the check is performed / enabled only with gcc. clang currently suffers
from some limitations to automatically detect the annobin plugin, that
would increase drastacally the complexity of the build system
unnecessarely.

implementation based on:
- https://bugzilla.redhat.com/show_bug.cgi?id=1961686
- https://developers.redhat.com/blog/2019/02/04/annocheck-examining-the-contents-of-binary-files#
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/developing_c_and_cpp_applications_in_rhel_8/annobin_toolsets

Original idea by Christine Caulfield <ccaulfie@redhat.com>

CentOS Stream CI insists on this but it's generally a 'good thing'

Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
chrissie-c authored and fabbione committed Sep 16, 2021
1 parent f8ef822 commit 9a8fd89
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 6 deletions.
31 changes: 31 additions & 0 deletions build-aux/check.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,34 @@ endif
else
@echo cov-build not available on this platform
endif

check-annocheck-libs:
if HAS_ANNOCHECK
@echo Running annocheck libs test
if ! $(ANNOCHECK_EXEC) --quiet .libs/*.so; then \
$(ANNOCHECK_EXEC) --verbose .libs/*.so; \
echo annocheck libs test: FAILED; \
exit 1; \
else \
echo annocheck libs test: PASS; \
fi
else
@echo Annocheck build or binary not available
endif

# we cannot check run-path because CI builds with specific prefix/user_prefix
# and the only binaries affected are the test suite.

check-annocheck-bins:
if HAS_ANNOCHECK
@echo Running annocheck binaries test
if ! $(ANNOCHECK_EXEC) --skip-run-path --quiet .libs/*; then \
$(ANNOCHECK_EXEC) --skip-run-path --verbose .libs/*; \
echo annocheck binaries test: FAILED; \
exit 1; \
else \
echo annocheck binaries test: PASS; \
fi
else
@echo Annocheck build or binary not available
endif
73 changes: 69 additions & 4 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ AX_CHECK_LINK_FLAG([-Wl,--enable-new-dtags],
[AC_MSG_ERROR(["Linker support for --enable-new-dtags is required"])])
AX_CHECK_LINK_FLAG([-Wl,--as-needed], [AM_LDFLAGS="$AM_LDFLAGS -Wl,--as-needed"])

AC_SUBST([AM_LDFLAGS])
saved_LDFLAGS="$LDFLAGS"
LDFLAGS="$AM_LDFLAGS $LDFLAGS"
LT_INIT
Expand Down Expand Up @@ -182,6 +181,23 @@ AC_ARG_ENABLE([rust-bindings],
[ enable_rust_bindings="no" ])
AM_CONDITIONAL([BUILD_RUST_BINDINGS], [test x$enable_rust_bindings = xyes])

## local helper functions
# this function checks if CC support options passed as
# args. Global CPPFLAGS are ignored during this test.
cc_supports_flag() {
saveCPPFLAGS="$CPPFLAGS"
CPPFLAGS="$@"
if echo $CC | grep -q clang; then
CPPFLAGS="-Werror $CPPFLAGS"
fi
AC_MSG_CHECKING([whether $CC supports "$@"])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[RC=0; AC_MSG_RESULT([yes])],
[RC=1; AC_MSG_RESULT([no])])
CPPFLAGS="$saveCPPFLAGS"
return $RC
}

# Checks for libraries.
AX_PTHREAD(,[AC_MSG_ERROR([POSIX threads support is required])])
saved_LIBS="$LIBS"
Expand Down Expand Up @@ -348,6 +364,10 @@ AC_SUBST([libnozzlerustver])
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug],[enable debug build])])

AC_ARG_ENABLE([hardening],
[AS_HELP_STRING([--disable-hardening],[disable hardening build flags])],,
[ enable_hardening="yes" ])

AC_ARG_WITH([sanitizers],
[AS_HELP_STRING([--with-sanitizers=...,...],
[enable SANitizer build, do *NOT* use for production. Only ASAN/UBSAN/TSAN are currently supported])],
Expand All @@ -363,6 +383,50 @@ AC_ARG_WITH([testdir],

AC_SUBST([TESTDIR])

# Check for availablility of hardening options

annocheck=no

if test "x${enable_hardening}" = xyes; then
# support only gcc for now
if echo $CC | grep -q gcc; then
ANNOPLUGIN="-fplugin=annobin"
annocheck=yes
fi

HARDENING_CFLAGS_ANNOCHECK="$ANNOPLUGIN -fPIC -DPIC -pie -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fexceptions -D_GLIBCXX_ASSERTIONS -Wl,-z,now"
HARDENING_CFLAGS="-fstack-clash-protection -fcf-protection=full -mcet -mstackrealign"
EXTRA_HARDENING_CFLAGS=""

# check for annobin required cflags/ldflags
for j in $HARDENING_CFLAGS_ANNOCHECK; do
if cc_supports_flag $j; then
EXTRA_HARDENING_CFLAGS="$EXTRA_HARDENING_CFLAGS $j"
else
annocheck=no
fi
done

# check for other hardening cflags/ldflags
for j in $HARDENING_CFLAGS; do
if cc_supports_flag $j; then
EXTRA_HARDENING_CFLAGS="$EXTRA_HARDENING_CFLAGS $j"
fi
done

# check if annocheck binary is available
if test "x${annocheck}" = xyes; then
AC_CHECK_PROGS([ANNOCHECK_EXEC], [annocheck])
if test "x${ANNOCHECK_EXEC}" = x; then
annocheck=no
fi
fi

AM_LDFLAGS="$AM_LDFLAGS $EXTRA_HARDENING_CFLAGS"
fi

AM_CONDITIONAL([HAS_ANNOCHECK], [test "x$annocheck" = "xyes"])

# debug build stuff
if test "x${enable_debug}" = xyes; then
AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
Expand All @@ -377,9 +441,9 @@ fi

# gdb flags
if test "x${GCC}" = xyes; then
GDB_FLAGS="-ggdb3"
GDB_CFLAGS="-ggdb3"
else
GDB_FLAGS="-g"
GDB_CFLAGS="-g"
fi

# --- ASAN/UBSAN/TSAN (see man gcc) ---
Expand Down Expand Up @@ -418,8 +482,9 @@ DEFAULT_CFLAGS="-Werror -Wall -Wextra"
# generates too much noise for stub APIs
UNWANTED_CFLAGS="-Wno-unused-parameter"

AC_SUBST([AM_CFLAGS],["$SANITIZERS_CFLAGS $OPT_CFLAGS $GDB_FLAGS $DEFAULT_CFLAGS $UNWANTED_CFLAGS"])
AC_SUBST([AM_CFLAGS],["$SANITIZERS_CFLAGS $OPT_CFLAGS $GDB_CFLAGS $DEFAULT_CFLAGS $EXTRA_HARDENING_CFLAGS $UNWANTED_CFLAGS"])
LDFLAGS="$SANITIZERS_LDFLAGS $LDFLAGS"
AC_SUBST([AM_LDFLAGS])
AC_SUBST([RUST_FLAGS])
AC_SUBST([RUST_TARGET_DIR])

Expand Down
2 changes: 2 additions & 0 deletions libknet/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ libknet_la_LDFLAGS = $(AM_LDFLAGS) \

libknet_la_LIBADD = $(PTHREAD_LIBS) $(dl_LIBS) $(rt_LIBS) $(m_LIBS)

check-local: check-annocheck-libs

# Prepare empty value for appending
pkglib_LTLIBRARIES =

Expand Down
2 changes: 1 addition & 1 deletion libknet/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ testsuitedir = $(TESTDIR)
testsuite_PROGRAMS = $(noinst_PROGRAMS)
endif

check-local: check-api-test-coverage
check-local: check-api-test-coverage check-annocheck-bins

check-api-test-coverage:
chmod u+x $(top_srcdir)/libknet/tests/api-test-coverage
Expand Down
2 changes: 2 additions & 0 deletions libnozzle/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ libnozzle_la_LDFLAGS = $(AM_LDFLAGS) \

libnozzle_la_LIBADD = $(PTHREAD_LIBS) $(libnl_LIBS) $(libnlroute_LIBS)

check-local: check-annocheck-libs

endif
2 changes: 1 addition & 1 deletion libnozzle/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ testsuitedir = $(TESTDIR)
testsuite_PROGRAMS = $(noinst_PROGRAMS)
endif

check-local: check-api-test-coverage
check-local: check-api-test-coverage check-annocheck-bins

check-api-test-coverage:
chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
Expand Down

0 comments on commit 9a8fd89

Please sign in to comment.