[ubuntu-hardened] apache2 and hardening flags: hardening-wrapper and buildflags.mk

Kees Cook kees at ubuntu.com
Tue Jan 7 20:22:45 UTC 2014


Hi,

On Mon, Jan 06, 2014 at 05:52:26PM +0000, Robie Basak wrote:
> • 2.4.7-1 uses export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow. What about
> PIE? Do we want hardening=+all in Ubuntu instead?

The Apache upstream supports PIE itself (see --enable-pie in the rules
file), so strictly speaking, it shouldn't be needed to be forced on via
build flags. Generally if an upstream handles it, that method should be
used.

Only 2 hardening features are not enabled by default: PIE and BIND_NOW, so
since upstream can enable PIE via configure, only BIND_NOW is needed to be
forced on.

> • 2.4.6-2ubuntu4 uses hardnening-wrapper. Is this superfluous, given that
> 2.4.7-1 uses buildflags.mk? Can I drop the use of hardening-wrapper?

Yeah, hardening-wrapper can be dropped if buildflags.mk or dh(1) is being
used. (And DEB_BUILD_MAINT_OPTIONS=hardening=+all (modulo upstream
configure abilities) is used.)

> • I used hardening-check to verify the resulting binaries built without our
> previous Ubuntu hardening delta. Results below. Does this mean that just
> dropping the Ubuntu delta for hardening is sufficient, as all hardening is now
> done by default through buildflags.mk, which Debian uses?

Looks like it, yes.

> • Given that we now have dep8 testing capability, should we have dep8 tests
> that run hardening-check to prevent hardening regressions? If so, can we
> standardise on how this should be done?

Since hardening-check isn't 100% accurate, it won't be perfect, but I
can't see a reason NOT to do this.

> • Is hardening-check sufficient on its own to detect regressions, or are there
> other hardening flags that might be missed or regressed that hardening-check
> does not detect?

Detecting -D_FORTIFY_SOURCE=2 and -fstack-protector can't be 100%
accurate, since some fortify functions are entirely done at build time and
require no runtime changes (i.e. undetectable in final binary), and if
nothing triggered the stack-protector, you can't tell if the compiler
option was missing. And, of course, if object files were compiled with
different options, it's not possible to detect if some got missed. As
such, hardening-check is mostly just a finger-in-the-air check for these
two features. All the other features are very binary (e.g. PIE is either
on or off, there's no way to do it half-way).

> • So what's the current best practice in Ubuntu for building hardened packages
> that use buildflags.mk and thus do not need hardening-wrapper?

If buildflags.mk is in use, then:
DEB_BUILD_MAINT_OPTIONS=hardening=+all
unless there is a strong reason not to use PIE.

> >From my latest merge in progress, which does not apply the previous Ubuntu
> hardening delta at all:
> /usr/lib/apache2/modules/mod_dav.so:
>  Fortify Source functions: no, only unprotected functions found!
> 
> From 2.4.6-2ubuntu4:
> /usr/lib/apache2/modules/mod_dav.so:
>  Fortify Source functions: no, only unprotected functions found!

In this case, I would just carefully examine the build logs for mod_dav.so
to verify that -D_FORTIFY_SOURCE=2 is, in fact, being passed to the
compiler.

> #!/usr/bin/make -f
> [snip]
> override_dh_auto_configure: generate-maintainer-scripts prebuild-checks support/suexec-custom.c
> 	./configure --enable-layout=Debian --enable-so --with-program-name=apache2 \
> 		--enable-suexec --with-suexec-caller=www-data \
> 		--with-suexec-bin=/usr/lib/apache2/suexec --with-suexec-docroot=/var/www \
> 		--with-suexec-userdir=public_html --with-suexec-logfile=/var/log/apache2/suexec.log \
> 		--with-suexec-uidmin=100 --enable-suexec=shared --enable-log-config=static \
> 		--with-apr=/usr/bin/apr-1-config --with-apr-util=/usr/bin/apu-1-config \
> 		--with-pcre=yes \
> 		--enable-pie \
^^^^^^^^^^^^^^^^^^^^ upstream doing the PIEness

> diff --git a/debian/rules b/debian/rules
> index adbf36d..cf01181 100755
> --- a/debian/rules
> +++ b/debian/rules
> @@ -6,12 +6,14 @@ DEB_BUILD_ARCH_OS    ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
>  # Uncomment this to turn on verbose mode.
>  # export DH_VERBOSE=1
>  
> +export DEB_BUILD_HARDENING=1
> +
>  LSB_RELEASE := $(shell lsb_release -i -s)
>  SERVER_VERSION := $(shell dpkg-parsechangelog | perl -ne 'print $$1 if m/Version:\s*([\d\.]+)/')
>  DEBIAN_VERSION := $(shell dpkg-parsechangelog | perl -ne 'print $$1 if m/Version:\s*(.+)/')
>  MODULE_DIR := /usr/lib/apache2/modules/
>  API = $(shell perl -ne 'print $$1 if m/define\s+MODULE_MAGIC_NUMBER_MAJOR\s+?(.*)$$/' < include/ap_mmn.h)
> -AP2_CFLAGS = -pipe $(shell dpkg-buildflags --get CFLAGS)
> +AP2_CFLAGS = -pipe $(shell dpkg-buildflags --get CFLAGS) -Wformat-security -D_FORTIFY_SOURCE=2 -fstack-protector -fno-strict-aliasing

This change is rather weird -- I won't have expected it to be needed for
hardening-wrapper. But if something is going weird for the users of
AP2_CFLAGS, I'd just look at the build log.

It may be possible that maybe this needs "--get CPPFLAGS" too? Though the
stuff added includes things from both CPPFLAGS and CFLAGS.

$ dpkg-buildflags --get CPPFLAGS
-D_FORTIFY_SOURCE=2

$ dpkg-buildflags --get CFLAGS
-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security

Anyway, just make sure all gcc lines include the needed CPPFLAGS and
CFLAGS, and things should be okay.

-Kees

-- 
Kees Cook



More information about the ubuntu-hardened mailing list