From patchwork Thu Feb 8 18:46:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 770867 Delivered-To: patch@linaro.org Received: by 2002:adf:9dca:0:b0:33b:4db1:f5b3 with SMTP id q10csp478895wre; Thu, 8 Feb 2024 10:47:41 -0800 (PST) X-Google-Smtp-Source: AGHT+IEpFW/aOmWgmQ7+3qkVrcgXfrnOiAf3WQJdjVEEDc9cSPQ7zShIZxz+ya0ohScnIaYnXMWo X-Received: by 2002:a0c:dd06:0:b0:68c:3df9:c3c9 with SMTP id u6-20020a0cdd06000000b0068c3df9c3c9mr126480qvk.2.1707418060952; Thu, 08 Feb 2024 10:47:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707418060; cv=pass; d=google.com; s=arc-20160816; b=UOx53UG5A4SvO5cs3snoCoTSr2cMz83QXbBtYrYlsx18TCLJNhxb4pm9Be8zESMTa8 aOBuGmNmq3l6w6DZaSbFioiUBe4/rWxlryVSBmQtUtNOeYxDqy1573HP56ZYALRoPmQX F8pETWR4/OQyeF0eN03cveJ3We9e7R9ymfmtcgkT1yeFeyhJlWUibCnygwqri7gE4hgD d2RSmIpuo1Cu7cxWxNme/DFrkTEyP1rQ+pyTtaFNbegZTJyGpkhiZ+w2A/D+w3o+3aYm biQT4JmLjjUsj9xzDLa43p7/XcFhGGkjK7NVpofXuc+5Ir0+uVtE5lHOdAn3SeSA6okp fzXg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=7dpXNmXpYSiA2Bj//iAvQ5vHtm1JSWSGNdHy1Th3iQo=; fh=wz2o7TnDShMlEiBKpeNDLA5mRoLwM4nxNMDXglrDmWM=; b=mpl57H3UL/o26pD1jhx8Zn/NJTviLxqyrFYwt8dNIujbcLUJGItozxDixC1qynLwnd HhGk6cBdt5zTT0dAn4AOfZiNrZgd4UsQG25gCFPLLGACRNTMAh68WZtIb1LvDEqIpq/8 FFGCDZe2EYmNTCTOl9FIBcjO6+FWAESeqM6flKv8wXMd9JkrrzuH2qVFXZTAih1/3ZVJ GwoX9ey1HxyioUYtLsXEKUopo1WLK2ciaxvS4AT7xhkMptHulXBuUpn3qvUYnK8o2JPV XZdRBqaSubCeNZt2caqD9ntmdkSsMwS/StYhfYAeozz9CT/dWyx7k7UwajLHxTUaf+S6 kkdQ==; darn=linaro.org ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Hh1q09oq; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org X-Forwarded-Encrypted: i=2; AJvYcCW39EKuMJ64BYtraOim+gCFIjYCRrMUoA5rrZCcFU8F4NDlvWD6lJJD6lBfUQYUjXkO3X94ZIJJcN8FEWPwROlU Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id u3-20020ad45aa3000000b0068ccd9efffdsi114915qvg.583.2024.02.08.10.47.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Feb 2024 10:47:40 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Hh1q09oq; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9134438582BB for ; Thu, 8 Feb 2024 18:47:40 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oo1-xc2a.google.com (mail-oo1-xc2a.google.com [IPv6:2607:f8b0:4864:20::c2a]) by sourceware.org (Postfix) with ESMTPS id 10A0F3858C35 for ; Thu, 8 Feb 2024 18:46:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 10A0F3858C35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 10A0F3858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::c2a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707417994; cv=none; b=WA8mgm/11wLBIKdRNH0LTMKD3VkwjdWepnGpoFAP47OuQ2QhfqFF8ZUU/9sY9C+OOFM422+5oTvFgK1kLZ2galj6F0RLKv1ih+wCCLxZVIl05hGlCziV5Qij63qG7noSWdMmogw1rn5us59+tDCZhP0SW9We0867YOFTRHsDCHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707417994; c=relaxed/simple; bh=OIKpXEvFULD2NWx8DJ7HCu55dEd3Vlj7+ZWGZqXC+Jw=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=ILeLOenFyDtu6k7QW7y4UtEyK0un0E8lb1nMQfrcssR4xXLFdVCIEOvFU/6JpqBHGgJzC/79DKt1pVQdQqIsbtsAKQxXp8pNMPUBS145vD7qiw0l7KesoI6bYBFZZJ0/COatc64fCPzZj/YM5s3NmEWT9nviSKsKwf8lmRPdWqA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oo1-xc2a.google.com with SMTP id 006d021491bc7-5986d902ae6so74551eaf.3 for ; Thu, 08 Feb 2024 10:46:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1707417989; x=1708022789; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7dpXNmXpYSiA2Bj//iAvQ5vHtm1JSWSGNdHy1Th3iQo=; b=Hh1q09oqlKQz/1R6dMkk4LgiK+vFGnKsde4IPRMgF5/qmjAKbIU+DE0/2nK/7jXFPn vC98p7w1ze5QnZjTU7DfPezAgmLWePt99WKbesrgAFvflrYmWaOJMImFW1hBzxbI2PPX faeWEkCWjcBPITsjQXlzerKhaCh515XzeH37qk7CETGFHFv0YXuVSi+0bUtC7UYcZgcn +iE0tI82IG0+xe01pY/4qBMpPp6jEx2yVqEPYtCQ4EsT/aWIApX11kW1KXFLluvDqjOr CHXVioadrGc/bDT5xko+aRHGS6ny/Vd0S6YsINS7TRkYECo98k+ME6xMWjeQqxfwV2kg 1lNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707417989; x=1708022789; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7dpXNmXpYSiA2Bj//iAvQ5vHtm1JSWSGNdHy1Th3iQo=; b=uNv8wWKImE2SHBE7ZZ24qU9s2nK6Gbg3oUkAeDqVeDiX9jNNiTct/5pCTAdUh9V2wD g++J+PnKfQjNU0U4elkIYy72JkKLuU/SAYcKpY2aakJ6Aa+sn2AW0a7Bs7DnKqYRzIpT PD4nFQ2NB3OiHtK9jPPwP0MJ4F4LymRMnGWt/gQNhubNk6xwyXrj7BfxV8bYf492h/ry sQ3F+0lAZrgfbagaPq36/ZT/EMDBm/KS4s6fiV54fYRYgGgCouU4g+afHYS7OsJwskjp eiI/zWwpD5HMhM+c2aNYcVef6/+BjN9M9kvNEjKJBSZnWoTijZp5uT4RCCTDO4bAJt44 cAQQ== X-Gm-Message-State: AOJu0YxoFS85OgKU3tLWHNKZXyNj3F1BCi/RsrsZzgddRZJ0maoy6K33 jMm7vBGdsOF0+CwSePq61X5R3IQJ+aJNeQezKWNwYS5VuuTNxJoYWpom5G5YzA64zDeXHb2CgnF h X-Received: by 2002:a05:6359:4588:b0:178:94bc:731e with SMTP id no8-20020a056359458800b0017894bc731emr13774rwb.8.1707417989265; Thu, 08 Feb 2024 10:46:29 -0800 (PST) Received: from mandiga.. ([2804:1b3:a7c0:378:6793:1dc3:1346:d6d6]) by smtp.gmail.com with ESMTPSA id n26-20020a638f1a000000b005d7994a08dcsm156408pgd.36.2024.02.08.10.46.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Feb 2024 10:46:28 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Siddhesh Poyarekar Subject: [PATCH v3 01/10] cdefs.h: Add clang fortify directives Date: Thu, 8 Feb 2024 15:46:13 -0300 Message-Id: <20240208184622.332678-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240208184622.332678-1-adhemerval.zanella@linaro.org> References: <20240208184622.332678-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+patch=linaro.org@sourceware.org For instance, the read wrapper is currently expanded as: extern __inline __attribute__((__always_inline__)) __attribute__((__artificial__)) __attribute__((__warn_unused_result__)) ssize_t read (int __fd, void *__buf, size_t __nbytes) { return __glibc_safe_or_unknown_len (__nbytes, sizeof (char), __glibc_objsize0 (__buf)) ? __read_alias (__fd, __buf, __nbytes) : __glibc_unsafe_len (__nbytes, sizeof (char), __glibc_objsize0 (__buf)) ? __read_chk_warn (__fd, __buf, __nbytes, __builtin_object_size (__buf, 0)) : __read_chk (__fd, __buf, __nbytes, __builtin_object_size (__buf, 0)); } The wrapper relies on __builtin_object_size call lowers to a constant at compile-time and many other operations in the wrapper depends on having a single, known value for parameters. Because this is impossible to have for function parameters, the wrapper depends heavily on inlining to work and While this is an entirely viable approach on GCC, it is not fully reliable on clang. This is because by the time llvm gets to inlining and optimizing, there is a minimal reliable source and type-level information available (more information on a more deep explanation on how to fortify wrapper works on clang [1]). To allow the wrapper to work reliably and with the same functionality as with GCC, clang requires a different approach: * __attribute__((diagnose_if(c, “str”, “warning”))) which is a function level attribute; if the compiler can determine that 'c' is true at compile-time, it will emit a warning with the text 'str1'. If it would be better to emit an error, the wrapper can use "error" instead of "warning". * __attribute__((overloadable)) which is also a function-level attribute; and it allows C++-style overloading to occur on C functions. * __attribute__((pass_object_size(n))) which is a parameter-level attribute; and it makes the compiler evaluate __builtin_object_size(param, n) at each call site of the function that has the parameter, and passes it in as a hidden parameter. This attribute has two side-effects that are key to how FORTIFY works: 1. It can overload solely on pass_object_size (e.g. there are two overloads of foo in void foo(char * __attribute__((pass_object_size(0))) c); void foo(char *); (The one with pass_object_size attribute has precende over the default one). 2. A function with at least one pass_object_size parameter can never have its address taken (and overload resolution respects this). Thus the read wrapper can be implemented as follows, without hindering any fortify coverage compile and runtime: extern __inline __attribute__((__always_inline__)) __attribute__((__artificial__)) __attribute__((__overloadable__)) __attribute__((__warn_unused_result__)) ssize_t read (int __fd, void *const __attribute__((pass_object_size (0))) __buf, size_t __nbytes) __attribute__((__diagnose_if__ ((((__builtin_object_size (__buf, 0)) != -1ULL && (__nbytes) > (__builtin_object_size (__buf, 0)) / (1))), "read called with bigger length than size of the destination buffer", "warning"))) { return (__builtin_object_size (__buf, 0) == (size_t) -1) ? __read_alias (__fd, __buf, __nbytes) : __read_chk (__fd, __buf, __nbytes, __builtin_object_size (__buf, 0)); } To avoid changing the current semantic for GCC, a set of macros is defined to enable the clang required attributes, along with some changes on internal macros to avoid the need to issue the symbol_chk symbols (which are done through the __diagnose_if__ attribute for clang). The read wrapper is simplified as: __fortify_function __attribute_overloadable__ __wur ssize_t read (int __fd, __fortify_clang_overload_arg0 (void *, ,__buf), size_t __nbytes) __fortify_clang_warning_only_if_bos0_lt (__nbytes, __buf, "read called with bigger length than " "size of the destination buffer") { return __glibc_fortify (read, __nbytes, sizeof (char), __glibc_objsize0 (__buf), __fd, __buf, __nbytes); } There is no expected semantic or code change when using GCC. Also, clang does not support __va_arg_pack, so variadic functions are expanded to call va_arg implementations. The error function must not have bodies (address takes are expanded to nonfortified calls), and with the __fortify_function compiler might still create a body with the C++ mangling name (due to the overload attribute). In this case, the function is defined with __fortify_function_error_function macro instead. [1] https://docs.google.com/document/d/1DFfZDICTbL7RqS74wJVIJ-YnjQOj1SaoqfhbgddFYSM/edit Checked on aarch64, armhf, x86_64, and i686. Reviewed-by: Carlos O'Donell Tested-by: Carlos O'Donell --- misc/sys/cdefs.h | 151 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 520231dbea..62507044c8 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -145,6 +145,14 @@ #endif +/* The overloadable attribute was added on clang 2.6. */ +#if defined __clang_major__ \ + && (__clang_major__ + (__clang_minor__ >= 6) > 2) +# define __attribute_overloadable__ __attribute__((__overloadable__)) +#else +# define __attribute_overloadable__ +#endif + /* Fortify support. */ #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) #define __bos0(ptr) __builtin_object_size (ptr, 0) @@ -187,27 +195,166 @@ __s, __osz)) \ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) +/* To correctly instrument the fortify wrapper clang requires the + pass_object_size attribute, and the attribute has the restriction that the + argument needs to be 'const'. Furthermore, to make it usable with C + interfaces, clang provides the overload attribute, which provides a C++ + like function overload support. The overloaded fortify wrapper with the + pass_object_size attribute has precedence over the default symbol. + + Also, clang does not support __va_arg_pack, so variadic functions are + expanded to issue va_arg implementations. The error function must not have + bodies (address takes are expanded to nonfortified calls), and with + __fortify_function compiler might still create a body with the C++ + mangling name (due to the overload attribute). In this case, the function + is defined with __fortify_function_error_function macro instead. + + The argument size check is also done with a clang-only attribute, + __attribute__ ((__diagnose_if__ (...))), different than gcc which calls + symbol_chk_warn alias with uses __warnattr attribute. + + The pass_object_size was added on clang 4.0, __diagnose_if__ on 5.0, + and pass_dynamic_object_size on 9.0. */ +#if defined __clang_major__ && __clang_major__ >= 5 +# define __fortify_use_clang 1 + +# define __fortify_function_error_function static __attribute__((__unused__)) + +# define __fortify_clang_pass_object_size_n(n) \ + __attribute__ ((__pass_object_size__ (n))) +# define __fortify_clang_pass_object_size0 \ + __fortify_clang_pass_object_size_n (0) +# define __fortify_clang_pass_object_size \ + __fortify_clang_pass_object_size_n (__USE_FORTIFY_LEVEL > 1) + +# if __clang_major__ >= 9 +# define __fortify_clang_pass_dynamic_object_size_n(n) \ + __attribute__ ((__pass_dynamic_object_size__ (n))) +# define __fortify_clang_pass_dynamic_object_size0 \ + __fortify_clang_pass_dynamic_object_size_n (0) +# define __fortify_clang_pass_dynamic_object_size \ + __fortify_clang_pass_dynamic_object_size_n (1) +# else +# define __fortify_clang_pass_dynamic_object_size_n(n) +# define __fortify_clang_pass_dynamic_object_size0 +# define __fortify_clang_pass_dynamic_object_size +# endif + +# define __fortify_clang_bos_static_lt_impl(bos_val, n, s) \ + ((bos_val) != -1ULL && (n) > (bos_val) / (s)) +# define __fortify_clang_bos_static_lt2(__n, __e, __s) \ + __fortify_clang_bos_static_lt_impl (__bos (__e), __n, __s) +# define __fortify_clang_bos_static_lt(__n, __e) \ + __fortify_clang_bos_static_lt2 (__n, __e, 1) +# define __fortify_clang_bos0_static_lt2(__n, __e, __s) \ + __fortify_clang_bos_static_lt_impl (__bos0 (__e), __n, __s) +# define __fortify_clang_bos0_static_lt(__n, __e) \ + __fortify_clang_bos0_static_lt2 (__n, __e, 1) + +# define __fortify_clang_bosn_args(bos_fn, n, buf, div, complaint) \ + (__fortify_clang_bos_static_lt_impl (bos_fn (buf), n, div)), (complaint), \ + "warning" + +# define __fortify_clang_warning(__c, __msg) \ + __attribute__ ((__diagnose_if__ ((__c), (__msg), "warning"))) +# define __fortify_clang_warning_only_if_bos0_lt(n, buf, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos0, n, buf, 1, complaint)))) +# define __fortify_clang_warning_only_if_bos0_lt2(n, buf, div, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos0, n, buf, div, complaint)))) +# define __fortify_clang_warning_only_if_bos_lt(n, buf, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos, n, buf, 1, complaint)))) +# define __fortify_clang_warning_only_if_bos_lt2(n, buf, div, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos, n, buf, div, complaint)))) + +# if __USE_FORTIFY_LEVEL == 3 +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_dynamic_object_size __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_dynamic_object_size0 __name +# else +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_object_size __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_object_size0 __name +# endif + +# define __fortify_clang_mul_may_overflow(size, n) \ + ((size | n) >= (((size_t)1) << (8 * sizeof (size_t) / 2))) + +# define __fortify_clang_size_too_small(__bos, __dest, __len) \ + (__bos (__dest) != (size_t) -1 && __bos (__dest) < __len) +# define __fortify_clang_warn_if_src_too_large(__dest, __src) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \ + __dest, \ + __builtin_strlen (__src) + 1), \ + "destination buffer will always be overflown by source") +# define __fortify_clang_warn_if_dest_too_small(__dest, __len) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \ + __dest, \ + __len), \ + "function called with bigger length than the destination buffer") +# define __fortify_clang_warn_if_dest_too_small0(__dest, __len) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize0, \ + __dest, \ + __len), \ + "function called with bigger length than the destination buffer") +#else +# define __fortify_use_clang 0 +# define __fortify_clang_warning(__c, __msg) +# define __fortify_clang_warning_only_if_bos0_lt(__n, __buf, __complaint) +# define __fortify_clang_warning_only_if_bos0_lt2(__n, __buf, __div, complaint) +# define __fortify_clang_warning_only_if_bos_lt(__n, __buf, __complaint) +# define __fortify_clang_warning_only_if_bos_lt2(__n, __buf, div, __complaint) +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __fortify_clang_overload_arg (__type, __attr, __name) +# define __fortify_clang_warn_if_src_too_large(__dest, __src) +# define __fortify_clang_warn_if_dest_too_small(__dest, __len) +# define __fortify_clang_warn_if_dest_too_small0(__dest, __len) +#endif + + /* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be declared. */ -#define __glibc_fortify(f, __l, __s, __osz, ...) \ +#if !__fortify_use_clang +# define __glibc_fortify(f, __l, __s, __osz, ...) \ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ : __ ## f ## _chk (__VA_ARGS__, __osz))) +#else +# define __glibc_fortify(f, __l, __s, __osz, ...) \ + (__osz == (__SIZE_TYPE__) -1) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : __ ## f ## _chk (__VA_ARGS__, __osz) +#endif /* Fortify function f, where object size argument passed to f is the number of elements and not total size. */ -#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ +#if !__fortify_use_clang +# define __glibc_fortify_n(f, __l, __s, __osz, ...) \ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +# else +# define __glibc_fortify_n(f, __l, __s, __osz, ...) \ + (__osz == (__SIZE_TYPE__) -1) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)) #endif +#endif /* __USE_FORTIFY_LEVEL > 0 */ + #if __GNUC_PREREQ (4,3) # define __warnattr(msg) __attribute__((__warning__ (msg))) # define __errordecl(name, msg) \