1#!/usr/bin/make -f 2# 3# Copyright (C) 2009-2014 Kees Cook <kees@debian.org> 4# License: GPLv2 or newer 5# 6# This file is intended to be included in a Debian rules file so that the 7# the calculated HARDENING_CFLAGS and HARDENING_LDFLAGS from this makefile 8# can by used in the package's CFLAGS (and/or CXXFLAGS) and LDFLAGS to 9# harden the security of a package's resulting binaries. For example: 10# 11# include /usr/share/hardening-includes/hardening.make 12# CFLAGS += $(HARDENING_CFLAGS) 13# LDFLAGS += $(HARDENING_LDFLAGS) 14# 15# and if you need it for C++ compilations: 16# 17# CXXFLAGS += $(HARDENING_CFLAGS) 18# 19# 20# By default, all hardening options that are valid for a given architecture 21# are enabled. The following can be set before or after including this 22# makefile: 23# To disable all hardening: DEB_BUILD_HARDENING:=0 24# To disable PIE: DEB_BUILD_HARDENING_PIE:=0 25# To disable stack protector: DEB_BUILD_HARDENING_STACKPROTECTOR:=0 26# To disable Fortify Source: DEB_BUILD_HARDENING_FORTIFY:=0 27# To disable format string checks: DEB_BUILD_HARDENING_FORMAT:=0 28# To disable readonly relocations: DEB_BUILD_HARDENING_RELRO:=0 29# To disable BIND_NOW: DEB_BUILD_HARDENING_BINDNOW:=0 30# 31# For more details, see https://wiki.debian.org/Hardening 32# 33# Thanks to Ryan Niebur for help with the Makefile magicks. 34# 35# -- Kees Cook <kees@debian.org> 36 37DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH 2>/dev/null) 38DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS 2>/dev/null) 39 40DEB_BUILD_HARDENING ?= 1 41 42ifneq (,$(filter $(DEB_HOST_ARCH_OS), linux knetbsd hurd )) 43 # PIE enabled only on linux, knetbsd, and hurd (bugs 430455 and 586215) 44 ifeq (,$(filter $(DEB_HOST_ARCH), hppa m68k mips mipsel avr32 )) 45 # disabled on hppa (bug number needed) 46 # disabled on m68k (bug 451192) 47 # disabled on mips/mipsel (toolchain bug 532821) 48 # disabled on avr32 (bug 574716) 49 DEB_BUILD_HARDENING_PIE ?= 1 50 endif 51endif 52DEB_BUILD_HARDENING_PIE ?= 0 53 54ifneq (,$(filter $(DEB_HOST_ARCH), ia64 alpha hppa arm)) 55 # Stack protector disabled on ia64, alpha, hppa. 56 # "warning: -fstack-protector not supported for this target" 57 # Stack protector disabled on arm (ok on armel, armhf). 58 # compiler supports it incorrectly (leads to SEGV) 59 DEB_BUILD_HARDENING_STACKPROTECTOR ?= 0 60endif 61DEB_BUILD_HARDENING_STACKPROTECTOR ?= 1 62 63ifneq (,$(filter $(DEB_HOST_ARCH), ia64 hppa avr32 )) 64 DEB_BUILD_HARDENING_RELRO ?= 0 65endif 66DEB_BUILD_HARDENING_RELRO ?= 1 67 68DEB_BUILD_HARDENING_FORTIFY ?= 1 69DEB_BUILD_HARDENING_FORMAT ?= 1 70DEB_BUILD_HARDENING_BINDNOW ?= 1 71 72_HARDENED_PIE_CFLAGS := -fPIE 73_HARDENED_PIE_LDFLAGS := -fPIE -pie 74 75_HARDENED_STACKPROTECTOR_CFLAGS := -fstack-protector-strong 76 77# Fortify Source requires that -O1 or higher is used, but that should be 78# handled outside of this include file. 79_HARDENED_FORTIFY_CFLAGS := -D_FORTIFY_SOURCE=2 80 81_HARDENED_FORMAT_CFLAGS := -Wformat -Wformat-security -Werror=format-security 82 83_HARDENED_RELRO_LDFLAGS := -Wl,-z,relro 84 85_HARDENED_BINDNOW_LDFLAGS := -Wl,-z,now 86 87_hardening_enabled = $(if $(filter $(DEB_BUILD_HARDENING), yes 1 on true),\ 88$(if $(filter $(1), yes 1 on true),$(2),),) 89 90HARDENING_CFLAGS ?= \ 91$(call _hardening_enabled,$(DEB_BUILD_HARDENING_PIE),$(_HARDENED_PIE_CFLAGS)) \ 92$(call _hardening_enabled,$(DEB_BUILD_HARDENING_STACKPROTECTOR),$(_HARDENED_STACKPROTECTOR_CFLAGS)) \ 93$(call _hardening_enabled,$(DEB_BUILD_HARDENING_FORTIFY),$(_HARDENED_FORTIFY_CFLAGS)) \ 94$(call _hardening_enabled,$(DEB_BUILD_HARDENING_FORMAT),$(_HARDENED_FORMAT_CFLAGS)) \ 95 96HARDENING_LDFLAGS ?= \ 97$(call _hardening_enabled,$(DEB_BUILD_HARDENING_PIE),$(_HARDENED_PIE_LDFLAGS)) \ 98$(call _hardening_enabled,$(DEB_BUILD_HARDENING_RELRO),$(_HARDENED_RELRO_LDFLAGS)) \ 99$(call _hardening_enabled,$(DEB_BUILD_HARDENING_BINDNOW),$(_HARDENED_BINDNOW_LDFLAGS)) \ 100 101# Utility macros designed to allow package maintainer to force a given 102# hardening feature off in certain areas of a build without disabling 103# the option for the entire build. For example: 104# CFLAGS += $(HARDENING_CFLAGS) 105# monkey.o: monkey.c 106# $(CC) $(CFLAGS) $(HARDENING_DISABLE_STACKPROTECTOR_CFLAGS) $< -o $@ 107HARDENING_DISABLE_STACKPROTECTOR_CFLAGS:=-fno-stack-protector 108HARDENING_DISABLE_FORTIFY_CFLAGS:=-U_FORTIFY_SOURCE 109HARDENING_DISABLE_FORMAT_CFLAGS:=-Wno-format-security 110HARDENING_DISABLE_RELRO_LDFLAGS:=-Wl,-z,norelro 111HARDENING_DISABLE_BINDNOW_LDFLAGS:=-Wl,-z,lazy 112# Note: GCC does not have a way to just turn off pie (there is no "-nopie") 113# so if PIE needs to be disabled for a specific target, the CFLAGS and LDFLAGS 114# need to be filtered. For example: 115# monkey: monkey.c 116# $(CC) $(filter-out $(HARDENING_DISABLE_PIE_CFLAGS_FILTER),$(CFLAGS)) \ 117# $(filter-out $(HARDENING_DISABLE_PIE_LDFLAGS_FILTER),$(LDFLAGS)) \ 118# $< -o $@ 119# 120# Note: when building shared libraries, or with some build frameworks (e.g. 121# cmake) that pass "-fPIC" to everything, the "-fPIE" option must be filtered 122# out to avoid building shared objects that need PIC but end up only with PIE. 123# This is usually indicated by errors at link time that look like this: 124# relocation R_X86_64_PC32 against symbol `foo' can not be used when making a shared object; recompile with -fPIC 125# In these cases, the CFLAGS can be filtered to exclude "-fPIE" until this 126# is fixed in gcc correctly. For example, on one target: 127# monkey.o: monkey.c 128# $(CC) $(filter-out $(HARDENING_DISABLE_PIE_CFLAGS_FILTER),$(CFLAGS)) \ 129# $< -c -o $@ 130# In cases where mixed shared objects and executable objects are being built, 131# "-fPIC" needs to actually replace "-fPIE", since gcc won't distinguish 132# between them yet. For example: 133# export CFLAGS=$(shell dpkg-buildflags --get CFLAGS) 134# CFLAGS += $(HARDENING_CFLAGS_PIC) \ 135# $(filter-out $(HARDENING_DISABLE_PIE_CFLAGS_FILTER),$(HARDENING_CFLAGS)) 136# 137HARDENING_DISABLE_PIE_CFLAGS_FILTER:=$(_HARDENED_PIE_CFLAGS) 138HARDENING_DISABLE_PIE_LDFLAGS_FILTER:=$(_HARDENED_PIE_LDFLAGS) 139HARDENING_CFLAGS_PIC:=-fPIC 140