[libc-commits] [libc] 315a5cc - [libc] move __stack_chk_fail to src/ from startup/ (#75863)

via libc-commits libc-commits at lists.llvm.org
Tue Dec 19 11:05:17 PST 2023


Author: Nick Desaulniers
Date: 2023-12-19T11:05:12-08:00
New Revision: 315a5cce89d8f15da5c47d85abbc8155b9c0f0b0

URL: https://github.com/llvm/llvm-project/commit/315a5cce89d8f15da5c47d85abbc8155b9c0f0b0
DIFF: https://github.com/llvm/llvm-project/commit/315a5cce89d8f15da5c47d85abbc8155b9c0f0b0.diff

LOG: [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*`.

Added: 
    libc/src/compiler/CMakeLists.txt
    libc/src/compiler/__stack_chk_fail.h
    libc/src/compiler/generic/CMakeLists.txt
    libc/src/compiler/generic/__stack_chk_fail.cpp
    libc/test/src/compiler/CMakeLists.txt
    libc/test/src/compiler/stack_chk_guard_test.cpp

Modified: 
    libc/config/baremetal/arm/entrypoints.txt
    libc/config/baremetal/riscv/entrypoints.txt
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/arm/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/src/CMakeLists.txt
    libc/startup/linux/x86_64/start.cpp
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index a88b7aa749e565..a0779c41652aeb 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -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

diff  --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 3b7ca513eb0965..3e15cc8901bddf 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -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
 

diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 60e0e2b29aed36..77c9a50b8b7e5d 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -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

diff  --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 123c7e33377ad1..274d5aa5a0057d 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -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

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 948708e35f45d2..e389936ffca1ef 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -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
 

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 1c93063e25e90c..3adcd57d0c0849 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -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

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 3ab62a4f667d26..492f9c5bd50f9b 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -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)

diff  --git a/libc/src/compiler/CMakeLists.txt b/libc/src/compiler/CMakeLists.txt
new file mode 100644
index 00000000000000..aa59d84e08d146
--- /dev/null
+++ b/libc/src/compiler/CMakeLists.txt
@@ -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}
+)

diff  --git a/libc/src/compiler/__stack_chk_fail.h b/libc/src/compiler/__stack_chk_fail.h
new file mode 100644
index 00000000000000..2e3d849ff8c67c
--- /dev/null
+++ b/libc/src/compiler/__stack_chk_fail.h
@@ -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

diff  --git a/libc/src/compiler/generic/CMakeLists.txt b/libc/src/compiler/generic/CMakeLists.txt
new file mode 100644
index 00000000000000..0d869b72a12cf5
--- /dev/null
+++ b/libc/src/compiler/generic/CMakeLists.txt
@@ -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
+)

diff  --git a/libc/src/compiler/generic/__stack_chk_fail.cpp b/libc/src/compiler/generic/__stack_chk_fail.cpp
new file mode 100644
index 00000000000000..0ca02071f2a997
--- /dev/null
+++ b/libc/src/compiler/generic/__stack_chk_fail.cpp
@@ -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

diff  --git a/libc/startup/linux/x86_64/start.cpp b/libc/startup/linux/x86_64/start.cpp
index c98f58a4ac0aff..bc03a3cb1de27f 100644
--- a/libc/startup/linux/x86_64/start.cpp
+++ b/libc/startup/linux/x86_64/start.cpp
@@ -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

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index c45b94f364397e..6bd8ace9ea71af 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -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)

diff  --git a/libc/test/src/compiler/CMakeLists.txt b/libc/test/src/compiler/CMakeLists.txt
new file mode 100644
index 00000000000000..b8d682c1c519a5
--- /dev/null
+++ b/libc/test/src/compiler/CMakeLists.txt
@@ -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
+  )

diff  --git a/libc/test/src/compiler/stack_chk_guard_test.cpp b/libc/test/src/compiler/stack_chk_guard_test.cpp
new file mode 100644
index 00000000000000..1de2d1b7357f70
--- /dev/null
+++ b/libc/test/src/compiler/stack_chk_guard_test.cpp
@@ -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));
+}


        


More information about the libc-commits mailing list