Translation(s): none


What is all this about?

dpkg-buildflags allows a uniform setting of default build flags for code written in C and C++. If your package is written in Java, pure Python, pure Perl or shell you don't need to do anything. Good, isn't it?

Default build flags have a number of benefits:

Enabling dpkg-buildflags in your package is two-fold. On the one hand you need to activate the flags your debian/rules file, on the other hand you need to ensure that the buildsystem of your code abides the necessary flags.

Selecting security hardening options

The standard build flags for Wheezy include the following

These hardening features are explained in more depth here.

Additionally there are two features, which are not enabled by default:

It is recommended to test, whether these two options work with your package and enable them if everything works fine. You can enable them by adding this your rules file:

export DEB_BUILD_MAINT_OPTIONS = hardening=+all

Enabling dpkg-buildflags in your debian/rules files

rules files based on debhelper and minimised dh(1)

If you have already converted your rules file to the minimised dh(1) form, enabling dpkg-buildflags is fairly easy: If you upgrade to compat level 9, they will be auto-injected during build. If you want to stay with earlier compat levels, you can still inject the build flags by passing them to dh_auto_configure, e.g.

override_dh_auto_configure:
       dh_auto_configure -- $(shell dpkg-buildflags --export=configure)

rules files based on standard debhelper or hand-written rules files

If your build file uses the standard debhelper format, the way of injecting the flags depends on your build system. If it's based on the autotools, passing the exported form of dpkg-buildflags to the configure script is usually needed, e.g.

../configure --prefix=/usr $(shell dpkg-buildflags --export=configure) 

If your build system reads the values from standard environment variables like CFLAGS, CXXFLAGS, CPPFLAGS or LDFLAFS, you often need to export these values at the beginning of your rules files. The simplest way to achieve this is to include the following snippet from dpkg at the beginning of your rules file:

DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/buildflags.mk

This will export all the needed flags.

rules files based on cdbs

cdbs already exports CFLAGS from dpkg-buildflags and it will soon be fixed to also export CPPFLAGS and LDFLAGS. If your package uses cdbs you will usually only need to verify, whether your upstream buildsystem properly follows these flags. The relevant cdbs bug is bug 651964

Handling dpkg-buildflags in your upstream build system

To fully support all hardened build flags in your upstream buildsystem, please ensure that the following flags are supported:

CFLAGS, CPPFLAGS and LDFLAGS for code written in C CXXFLAGS, CPPFLAGS and LDFLAGS for code written in C++

buildsystems based on the autotools

If your buildsystem is based on autotools it usually requires no further modifications. If might however occur that some variables are hard-coded in one of the Makefile.in files. An examples for this can be found at bug 655870

Handwritten Makefiles

If your package uses a home-grown buildsystems you first need to check, whether it abides the above-mentioned flags. If not, you can either add the dpkg-buildflags calls directly as part of your Debian-specific modifications. Another solution would to fix the Makefiles to source an already existing environment variable.

Many home-grown Makefiles already support CFLAGS and LDFLAGS, but not CPPFLAGS. In most cases you can simply append CPPFLAGS to CFLAGS, e.g.

CFLAGS = `dpkg-buildflags --get CFLAGS`
CFLAGS += `dpkg-buildflags --get CPPFLAGS`

buildsystems for Perl modules

The conversion of Perl modules is still under discussion, please follow the discussion at bug 657853

buildsystems using cmake

cmake doesn't follow CPPFLAGS. A fix was briefly available in sid, but had been revoked since upstream rejected the patch. See bug 653916 for details. As a workaround appending CPPFLAGS to CFLAGS and CXXFLAGS should work in most cases.

Testing your packages after conversion

"hardening-check" from the "hardening-includes" allows testing a binary, whether hardening options have been properly enabled. If you're using only the default flags emitted by dpkg-buildflags, you should see "Stack protected", "Fortify Source functions" and "Read-only relocations" marked as "Yes", e.g.

jmm@pisco:~$ hardening-check /usr/bin/emacs23
/usr/bin/emacs23:
 Position Independent Executable: no, normal executable!
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: no not found!

In some cases, "Stack protected" and "Fortify Source functions" emit false positives, see these notes from hardening-check's manpage:

If a package has enabled all flags, the output should look like this:

jmm@pisco:~$ hardening-check /usr/sbin/sshd
/usr/sbin/sshd:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

Common questions / problems

My package already uses hardening-wrapper or hardening-includes. Should I switch to dpkg-buildflags?

Both will not go away any time soon, but it is advised to convert to dpkg-buildflags instead, since it's a more generalised solution to the problem and is also useful beyond security hardening.

My package builds with optimisation flags other than -O2, e.g. -Os

You can add the following to your rules before before invoking dpkg-buildflags

DEB_CFLAGS_MAINT_APPEND=-Os

Are there example patches?

Many of the bugs filed for the hardening flags Wheezy release goal have patches attached.

How can I use this and keep my packages backportable to Squeeze?

squeeze-backports includes a backport of 1.16.1.1, so all should be fine.

Additionally, dpkg-buildflags already existed in plain Squeeze (emitting only flags w/o hardening:

$ dpkg-buildflags --get CFLAGS
-g -O2
$ dpkg-buildflags --get CPPFLAGS

$ dpkg-buildflags --get LDFLAGS

$ dpkg-buildflags --get CXXFLAGS
-g -O2

Most of the convenience functions (/usr/share/dpkg/buildflags.mk and dpkg-buildflags --export=configure) don't exist yet, though. As such, you need to export your flags like this:

CFLAGS:=$(shell dpkg-buildflags --get CFLAGS)
CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS)
LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS)

Is there a lintian test?

A lintian test is in preparation, see this bug to monitor the progress.

My package isn't security-sensitive, should I still convert it?

Yes. dpkg-buildflags easies rebuilding Debian with modified build flags and is useful to spot long-standing bugs in your packages, see this blog posting on Planet Debian for an example.