[libc] move __stack_chk_fail to src/ from startup/ (#75863)

__stack_chk_fail should be provided by libc.a, not startup files.

Add __stack_chk_fail to existing linux and arm entrypoints. On Windows
(when
not targeting MinGW), it seems that the corresponding function
identifier is
__security_check_cookie, so no entrypoint is added for Windows.
Baremetal
targets also ought to be compileable with `-fstack-protector*`

There is no common header for this prototype, since calls to
__stack_chk_fail
are meant to be inserted by the compiler upon function return when
compiled
`-fstack-protector*`.
This commit is contained in:
Nick Desaulniers 2023-12-19 11:05:12 -08:00 committed by GitHub
parent 0768253c20
commit 315a5cce89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 131 additions and 12 deletions

View File

@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
# compiler entrypoints (no corresponding header)
libc.src.compiler.__stack_chk_fail
# errno.h entrypoints
libc.src.errno.errno
@ -69,7 +72,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.snprintf
libc.src.stdio.vsprintf
libc.src.stdio.vsnprintf
# stdlib.h entrypoints
libc.src.stdlib.abs
libc.src.stdlib.atoi

View File

@ -17,6 +17,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
# compiler entrypoints (no corresponding header)
libc.src.compiler.__stack_chk_fail
# errno.h entrypoints
libc.src.errno.errno

View File

@ -16,7 +16,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.toascii
libc.src.ctype.tolower
libc.src.ctype.toupper
# errno.h entrypoints
libc.src.errno.errno
@ -239,7 +239,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.asinf
libc.src.math.asinhf
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.atanhf
libc.src.math.copysign
libc.src.math.copysignf
libc.src.math.copysignl
@ -353,6 +353,9 @@ set(TARGET_LIBM_ENTRYPOINTS
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# compiler entrypoints (no corresponding header)
libc.src.compiler.__stack_chk_fail
# network.h entrypoints
libc.src.network.htonl
libc.src.network.htons

View File

@ -66,7 +66,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.inttypes.imaxdiv
libc.src.inttypes.strtoimax
libc.src.inttypes.strtoumax
# stdlib.h entrypoints
libc.src.stdlib.abs
libc.src.stdlib.atoi
@ -88,7 +88,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.strtoll
libc.src.stdlib.strtoul
libc.src.stdlib.strtoull
# sys/mman.h entrypoints
libc.src.sys.mman.mmap
libc.src.sys.mman.munmap

View File

@ -362,6 +362,9 @@ set(TARGET_LIBM_ENTRYPOINTS
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# compiler entrypoints (no corresponding header)
libc.src.compiler.__stack_chk_fail
# assert.h entrypoints
libc.src.assert.__assert_fail

View File

@ -375,6 +375,9 @@ if(LLVM_LIBC_FULL_BUILD)
# assert.h entrypoints
libc.src.assert.__assert_fail
# compiler entrypoints (no corresponding header)
libc.src.compiler.__stack_chk_fail
# dirent.h entrypoints
libc.src.dirent.closedir
libc.src.dirent.dirfd

View File

@ -29,10 +29,11 @@ if(NOT LLVM_LIBC_FULL_BUILD)
endif()
add_subdirectory(assert)
add_subdirectory(compiler)
add_subdirectory(network)
add_subdirectory(search)
add_subdirectory(setjmp)
add_subdirectory(signal)
add_subdirectory(spawn)
add_subdirectory(threads)
add_subdirectory(time)
add_subdirectory(search)

View File

@ -0,0 +1,18 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
else()
add_subdirectory(generic)
endif()
if(TARGET libc.src.compiler.${LIBC_TARGET_OS}.__stack_chk_fail)
set(stack_chk_fail_dep libc.src.compiler.${LIBC_TARGET_OS}.__stack_chk_fail)
else()
set(stack_chk_fail_dep libc.src.compiler.generic.__stack_chk_fail)
endif()
add_entrypoint_object(
__stack_chk_fail
ALIAS
DEPENDS
${stack_chk_fail_dep}
)

View File

@ -0,0 +1,18 @@
//===-- Internal header for __stack_chk_fail --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_COMPILER___STACK_CHK_FAIL_H
#define LLVM_LIBC_SRC_COMPILER___STACK_CHK_FAIL_H
namespace LIBC_NAMESPACE {
[[noreturn]] void __stack_chk_fail();
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_COMPILER___STACK_CHK_FAIL_H

View File

@ -0,0 +1,11 @@
add_entrypoint_object(
__stack_chk_fail
SRCS
__stack_chk_fail.cpp
HDRS
../__stack_chk_fail.h
DEPENDS
libc.include.assert
libc.src.__support.OSUtil.osutil
libc.src.stdlib.abort
)

View File

@ -0,0 +1,20 @@
//===-- Implementation of __stack_chk_fail --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/compiler/__stack_chk_fail.h"
#include "src/__support/OSUtil/io.h"
#include "src/stdlib/abort.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(void, __stack_chk_fail, (void)) {
LIBC_NAMESPACE::write_to_stderr("stack smashing detected");
LIBC_NAMESPACE::abort();
}
} // namespace LIBC_NAMESPACE

View File

@ -25,11 +25,6 @@
extern "C" int main(int, char **, char **);
extern "C" void __stack_chk_fail() {
LIBC_NAMESPACE::write_to_stderr("stack smashing detected");
LIBC_NAMESPACE::abort();
}
namespace LIBC_NAMESPACE {
#ifdef SYS_mmap2

View File

@ -60,8 +60,9 @@ if(NOT LLVM_LIBC_FULL_BUILD)
return()
endif()
add_subdirectory(dirent)
add_subdirectory(assert)
add_subdirectory(compiler)
add_subdirectory(dirent)
add_subdirectory(network)
add_subdirectory(setjmp)
add_subdirectory(signal)

View File

@ -0,0 +1,14 @@
add_custom_target(libc_stack_chk_guard_unittests)
add_libc_unittest(
stack_chk_guard_test
SUITE
libc_stack_chk_guard_unittests
SRCS
stack_chk_guard_test.cpp
DEPENDS
libc.src.compiler.__stack_chk_fail
libc.src.string.memset
COMPILE_OPTIONS
-fstack-protector-all
)

View File

@ -0,0 +1,26 @@
//===-- Unittests for __stack_chk_fail ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm-libc-macros/signal-macros.h"
#include "src/compiler/__stack_chk_fail.h"
#include "src/string/memset.h"
#include "test/UnitTest/Test.h"
TEST(LlvmLibcStackChkFail, Death) {
EXPECT_DEATH([] { LIBC_NAMESPACE::__stack_chk_fail(); },
WITH_SIGNAL(SIGABRT));
}
TEST(LlvmLibcStackChkFail, Smash) {
EXPECT_DEATH(
[] {
int arr[20];
LIBC_NAMESPACE::memset(arr, 0xAA, 9001);
},
WITH_SIGNAL(SIGABRT));
}