Add clang's CFI instrumentation
Add --enable-cfi ./configure option to enable LLVM/Clang's Control Flow Integrity for builds. CFI aborts a program upon detecting certain forms of undefined behavior that can potentially allow attackers to subvert the program’s control flow.
This commit is contained in:
parent
d417badedb
commit
e20e6f369b
26
.travis.yml
26
.travis.yml
|
@ -1,15 +1,16 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
language: c
|
language: c
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang-3.8
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- develop
|
- clang-cfi
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- RUNTIME=libicu
|
- RUNTIME=libicu
|
||||||
|
@ -26,23 +27,26 @@ addons:
|
||||||
- libtool
|
- libtool
|
||||||
- gtk-doc-tools
|
- gtk-doc-tools
|
||||||
- gettext
|
- gettext
|
||||||
- libidn11
|
|
||||||
- libidn11-dev
|
- libidn11-dev
|
||||||
- libidn2-0
|
|
||||||
- libidn2-0-dev
|
- libidn2-0-dev
|
||||||
- libicu48
|
|
||||||
- libicu-dev
|
- libicu-dev
|
||||||
- libunistring0
|
|
||||||
- libunistring-dev
|
- libunistring-dev
|
||||||
- lcov
|
- lcov
|
||||||
|
- clang-3.8
|
||||||
|
- llvm-3.8-dev
|
||||||
|
- llvm-dev
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
- ./configure && make -j4 && make check -j4
|
# CFI doesn't work out on Ubuntu 14.04 (Trusty). They dont't include LLVMgold.so for clang-3.8.
|
||||||
- ./configure --enable-runtime=$RUNTIME --enable-builtin=libicu && make clean && make -j4 && make check -j4
|
# clang-3.4 doesn't know CFI yet.
|
||||||
- ./configure --enable-runtime=$RUNTIME --enable-builtin=libidn2 && make clean && make -j4 && make check -j4
|
# The only chance with Travis-CI is to switch to docker and use Ubuntu 16.04 or whatever.
|
||||||
- ./configure --enable-runtime=$RUNTIME --enable-builtin=libidn && make clean && make -j4 && make check -j4
|
# - if [[ $CC == "gcc" ]]; then CFI=""; else CFI="--enable-cfi"; fi
|
||||||
- ./configure --enable-runtime=$RUNTIME --disable-builtin && make clean && make -j4 && make check -j4
|
- ./configure $CFI && make -j4 && make check -j4 || (cat config.log; ls -la /usr/lib/*gold*)
|
||||||
|
- ./configure $CFI --enable-runtime=$RUNTIME --enable-builtin=libicu && make clean && make -j4 && make check -j4
|
||||||
|
- ./configure $CFI --enable-runtime=$RUNTIME --enable-builtin=libidn2 && make clean && make -j4 && make check -j4
|
||||||
|
- ./configure $CFI --enable-runtime=$RUNTIME --enable-builtin=libidn && make clean && make -j4 && make check -j4
|
||||||
|
- ./configure $CFI --enable-runtime=$RUNTIME --disable-builtin && make clean && make -j4 && make check -j4
|
||||||
- ./configure --enable-gtk-doc && make -j4 && make check -j4
|
- ./configure --enable-gtk-doc && make -j4 && make check -j4
|
||||||
- make distcheck
|
- make distcheck
|
||||||
- if [[ $CC == "gcc" && $RUNTIME == "libicu" ]]; then ./.travis_coveralls.sh; fi
|
- if [[ $CC == "gcc" && $RUNTIME == "libicu" ]]; then ./.travis_coveralls.sh; fi
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
make check-coverage-libicu
|
make check-coverage-libicu
|
||||||
|
pip install --upgrade pip
|
||||||
pip install --user urllib3[secure] cpp-coveralls
|
pip install --user urllib3[secure] cpp-coveralls
|
||||||
|
|
||||||
# Work around https://github.com/eddyxu/cpp-coveralls/issues/108 by manually
|
# Work around https://github.com/eddyxu/cpp-coveralls/issues/108 by manually
|
||||||
# installing the pyOpenSSL module and injecting it into urllib3 as per
|
# installing the pyOpenSSL module and injecting it into urllib3 as per
|
||||||
# https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2
|
# https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2
|
||||||
sed -i -e '/^import sys$/a import urllib3.contrib.pyopenssl\nurllib3.contrib.pyopenssl.inject_into_urllib3()' `which coveralls`
|
#sed -i -e '/^import sys$/a import urllib3.contrib.pyopenssl\nurllib3.contrib.pyopenssl.inject_into_urllib3()' `which coveralls`
|
||||||
|
|
||||||
coveralls -t d9uGTP4NSD092kh2b85aDSsEDxatcYC6F --include src/
|
coveralls -t d9uGTP4NSD092kh2b85aDSsEDxatcYC6F --include src/
|
||||||
|
|
18
configure.ac
18
configure.ac
|
@ -77,6 +77,23 @@ AM_PATH_PYTHON([2.7])
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([cfi],
|
||||||
|
[AS_HELP_STRING([--enable-cfi], [Turn on clang's Control Flow Integrity (CFI) (for developers)])],
|
||||||
|
[
|
||||||
|
clang_cfi=$enableval;
|
||||||
|
if test "$enableval" = yes; then
|
||||||
|
CFLAGS=$CFLAGS" -B/usr/bin/gold -fsanitize=cfi -flto -fvisibility=default -fno-sanitize-trap=all"
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([], [])
|
||||||
|
], [], [
|
||||||
|
AC_MSG_ERROR([clang 3.7+ and the 'gold' linker are required for --enable-cfi])
|
||||||
|
])
|
||||||
|
else
|
||||||
|
clang_cfi=no
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[clang_cfi=no])
|
||||||
|
|
||||||
# Define these substitions here to keep all version information in one place.
|
# Define these substitions here to keep all version information in one place.
|
||||||
# For information on how to properly maintain the library version information,
|
# For information on how to properly maintain the library version information,
|
||||||
# refer to the libtool manual, section "Updating library version information":
|
# refer to the libtool manual, section "Updating library version information":
|
||||||
|
@ -287,6 +304,7 @@ AC_MSG_NOTICE([Summary of build options:
|
||||||
CFlags: ${CFLAGS} ${CPPFLAGS}
|
CFlags: ${CFLAGS} ${CPPFLAGS}
|
||||||
LDFlags: ${LDFLAGS}
|
LDFlags: ${LDFLAGS}
|
||||||
Libs: ${LIBS}
|
Libs: ${LIBS}
|
||||||
|
CFI: ${clang_cfi}
|
||||||
Runtime: ${enable_runtime}
|
Runtime: ${enable_runtime}
|
||||||
Builtin: ${enable_builtin}
|
Builtin: ${enable_builtin}
|
||||||
PSL Dist File: ${PSL_DISTFILE}
|
PSL Dist File: ${PSL_DISTFILE}
|
||||||
|
|
|
@ -43,6 +43,9 @@ for CC in gcc clang; do
|
||||||
"--enable-runtime=libidn --enable-builtin=libidn" \
|
"--enable-runtime=libidn --enable-builtin=libidn" \
|
||||||
"--disable-runtime --enable-builtin=libicu"; do
|
"--disable-runtime --enable-builtin=libicu"; do
|
||||||
export DISTCHECK_CONFIGURE_FLAGS="-C --cache-file=$CACHEFILE $options"
|
export DISTCHECK_CONFIGURE_FLAGS="-C --cache-file=$CACHEFILE $options"
|
||||||
|
if test "$CC" == "clang"; then
|
||||||
|
export DISTCHECK_CONFIGURE_FLAGS=$DISTCHECK_CONFIGURE_FLAGS" --enable-cfi"
|
||||||
|
fi
|
||||||
echo
|
echo
|
||||||
echo " *** ./configure $DISTCHECK_CONFIGURE_FLAGS"
|
echo " *** ./configure $DISTCHECK_CONFIGURE_FLAGS"
|
||||||
./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS="$CFLAGS" > /dev/null
|
./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS="$CFLAGS" > /dev/null
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) -Wno-unused-parameter
|
AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) -Wno-unused-parameter
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(srcdir) -DSRCDIR=\"$(abs_srcdir)\" -DTEST_RUN
|
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(srcdir) -DSRCDIR=\"$(abs_srcdir)\" -DTEST_RUN
|
||||||
AM_LDFLAGS = -static
|
#AM_LDFLAGS = -static
|
||||||
LDADD = ../src/libpsl.la
|
AM_LDFLAGS = -no-install
|
||||||
|
LDADD = ../src/libpsl.la $(LIBICU_LIBS) $(LIBIDN_LIBS) $(LIBIDN2_LIBS)
|
||||||
|
|
||||||
PSL_TESTS = \
|
PSL_TESTS = \
|
||||||
libpsl_fuzzer$(EXEEXT) \
|
libpsl_fuzzer$(EXEEXT) \
|
||||||
|
|
|
@ -65,3 +65,12 @@ To work on corpora for better coverage, `cd fuzz` and use e.g.
|
||||||
|
|
||||||
Each reproducer file should be dropped into the appropriate *.repro/
|
Each reproducer file should be dropped into the appropriate *.repro/
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
|
|
||||||
|
# Clang CFI instrumentation
|
||||||
|
```
|
||||||
|
CC=clang-5.0 CFLAGS="-B/usr/bin/gold -O0 -fsanitize=cfi -flto -fvisibility=default -fno-sanitize-trap=all" ./configure
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
make check
|
||||||
|
```
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
DEFS = @DEFS@ -DSRCDIR=\"$(srcdir)\" -DPSL_FILE=\"$(PSL_FILE)\" -DPSL_TESTFILE=\"$(PSL_TESTFILE)\"
|
DEFS = @DEFS@ -DSRCDIR=\"$(srcdir)\" -DPSL_FILE=\"$(PSL_FILE)\" -DPSL_TESTFILE=\"$(PSL_TESTFILE)\"
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
LDADD = ../src/libpsl.la
|
LDADD = ../src/libpsl.la
|
||||||
|
AM_LDFLAGS = -no-install
|
||||||
|
|
||||||
# ./configure'd with '--disable-builtin'
|
# ./configure'd with '--disable-builtin'
|
||||||
# Do not call test-is-public-builtin here: it does not make sense.
|
# Do not call test-is-public-builtin here: it does not make sense.
|
||||||
|
|
Loading…
Reference in New Issue