diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index f725b1c2394c6a..39f54440780deb 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS # compiler entrypoints (no corresponding header) libc.src.compiler.__stack_chk_fail + libc.src.compiler.__stack_chk_guard # errno.h entrypoints libc.src.errno.errno diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 5da755170fda96..79bd24bea103ae 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS # compiler entrypoints (no corresponding header) libc.src.compiler.__stack_chk_fail + libc.src.compiler.__stack_chk_guard # errno.h entrypoints libc.src.errno.errno diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 625fa6bffe63c6..7496947a781bd4 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -366,6 +366,7 @@ if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # compiler entrypoints (no corresponding header) libc.src.compiler.__stack_chk_fail + libc.src.compiler.__stack_chk_guard # network.h entrypoints libc.src.network.htonl diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index c75ac2302d4ac4..7070f6c4e5a152 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -235,6 +235,14 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.truncl ) +if(LLVM_LIBC_FULL_BUILD) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # compiler entrypoints (no corresponding header) + libc.src.compiler.__stack_chk_fail + libc.src.compiler.__stack_chk_guard + ) +endif() + set(TARGET_LLVMLIBC_ENTRYPOINTS ${TARGET_LIBC_ENTRYPOINTS} ${TARGET_LIBM_ENTRYPOINTS} diff --git a/libc/src/compiler/CMakeLists.txt b/libc/src/compiler/CMakeLists.txt index aa59d84e08d146..b37b2dbe1c6198 100644 --- a/libc/src/compiler/CMakeLists.txt +++ b/libc/src/compiler/CMakeLists.txt @@ -1,9 +1,9 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) -else() - add_subdirectory(generic) endif() +add_subdirectory(generic) + 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() @@ -16,3 +16,16 @@ add_entrypoint_object( DEPENDS ${stack_chk_fail_dep} ) + +if(TARGET libc.src.compiler.${LIBC_TARGET_OS}.__stack_chk_guard) + set(stack_chk_guard_dep libc.src.compiler.${LIBC_TARGET_OS}.__stack_chk_guard) +else() + set(stack_chk_guard_dep libc.src.compiler.generic.__stack_chk_guard) +endif() + +add_entrypoint_object( + __stack_chk_guard + ALIAS + DEPENDS + ${stack_chk_guard_dep} +) diff --git a/libc/src/compiler/__stack_chk_guard.h b/libc/src/compiler/__stack_chk_guard.h new file mode 100644 index 00000000000000..17edefa3465d7e --- /dev/null +++ b/libc/src/compiler/__stack_chk_guard.h @@ -0,0 +1,20 @@ +//===-- Internal header for __stack_chk_guard -------------------*- 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_GUARD_H +#define LLVM_LIBC_SRC_COMPILER___STACK_CHK_GUARD_H + +#include + +// The compiler will emit calls implicitly to a non-namespaced version. +// TODO: can we additionally provide a namespaced alias so that tests can +// explicitly call the namespaced variant rather than the non-namespaced +// definition? +extern "C" uintptr_t __stack_chk_guard; + +#endif // LLVM_LIBC_SRC_COMPILER___STACK_CHK_GUARD_H diff --git a/libc/src/compiler/baremetal/CMakeLists.txt b/libc/src/compiler/baremetal/CMakeLists.txt new file mode 100644 index 00000000000000..222ca9fc152367 --- /dev/null +++ b/libc/src/compiler/baremetal/CMakeLists.txt @@ -0,0 +1,7 @@ +add_entrypoint_object( + __stack_chk_guard + SRCS + __stack_chk_guard.cpp + HDRS + ../__stack_chk_guard.h +) diff --git a/libc/src/compiler/baremetal/__stack_chk_guard.cpp b/libc/src/compiler/baremetal/__stack_chk_guard.cpp new file mode 100644 index 00000000000000..691e0c4f725220 --- /dev/null +++ b/libc/src/compiler/baremetal/__stack_chk_guard.cpp @@ -0,0 +1,17 @@ +//===-- Implementation of __stack_chk_guard -------------------------------===// +// +// 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_guard.h" + +#include + +extern "C" { + +uintptr_t __stack_chk_guard = 0x00000aff; // 0, 0, '\n', 255 + +} // extern "C" diff --git a/libc/src/compiler/linux/CMakeLists.txt b/libc/src/compiler/linux/CMakeLists.txt new file mode 100644 index 00000000000000..33918fb2f4db28 --- /dev/null +++ b/libc/src/compiler/linux/CMakeLists.txt @@ -0,0 +1,11 @@ +add_entrypoint_object( + __stack_chk_guard + SRCS + __stack_chk_guard.cpp + HDRS + ../__stack_chk_guard.h + DEPENDS + libc.src.__support.OSUtil.osutil + COMPILE_OPTIONS + -Wno-global-constructors +) diff --git a/libc/src/compiler/linux/__stack_chk_guard.cpp b/libc/src/compiler/linux/__stack_chk_guard.cpp new file mode 100644 index 00000000000000..112dd2a52da70c --- /dev/null +++ b/libc/src/compiler/linux/__stack_chk_guard.cpp @@ -0,0 +1,39 @@ +//===-- Implementation of __stack_chk_guard -------------------------------===// +// +// 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_guard.h" +#include "src/__support/OSUtil/syscall.h" +#include "src/errno/libc_errno.h" + +#include + +extern "C" { + +uintptr_t __stack_chk_guard = 0; + +} // extern "C" + +namespace LIBC_NAMESPACE { +namespace { + +class StackCheckGuard { +public: + StackCheckGuard() { + // TODO: Use getauxval(AT_RANDOM) once available. + long retval = + syscall_impl(SYS_getrandom, reinterpret_cast(&__stack_chk_guard), + sizeof(uintptr_t), 0); + if (retval < 0) + __stack_chk_guard = 0x00000aff; // 0, 0, '\n', 255 + } +}; + +StackCheckGuard stack_check_guard; + +} // anonymous namespace +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/compiler/CMakeLists.txt b/libc/test/src/compiler/CMakeLists.txt index 65a9acceb6f7f1..39f96eb2272431 100644 --- a/libc/test/src/compiler/CMakeLists.txt +++ b/libc/test/src/compiler/CMakeLists.txt @@ -9,6 +9,7 @@ add_libc_unittest( DEPENDS libc.src.__support.macros.sanitizer libc.src.compiler.__stack_chk_fail + libc.src.compiler.__stack_chk_guard libc.src.string.memset COMPILE_OPTIONS -fstack-protector-all