From patchwork Thu Sep 13 20:26:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Weber X-Patchwork-Id: 969532 Return-Path: X-Original-To: incoming-buildroot@patchwork.ozlabs.org Delivered-To: patchwork-incoming-buildroot@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=busybox.net (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=buildroot-bounces@busybox.net; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=rockwellcollins.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42B9Cj1j2Bz9s4V for ; Fri, 14 Sep 2018 06:26:25 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 056098750E; Thu, 13 Sep 2018 20:26:20 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4C2IXR5GmV_I; Thu, 13 Sep 2018 20:26:17 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by fraxinus.osuosl.org (Postfix) with ESMTP id 204DD874D4; Thu, 13 Sep 2018 20:26:17 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id CA2701C1011 for ; Thu, 13 Sep 2018 20:26:14 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id C73E687D86 for ; Thu, 13 Sep 2018 20:26:14 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kYac+SfKN4a0 for ; Thu, 13 Sep 2018 20:26:11 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from ch3vs01.rockwellcollins.com (ch3vs01.rockwellcollins.com [205.175.226.27]) by whitealder.osuosl.org (Postfix) with ESMTPS id 7DA7988247 for ; Thu, 13 Sep 2018 20:26:11 +0000 (UTC) Received: from ofwch3n02.rockwellcollins.com (HELO dtulimr01.rockwellcollins.com) ([205.175.226.14]) by ch3vs01.rockwellcollins.com with ESMTP; 13 Sep 2018 15:26:10 -0500 X-Received: from largo.rockwellcollins.com (unknown [192.168.140.76]) by dtulimr01.rockwellcollins.com (Postfix) with ESMTP id 4AAB6601D0; Thu, 13 Sep 2018 15:26:10 -0500 (CDT) From: Matt Weber To: buildroot@buildroot.org Date: Thu, 13 Sep 2018 15:26:04 -0500 Message-Id: <1536870367-38035-2-git-send-email-matthew.weber@rockwellcollins.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1536870367-38035-1-git-send-email-matthew.weber@rockwellcollins.com> References: <1536870367-38035-1-git-send-email-matthew.weber@rockwellcollins.com> Subject: [Buildroot] [PATCH v3 1/4] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.24 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" The current implementation is broken for full RELRO as the conditional checking of flag combinations both for compile and link time need to occur at the point of use in a package (GCC/LD invocation using specfile) or be enforced via a toolchain wrapper GCC/LD args adjustment. If the current approach is maintained, a large amount of packages will need to be patched and made aware of this scenario or at a minimum reorder their flag usage to be compatible. I've found this type of patch to be hard to upstream and in some cases touch makefiles that haven't required updates on stable (unmaintained) projects. There have been two main approaches for a solution (specfile vs toolchain wrapper). The specfile approach proposed by Stefan is a working solution and has been tested by me with a few different target package configurations as well as an internal autobuilder regressioning this feature. This solution isn't ideal as it adds another way Buildroot is adjusting flags that may confuse/conflict with the toolchain wrapper approach. (Ref Stefan's patch: http://patchwork.ozlabs.org/patch/942524/) The second option was the addition of a new linker wrapper but after completing that approach, the amount of complexity and new software, seems to out weigh possibly doing a hybrid approach proposed in this patchset. The one main complexity of solely using wrappers, is the fact that the GCC wrapper needs to know if it is being called with LDFLAGS vs not. So it really had to handle both compile and link cases which could overlap. Then the seperate new linker toolchain wrapper would handle the sole linker case. This resulted in extra bookkeeping flags and felt heavy. New linker wrapper example ref: http://patchwork.ozlabs.org/patch/963748/ http://patchwork.ozlabs.org/patch/963743/ The hybrid approach updates the existing GCC wrapper to handle the conditional fix-ups to the CFLAGS and utilizes the linker specfile which would be included when GCC links via LDFLAGS to handle the more basic link time fix-up. The linker specfile would also be included when LD is directly used and satisfy that case. This handles the sunny day scenario where the FLAGS are being used correctly and doesn't try to accomodate/fix package mis-use. It does force the compile time fixup, however when testing I noticed it was not a good idea to try and force the link time behavior (ie. if LDFLAGS were not explicitly provided). In most cases when I forced the link time behavior, I ended up with broken builds (had an offline autobuilder helping me assess this). Link time adjustments for flag usage in the special case, ideally need to be worked as a build output is reviewed on a case by case basis. This also helps manage the situations where autotools and similar build configuration/capability testing, may conflict with flags being forced whenever GCC or LD are invoked. Signed-off-by: Matthew Weber --- Changes v2 -> v3 - Fell back on a linker approach using a spec file and kept compiler flag tweaks in the wrapper v1 -> v2 - Reworked handling of pie/pic/shared to replace each time they occur with a dummy string and then insert the right combination when rebuilding the exec string. - Fixed mix of tabs and spaces - Swapped order of shared and pie. Originally coded it backwards. --- package/Makefile.in | 4 ++-- toolchain/gcc-specs-pie-ld | 2 ++ toolchain/toolchain-wrapper.c | 20 +++++++++++++++++++- toolchain/toolchain-wrapper.mk | 4 ++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 toolchain/gcc-specs-pie-ld diff --git a/package/Makefile.in b/package/Makefile.in index abfdb81..36b5139 100644 --- a/package/Makefile.in +++ b/package/Makefile.in @@ -158,8 +158,8 @@ ifeq ($(BR2_RELRO_PARTIAL),y) TARGET_HARDENED += $(TARGET_CFLAGS_RELRO) TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO) else ifeq ($(BR2_RELRO_FULL),y) -TARGET_HARDENED += -fPIE $(TARGET_CFLAGS_RELRO_FULL) -TARGET_LDFLAGS += -pie $(TARGET_CFLAGS_RELRO_FULL) +TARGET_HARDENED += $(TARGET_CFLAGS_RELRO_FULL) +TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO_FULL) -specs=$(TOPDIR)/toolchain/gcc-specs-pie-ld endif ifeq ($(BR2_FORTIFY_SOURCE_1),y) diff --git a/toolchain/gcc-specs-pie-ld b/toolchain/gcc-specs-pie-ld new file mode 100644 index 0000000..bd6b907 --- /dev/null +++ b/toolchain/gcc-specs-pie-ld @@ -0,0 +1,2 @@ +*self_spec: ++ %{!static:%{!shared:%{!r:-pie}}} diff --git a/toolchain/toolchain-wrapper.c b/toolchain/toolchain-wrapper.c index c5eb813..fbc3fc7 100644 --- a/toolchain/toolchain-wrapper.c +++ b/toolchain/toolchain-wrapper.c @@ -49,8 +49,9 @@ static char _date_[sizeof("-D__DATE__=\"MMM DD YYYY\"")]; * -D__TIME__= * -D__DATE__= * -Wno-builtin-macro-redefined + * -fPIE */ -#define EXCLUSIVE_ARGS 6 +#define EXCLUSIVE_ARGS 7 static char *predef_args[] = { #ifdef BR_CCACHE @@ -363,6 +364,23 @@ int main(int argc, char **argv) *cur++ = "-Wno-builtin-macro-redefined"; } +#ifdef BR2_RELRO_FULL + /* Must handle combinations of compiler/link options */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-r") || + !strcmp(argv[i], "-fpie") || + !strcmp(argv[i], "-fPIE") || + !strcmp(argv[i], "-fpic") || + !strcmp(argv[i], "-fPIC") || + !strcmp(argv[i], "-fno-pic") || + !strcmp(argv[i], "-static")) + break; + } + if (i == argc) { + *cur++ = "-fPIE"; + } +#endif + paranoid_wrapper = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); if (paranoid_wrapper && strlen(paranoid_wrapper) > 0) paranoid = 1; diff --git a/toolchain/toolchain-wrapper.mk b/toolchain/toolchain-wrapper.mk index b8074ef..ec0f128 100644 --- a/toolchain/toolchain-wrapper.mk +++ b/toolchain/toolchain-wrapper.mk @@ -45,6 +45,10 @@ ifeq ($(BR2_CCACHE_USE_BASEDIR),y) TOOLCHAIN_WRAPPER_ARGS += -DBR_CCACHE_BASEDIR='"$(BASE_DIR)"' endif +ifeq ($(BR2_RELRO_FULL),y) +TOOLCHAIN_WRAPPER_ARGS += -DBR2_RELRO_FULL +endif + define TOOLCHAIN_WRAPPER_BUILD $(HOSTCC) $(HOST_CFLAGS) $(TOOLCHAIN_WRAPPER_ARGS) \ -s -Wl,--hash-style=$(TOOLCHAIN_WRAPPER_HASH_STYLE) \