From patchwork Wed Nov 1 04:52:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaakov Selkowitz X-Patchwork-Id: 117670 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp421986qgn; Tue, 31 Oct 2017 21:53:26 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Tl8qnPIQOPxN3hkyQkRLSOybYtTffEB4JaXP9zNY79gaPofhqeUE50TqziHPE/ecPW0qNy X-Received: by 10.99.55.82 with SMTP id g18mr4469660pgn.31.1509512006363; Tue, 31 Oct 2017 21:53:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509512006; cv=none; d=google.com; s=arc-20160816; b=qiQ9tRHUUqrZ230AlnBE3/JSYsbogJL/hm6i8SyoYFG1cH25wdIUmFcu3rF8gz2XYI E7GHYBTGPpYM4W3UOpUX3tjdjkayW/1C0th05gn/yWLAugfMuW8FQMsGFiIB2zuGUbiq hCWiSJOaUHAQ4lmCu5/TWQdTd3R/SAL1UBNAJUmB06EEjKVh8fiQj6ySbZj15J+yqHLs 4xhk4qNpoVvbQOM2flNJxfs9EhrIGRXrAn9mugzNd746rBzAhXbv0BR3dAdIpGae9cvX AmsW4q+BiVSU+XYEzbfnBdS4ai5buuyzgnIN2PTIQfLRy49ecJIW1piaHmvL/AOww3Ta Jt8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:dmarc-filter :delivered-to:sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=zyDu8bvj5ItzZJncmn1fcLL34EmoZ2UymCupC3vr+QI=; b=blzjOcBvzO4a6Og9vJtuRGbr47SMnHXQYLApej2VCn0o0Yz0fdkkdts8d1tu4EkaJm g2AwI3NZsUDngm/ePhfczwp6cm+kmUKPwYlT8ay0lSoKfSfusGtJbsABrnsw9hXDBmfd oZQeWnjIWdIJSY39BoUoy2ZZ+JxwGroLFZFhri0jR8TYjAEdwzQ0Yx/dzBJXtXGc6hgT lkWOaNwbiaaC05kiOOEatZCLwdr6eQE5YvchGnsOOW0UUijyhxmhkFWNMY+5ujwULIGf W8w62PGzCRO+1Uj5CThx/yAplamEcMGm4ptxj8mGxppnsQL/A4KvvM8yHIYZs6h7Af8t VwYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=utGTyxjt; spf=pass (google.com: domain of newlib-return-15296-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=newlib-return-15296-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id y65si3756760pfi.384.2017.10.31.21.53.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Oct 2017 21:53:26 -0700 (PDT) Received-SPF: pass (google.com: domain of newlib-return-15296-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=utGTyxjt; spf=pass (google.com: domain of newlib-return-15296-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=newlib-return-15296-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=uZg4uBXZw9+0w0OpEECB7/CpI+uX58q oeY9qxBrl5Rhu8jCBco5u2L76RuXxWPoVmgHX2MxDUsYwkZpKU4Y1b4O1D0uOrfA y32inJo+mYq/IWLX5MsZY262UTra3ouu4f/1MzEvlJacDV7BLMgDmwHPWtmiuA6W r0t9/F8GvKd4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=ZiQvLr7nZfxVArLlOsnrdnoi0KI=; b=utGTy xjtBLR4H8DDMScQPysmXzMExva7CHGE2Iqxxp9ApFUGfEJBKsgc4Fn/DX+kF46NP 1eFuoIu8qa283TS34L/Dvgl6gewn2T/qOQuM+0YBndaJ3LOtD/uPHpbNElF3OVUM Ya5vnBUE1c6BZ08Blg3J0OQO6swB7svy/gqI10= Received: (qmail 105877 invoked by alias); 1 Nov 2017 04:53:03 -0000 Mailing-List: contact newlib-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: newlib-owner@sourceware.org Delivered-To: mailing list newlib@sourceware.org Received: (qmail 105549 invoked by uid 89); 1 Nov 2017 04:53:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=DIRECT, WAY, consequential, BUT X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 01 Nov 2017 04:53:01 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 271F981DE1 for ; Wed, 1 Nov 2017 04:53:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 271F981DE1 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=yselkowi@redhat.com Received: from localhost.localdomain (ovpn-125-104.rdu2.redhat.com [10.10.125.104]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A3E7660605 for ; Wed, 1 Nov 2017 04:52:59 +0000 (UTC) From: Yaakov Selkowitz To: newlib@sourceware.org Subject: [PATCH v1 01/10] ssp: add APIs for Stack Smashing Protection (-fstack-protector*) Date: Tue, 31 Oct 2017 23:52:37 -0500 Message-Id: <20171101045246.16596-2-yselkowi@redhat.com> In-Reply-To: <20171101045246.16596-1-yselkowi@redhat.com> References: <20171101045246.16596-1-yselkowi@redhat.com> Compiling with any of the -fstack-protector flags requires the __stack_chk_guard data import (which needs to be initialized) and the __stack_chk_fail{,_local} functions. While GCC's own libssp can provide these, it is better that we provide these ourselves. The header is from NetBSD but the implementation is custom due to NetBSD's implementation being OS-specific. Signed-off-by: Yaakov Selkowitz --- newlib/libc/include/ssp/ssp.h | 93 +++++++++++++++++++++++++++++++++++++++ newlib/libc/ssp/stack_protector.c | 46 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 newlib/libc/include/ssp/ssp.h create mode 100644 newlib/libc/ssp/stack_protector.c -- 2.14.3 diff --git a/newlib/libc/include/ssp/ssp.h b/newlib/libc/include/ssp/ssp.h new file mode 100644 index 000000000..14409c1ec --- /dev/null +++ b/newlib/libc/include/ssp/ssp.h @@ -0,0 +1,93 @@ +/* $NetBSD: ssp.h,v 1.13 2015/09/03 20:43:47 plunky Exp $ */ + +/*- + * Copyright (c) 2006, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _SSP_SSP_H_ +#define _SSP_SSP_H_ + +#include + +#ifndef __RENAME +#define __RENAME(__f) __asm__(__ASMNAME (#__f)) +#endif + +#if !defined(__cplusplus) +# if _FORTIFY_SOURCE > 0 && !defined(__lint__) && \ + (__OPTIMIZE__ > 0 || defined(__clang__)) && __GNUC_PREREQ__(4, 1) +# if _FORTIFY_SOURCE > 1 +# define __SSP_FORTIFY_LEVEL 2 +# else +# define __SSP_FORTIFY_LEVEL 1 +# endif +# else +# define __SSP_FORTIFY_LEVEL 0 +# endif +#else +# define __SSP_FORTIFY_LEVEL 0 +#endif + +/* __ssp_real is used by the implementation in libc */ +#if __SSP_FORTIFY_LEVEL == 0 +#define __ssp_real_(fun) fun +#else +#define __ssp_real_(fun) __ssp_real_ ## fun +#endif +#define __ssp_real(fun) __ssp_real_(fun) + +#define __ssp_inline static __inline __attribute__((__always_inline__)) + +#define __ssp_bos(ptr) __builtin_object_size(ptr, __SSP_FORTIFY_LEVEL > 1) +#define __ssp_bos0(ptr) __builtin_object_size(ptr, 0) + +#define __ssp_check(buf, len, bos) \ + if (bos(buf) != (size_t)-1 && len > bos(buf)) \ + __chk_fail() +#define __ssp_redirect_raw(rtype, fun, symbol, args, call, cond, bos) \ +rtype __ssp_real_(fun) args __RENAME(symbol); \ +__ssp_inline rtype fun args __RENAME(__ssp_protected_ ## fun); \ +__ssp_inline rtype fun args { \ + if (cond) \ + __ssp_check(__buf, __len, bos); \ + return __ssp_real_(fun) call; \ +} + +#define __ssp_redirect(rtype, fun, args, call) \ + __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos) +#define __ssp_redirect0(rtype, fun, args, call) \ + __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0) + +#define __ssp_overlap(a, b, l) \ + (((a) <= (b) && (b) < (a) + (l)) || ((b) <= (a) && (a) < (b) + (l))) + +__BEGIN_DECLS +void __stack_chk_fail(void) __dead2; +void __chk_fail(void) __dead2; +__END_DECLS + +#endif /* _SSP_SSP_H_ */ diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c new file mode 100644 index 000000000..608f79753 --- /dev/null +++ b/newlib/libc/ssp/stack_protector.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include + +uintptr_t __stack_chk_guard = 0; + +void +__attribute__((__constructor__)) +__stack_chk_init (void) +{ + if (__stack_chk_guard != 0) + return; + +#if defined(__CYGWIN__) || defined(__rtems__) + arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); +#else + /* If getentropy is not available, use the "terminator canary". */ + ((unsigned char *)&__stack_chk_guard)[0] = 0; + ((unsigned char *)&__stack_chk_guard)[1] = 0; + ((unsigned char *)&__stack_chk_guard)[2] = '\n'; + ((unsigned char *)&__stack_chk_guard)[3] = 255; +#endif +} + +void +__attribute__((__noreturn__)) +__stack_chk_fail (void) +{ + char msg[] = "*** stack smashing detected ***: terminated\n"; + write (2, msg, strlen (msg)); + raise (SIGABRT); + _exit (127); +} + +#ifdef __ELF__ +void +__attribute__((visibility ("hidden"))) +__stack_chk_fail_local(void) +{ + __stack_chk_fail(); +} +#endif