X-Recipient: archive-cygwin AT delorie DOT 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:to:from:subject:message-id:date:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=G3j 7ixHBgbR9GlZBWxiSoRXxwVksKVDHY0ewPY3Nk+XObI5O7etD9N93PJJ0z9p2t4L EzuNc6LsRDp4G4qycyKwx6vUZuPeN8gefjYGPpUkmNsntTJh1yFQFvzELTFSGd6N u0aBXCbMbA23WIFNBXg0E1DywjAsJjVS443ogWdk= 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:to:from:subject:message-id:date:mime-version :content-type:content-transfer-encoding; s=default; bh=I2JDF0gj5 kz+YU3OWMWWtezi/3w=; b=ByhgIKJk2Bl4S2SZumfONqXJu6IbR7ikXnhx0Tcvv 8e9/pNge5SnFhnNDegPlbLDOBf4Epvra07g8G2ACBzKBx6sZKjgZy96orINyFdAy pVNXY6ftJIB5A2cMcJb1D6nVZlRLc//xreV+7z9kk/8DK5SXYOrhNqYF2wn+UKgs kI= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=H*M:online, H*MI:online, H*UA:2.51 X-HELO: mailout10.t-online.de To: cygwin AT cygwin DOT com From: Christian Franke Subject: _FORTIFY_SOURCE has no effect for C++ due to usage of #define Message-ID: <2525db3d-f9e1-79d1-94be-4a0c11d2a84c@t-online.de> Date: Tue, 6 Mar 2018 13:04:50 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0 SeaMonkey/2.51 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Cygport now sets _FORTIFY_SOURCE=2 for C and C++ but this has no effect for C++. In __SSP_FORTIFY_LEVEL is always set to 0 if __cplusplus is defined. This is needed because ... use #defines to replace the functions. Testcase: $ cat copy.c #include char sbuf[42], *dbuf; void to_sbuf(const char *p) { strcpy(sbuf, p); } void to_dbuf(const char *p) { strcpy(dbuf, p); } Examine preprocessed code: $ gcc -D_FORTIFY_SOURCE=2 -O2 -E copy.c > copy2.c $ vim copy2.c # Remove unnecessary code && pretty-print $ cat copy2.c typedef unsigned int size_t; char *__strcpy_chk(char *, const char *, size_t); extern __inline__ __attribute__((__always_inline__, __gnu_inline__)) char * __strcpy_ichk(char * restrict dst, const char * restrict src) { return __builtin___strcpy_chk(dst, src, __builtin_object_size(dst, 0)); } char sbuf[42], *dbuf; void to_sbuf(const char *p) { ((__builtin_object_size(sbuf, 0) != (size_t)-1) ? __builtin___strcpy_chk(sbuf, p, __builtin_object_size(sbuf, 0)) : __strcpy_ichk(sbuf, p)); } void to_dbuf(const char *p) { ((__builtin_object_size(dbuf, 0) != (size_t)-1) ? __builtin___strcpy_chk(dbuf, p, __builtin_object_size(dbuf, 0)) : __strcpy_ichk(dbuf, p)); } Why are these (a ? b : c) expanded from the "#define strcpy" needed? Both branches lead to the same __builtin___strcpy_chk() call. Is this possibly needed for (very) old compiler versions with weaker optimization? According to "gcc -O2 -S" outputs, the generated code is identical for this source: $ cat copy3.c typedef unsigned int size_t; char *strcpy (char *restrict, const char *restrict); char *__strcpy_chk(char *, const char *, size_t); char sbuf[42], *dbuf; void to_sbuf(const char *p) { __strcpy_chk(sbuf, p, 42); } void to_dbuf(const char *p) { strcpy(dbuf, p); } The same code is generated if strcpy() is replaced itself without a "#define strcpy": $ cat copy4.c typedef unsigned int size_t; char *strcpy (char *restrict, const char *restrict); // #if __SSP_FORTIFY_LEVEL > 0 extern __inline__ __attribute__((__always_inline__, __gnu_inline__)) char * strcpy(char * restrict dst, const char * restrict src) { return __builtin___strcpy_chk(dst, src, __builtin_object_size(dst, 0)); } // #endif char sbuf[42], *dbuf; void to_sbuf(const char *p) { strcpy(sbuf, p); // changed to __strcpy_chk(sbuf, p, 42); } void to_dbuf(const char *p) { strcpy(dbuf, p); // unchanged } This variant would be also compatible with C++. Same results with CLang(++). Christian PS: There is an outdated "#define __restrict" section in which checks for GCC version 2.95 only. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple