Re: Initial implementation of _FORTIFY_SOURCE

From: Alexander Leidinger <Alexander_at_Leidinger.net>
Date: Wed, 15 May 2024 06:05:59 UTC
Am 2024-05-15 01:15, schrieb Kyle Evans:
> On 5/14/24 11:34, Kyle Evans wrote:
>> On 5/14/24 07:47, Alexander Leidinger wrote:
>>> Am 2024-05-13 19:47, schrieb Kyle Evans:
>>>> Hi,
>>>> 
>>>> As of 9bfd3b407 ("Add a build knob for _FORTIFY_SOURCE"), I've 
>>>> imported an initial version of FORTIFY_SOURCE from FreeBSD. 
>>>> FORTIFY_SOURCE is an improvement over classical SSP, doing 
>>>> compiler-aided checking of stack object sizes to detect more 
>>>> fine-grained stack overflow without relying on the randomized stack 
>>>> canary just past the stack frame.
>>> 
>>> This breaks some port builds.
>>> 
>>> Example libfido2 (which is a dependency in the build of e.g. mysql):
>>> ---snip---
>>> [  0% 4/1032] /usr/local/libexec/ccache/cc -DHAVE_ARC4RANDOM_BUF 
>>> -DHAVE_ASPRINTF -DHAVE_CLOCK_GETTIME -DHAVE_DEV_URANDOM 
>>> -DHAVE_ENDIAN_H -DHAVE_ERR_H -DHAVE_EXPLICIT_BZERO -DHAVE_GETLINE 
>>> -DHAVE_GETOPT -DHAVE_GETPAGESIZE -DHAVE_GETRANDOM -DHAVE_OPENSSLV_H 
>>> -DHAVE_READPASSPHRASE -DHAVE_SIGNAL_H -DHAVE_STRLCAT -DHAVE_STRLCPY 
>>> -DHAVE_STRSEP -DHAVE_SYSCONF -DHAVE_SYS_RANDOM_H -DHAVE_TIMESPECSUB 
>>> -DHAVE_TIMINGSAFE_BCMP -DHAVE_UNISTD_H 
>>> -DOPENSSL_API_COMPAT=0x10100000L -DTLS=__thread -D_FIDO_INTERNAL 
>>> -D_FIDO_MAJOR=1 -D_FIDO_MINOR=14 -D_FIDO_PATCH=0 
>>> -I/wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src 
>>> -I/usr/local/include -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE 
>>> -D__BSD_VISIBLE=1 -std=c99 -O2 -pipe -O2 -pipe -mtune=native 
>>> -fvectorize -O2 -pipe -mtune=native -fvectorize -march=native 
>>> -DOPENSSL_API_COMPAT=0x10100000L -fstack-protector-strong 
>>> -fno-strict-aliasing -O2 -pipe -O2 -pipe -mtune=native -fvectorize 
>>> -O2 -pipe -mtune=native -fvectorize -march=native 
>>> -DOPENSSL_API_COMPAT=0x10100000L -fstack-protector-strong 
>>> -fno-strict-aliasing  -DNDEBUG -D_FORTIFY_SOURCE=2 -fPIC -Wall 
>>> -Wextra -Werror -Wshadow -Wcast-qual -Wwrite-strings 
>>> -Wmissing-prototypes -Wbad-function-cast -Wimplicit-fallthrough 
>>> -pedantic -pedantic-errors -Wshorten-64-to-32 -fstack-protector-all 
>>> -Wconversion -Wsign-conversion -Wframe-larger-than=2047 -MD -MT 
>>> src/CMakeFiles/fido2.dir/aes256.c.o -MF 
>>> src/CMakeFiles/fido2.dir/aes256.c.o.d -o 
>>> src/CMakeFiles/fido2.dir/aes256.c.o -c 
>>> /wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src/aes256.c
>>> FAILED: src/CMakeFiles/fido2.dir/aes256.c.o
>>> /usr/local/libexec/ccache/cc -DHAVE_ARC4RANDOM_BUF -DHAVE_ASPRINTF 
>>> -DHAVE_CLOCK_GETTIME -DHAVE_DEV_URANDOM -DHAVE_ENDIAN_H -DHAVE_ERR_H 
>>> -DHAVE_EXPLICIT_BZERO -DHAVE_GETLINE -DHAVE_GETOPT -DHAVE_GETPAGESIZE 
>>> -DHAVE_GETRANDOM -DHAVE_OPENSSLV_H -DHAVE_READPASSPHRASE 
>>> -DHAVE_SIGNAL_H -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRSEP 
>>> -DHAVE_SYSCONF -DHAVE_SYS_RANDOM_H -DHAVE_TIMESPECSUB 
>>> -DHAVE_TIMINGSAFE_BCMP -DHAVE_UNISTD_H 
>>> -DOPENSSL_API_COMPAT=0x10100000L -DTLS=__thread -D_FIDO_INTERNAL 
>>> -D_FIDO_MAJOR=1 -D_FIDO_MINOR=14 -D_FIDO_PATCH=0 
>>> -I/wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src 
>>> -I/usr/local/include -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE 
>>> -D__BSD_VISIBLE=1 -std=c99 -O2 -pipe -O2 -pipe -mtune=native 
>>> -fvectorize -O2 -pipe -mtune=native -fvectorize -march=native 
>>> -DOPENSSL_API_COMPAT=0x10100000L -fstack-protector-strong 
>>> -fno-strict-aliasing -O2 -pipe -O2 -pipe -mtune=native -fvectorize 
>>> -O2 -pipe -mtune=native -fvectorize -march=native 
>>> -DOPENSSL_API_COMPAT=0x10100000L -fstack-protector-strong 
>>> -fno-strict-aliasing  -DNDEBUG -D_FORTIFY_SOURCE=2 -fPIC -Wall 
>>> -Wextra -Werror -Wshadow -Wcast-qual -Wwrite-strings 
>>> -Wmissing-prototypes -Wbad-function-cast -Wimplicit-fallthrough 
>>> -pedantic -pedantic-errors -Wshorten-64-to-32 -fstack-protector-all 
>>> -Wconversion -Wsign-conversion -Wframe-larger-than=2047 -MD -MT 
>>> src/CMakeFiles/fido2.dir/aes256.c.o -MF 
>>> src/CMakeFiles/fido2.dir/aes256.c.o.d -o 
>>> src/CMakeFiles/fido2.dir/aes256.c.o -c 
>>> /wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src/aes256.c
>>> /wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src/aes256.c:18:2: 
>>> error: use of GNU statement expression extension from macro expansion 
>>> [-Werror,-Wgnu-statement-expression-from-macro-expansion]
>>>     18 |         memset(out, 0, sizeof(*out));
>>>        |         ^
>>> /usr/include/ssp/string.h:120:5: note: expanded from macro 'memset'
>>>    120 |     __ssp_bos_check3_typed(memset, void *, dst, int, val, 
>>> len)
>>>        |     ^
>>> /usr/include/ssp/string.h:65:5: note: expanded from macro 
>>> '__ssp_bos_check3_typed'
>>>     65 |     __ssp_bos_check3_typed_var(fun, dsttype, 
>>> __ssp_var(dstv), dst,      \
>>>        |     ^
>>> /usr/include/ssp/string.h:54:24: note: expanded from macro 
>>> '__ssp_bos_check3_typed_var'
>>>     54 |     src, lenvar, len) ({                                \
>>>        |                        ^
>>> /wrkdirs/usr/ports/security/libfido2/work/libfido2-1.14.0/src/aes256.c:60:2: 
>>> error: use of GNU statement expression extension from macro expansion 
>>> [-Werror,-Wgnu-statement-expression-from-macro-expansion]
>>>     60 |         memset(&iv, 0, sizeof(iv));
>>>        |         ^
>>> /usr/include/ssp/string.h:120:5: note: expanded from macro 'memset'
>>>    120 |     __ssp_bos_check3_typed(memset, void *, dst, int, val, 
>>> len)
>>>        |     ^
>>> /usr/include/ssp/string.h:65:5: note: expanded from macro 
>>> '__ssp_bos_check3_typed'
>>>     65 |     __ssp_bos_check3_typed_var(fun, dsttype, 
>>> __ssp_var(dstv), dst,      \
>>>        |     ^
>>> /usr/include/ssp/string.h:54:24: note: expanded from macro 
>>> '__ssp_bos_check3_typed_var'
>>>     54 |     src, lenvar, len) ({                                \
>>>        |                        ^
>>> ---snip---
>>> 
>>> I also have a failed archivers/libdeflate, devel/highway, www/node20, 
>>> and lang/rust, but those complain about something which could also be 
>>> attributed to some kind of interaction between my use of -fvectorize 
>>> and the new fortify stuff. Example with libdeflate (the libdeflate 
>>> update in ports is from March, and I had it compiled with -fvectorize 
>>> successfully before the fortify stuff came in):
>>> ---snip---
>>> In file included from 
>>> /wrkdirs/usr/ports/archivers/libdeflate/work/libdeflate-1.20/lib/x86/adler32_impl.h:93:
>>> /wrkdirs/usr/ports/archivers/libdeflate/work/libdeflate-1.20/lib/x86/adler32_template.h:197:21: 
>>> error: always_inline function '_mm512_set1_epi8' requires target 
>>> feature 'evex512', but would be inlined into function 
>>> 'adler32_x86_avx512_vl512_vnni' that is compiled without support for 
>>> 'evex512'
>>>    197 |         const vec_t ones = VSET1_8(1);
>>>        |                            ^
>>> ---snip---
>>> Note, my CPUs don't support evex512 or avx512 at all, the compile 
>>> flags haven't changed, this version of the port is installed in 
>>> multiple jails (since March 28), so there is a change in behavior 
>>> since then. It may or may not be due to the fortify stuff.
>>> 
>>> I will test without -fvectorize later, poudriere is still building 
>>> ports, and I want to see if some other ports fail. Those 5 failed 
>>> port builds result in 160 skipped ports already (out of the >600 
>>> which this run wants to build).
>>> 
>>> Maybe you want to backout and request an exp-build to not get swamped 
>>> with failure reports from various people...
>>> 
>> 
>> There's really not that much that can go wrong here; I looked at 
>> enabling the warning in question in base to try and avoid future 
>> landmines, but that results in an absolute dumpster fire so I guess we 
>> won't do that.
>> 
>> Can you try this patch, please? https://termbin.com/jdtv -- it's the 
>> apparently proper way to avoid the warning.
>> 
> 
> I've confirmed that this patch fixes libfido2, will commit shortly.  
> The other failures you noted are indeed not related, FORTIFY_SOURCE has 
> no bearing on any of these things.

Your stdio.h does look different to my tree (it's from May 13, with 
manual removal of the ObsoleteFiles.inc stuff)... I did this manually 
now and give it a try in poudriere:
---snip---
#define sprintf(str, ...) __extension__ ({      \
     char *_ssp_str = (str);     \
     __builtin___sprintf_chk(_ssp_str, 0, __ssp_bos(_ssp_str),           
\
         __VA_ARGS__); \
})

#define vsprintf(str, fmt, ap) __extension__ ({ \
     char *_ssp_str = (str);             \
     __builtin___vsprintf_chk(_ssp_str, 0, __ssp_bos(_ssp_str), fmt,     
\
         ap);                            \
})

#define snprintf(str, len, ...) __extension__ ({        \
     char *_ssp_str = (str);             \
     __builtin___snprintf_chk(_ssp_str, len, 0, __ssp_bos(_ssp_str),     
\
         __VA_ARGS__);                   \
})

#define vsnprintf(str, len, fmt, ap) __extension__ ({   \
     char *_ssp_str = (str);             \
     __builtin___vsnprintf_chk(_ssp_str, len, 0, __ssp_bos(_ssp_str),    
\
         fmt, ap);                       \
})

#define gets(str) __extension__ ({                      \
    char *_ssp_str = (str);              \
     __gets_chk(_ssp_str, __ssp_bos(_ssp_str));  \
})

#define fgets(str, len, fp) __extension__ ({            \
     char *_ssp_str = (str);             \
     __fgets_chk(_ssp_str, len, __ssp_bos(_ssp_str), fp);        \
})
---snip---

Bye,
Alexander.

-- 
http://www.Leidinger.net Alexander@Leidinger.net: PGP 0x8F31830F9F2772BF
http://www.FreeBSD.org    netchild@FreeBSD.org  : PGP 0x8F31830F9F2772BF