diff --git a/compiler-rt/cmake/Modules/CompilerRTCompile.cmake b/compiler-rt/cmake/Modules/CompilerRTCompile.cmake --- a/compiler-rt/cmake/Modules/CompilerRTCompile.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTCompile.cmake @@ -24,6 +24,26 @@ set(${out_flags} "${clang_flags}" PARENT_SCOPE) endfunction() +# Add warnings to catch potential errors that can lead to security +# vulnerabilities. +function(add_security_warnings out_flags macosx_sdk_version) + set(flags "${${out_flags}}" -Werror=builtin-memcpy-chk-size -Werror=format-security + -Werror=array-bounds -Werror=uninitialized -Werror=array-bounds-pointer-arithmetic + -Werror=shadow -Werror=empty-body -Werror=sizeof-pointer-memaccess + -Werror=return-stack-address -Werror=sizeof-array-decay -Werror=sizeof-array-argument + -Werror=memset-transposed-args -Werror=format-insufficient-args) + + # Add -Wformat-nonliteral only if we can avoid adding the defintion of + # eprintf. On Apple platforms, eprintf is needed only on macosx and only if + # its version is older than 10.7. + if ("${macosx_sdk_version}" VERSION_GREATER_EQUAL 10.7 OR + "${macosx_sdk_version}" EQUAL 0) + set(flags "${flags}" -Werror=format-nonliteral -DDONT_DEFINE_EPRINTF) + endif() + + set(${out_flags} "${flags}" PARENT_SCOPE) +endfunction() + # Compile a sanitizer test with a freshly built clang # for a given architecture, adding the result to the object list. # - obj_list: output list of objects, populated by path diff --git a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake --- a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake @@ -413,6 +413,12 @@ ../profile/InstrProfilingInternal.c ../profile/InstrProfilingVersionVar.c) foreach (os ${ARGN}) + set(macosx_sdk_version 0) + if ("${os}" STREQUAL "osx") + find_darwin_sdk_version(macosx_sdk_version "macosx") + endif() + add_security_warnings(CFLAGS ${macosx_sdk_version}) + list_intersect(DARWIN_BUILTIN_ARCHS DARWIN_${os}_BUILTIN_ARCHS BUILTIN_SUPPORTED_ARCH) if((arm64 IN_LIST DARWIN_BUILTIN_ARCHS OR arm64e IN_LIST DARWIN_BUILTIN_ARCHS) AND NOT TARGET lse_builtin_symlinks) diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -129,10 +129,10 @@ INSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version()) INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) /* FIXME: A more accurate name is NumData */ -INSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSize) +INSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSizeInitVal) INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesBeforeCounters, PaddingBytesBeforeCounters) /* FIXME: A more accurate name is NumCounters */ -INSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSize) +INSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSizeInitVal) INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterCounters, PaddingBytesAfterCounters) INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -699,6 +699,7 @@ darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS}) else () set(BUILTIN_CFLAGS "") + add_security_warnings(BUILTIN_CFLAGS -1) if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG) append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full BUILTIN_CFLAGS) diff --git a/compiler-rt/lib/builtins/eprintf.c b/compiler-rt/lib/builtins/eprintf.c --- a/compiler-rt/lib/builtins/eprintf.c +++ b/compiler-rt/lib/builtins/eprintf.c @@ -15,6 +15,7 @@ // // It should never be exported from a dylib, so it is marked // visibility hidden. +#ifndef DONT_DEFINE_EPRINTF #ifndef _WIN32 __attribute__((visibility("hidden"))) #endif @@ -25,3 +26,4 @@ fflush(stderr); compilerrt_abort(); } +#endif diff --git a/compiler-rt/lib/profile/InstrProfiling.c b/compiler-rt/lib/profile/InstrProfiling.c --- a/compiler-rt/lib/profile/InstrProfiling.c +++ b/compiler-rt/lib/profile/InstrProfiling.c @@ -64,11 +64,11 @@ CurrentVSiteCount += DI->NumValueSites[VKI]; for (i = 0; i < CurrentVSiteCount; ++i) { - ValueProfNode *CurrentVNode = ValueCounters[i]; + ValueProfNode *CurrVNode = ValueCounters[i]; - while (CurrentVNode) { - CurrentVNode->Count = 0; - CurrentVNode = CurrentVNode->Next; + while (CurrVNode) { + CurrVNode->Count = 0; + CurrVNode = CurrVNode->Next; } } } diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c --- a/compiler-rt/lib/profile/InstrProfilingWriter.c +++ b/compiler-rt/lib/profile/InstrProfilingWriter.c @@ -291,8 +291,8 @@ // TODO: Unfortunately the header's fields are named DataSize and // CountersSize when they should be named NumData and NumCounters, // respectively. - const uint64_t CountersSize = NumCounters; - const uint64_t DataSize = NumData; + const uint64_t CountersSizeInitVal = NumCounters; + const uint64_t DataSizeInitVal = NumData; /* Initialize header structure. */ #define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init; #include "profile/InstrProfData.inc"