delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2018/03/06/07:05:17

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: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
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 <Christian DOT Franke AT t-online DOT de>
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
X-IsSubscribed: yes

Cygport now sets _FORTIFY_SOURCE=2 for C and C++ but this has no effect 
for C++. In <sys/features.h> __SSP_FORTIFY_LEVEL is always set to 0 if 
__cplusplus is defined. This is needed because <ssp/string.h> ... use 
#defines to replace the functions.

Testcase:

$ cat copy.c
#include <string.h>

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 <sys/cdefs.h> 
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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019