Skip to content

Commit 678db53

Browse files
timschumilinusg
authored andcommitted
LibC: Properly implement stack protectors
The shared parts are now firmly compiled into LibC instead of being defined as a static library and then being copied over manually. The non-shared ("local") parts are kept as a static library that is linked into each binary on demand. This finally allows us to support linking with the -fstack-protector flag, which now replaces the `ssp` target being linked into each binary accidentally via CMake.
1 parent 7834e26 commit 678db53

File tree

7 files changed

+45
-21
lines changed

7 files changed

+45
-21
lines changed

Meta/CMake/serenity_compile_options.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_compile_options(-fno-semantic-interposition)
2626
add_compile_options(-fsized-deallocation)
2727
add_compile_options(-fstack-clash-protection)
2828
add_compile_options(-fstack-protector-strong)
29+
add_link_options(-fstack-protector-strong)
2930
add_compile_options(-g1)
3031

3132
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

Meta/CMake/utils.cmake

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ function(serenity_set_implicit_links target_name)
99
# slightly outdated stub in the sysroot, but have not yet installed the freshly
1010
# built LibC.
1111
target_link_libraries(${target_name} LibC)
12+
13+
# Same goes for -lssp_nonshared, which is required during build time but is not
14+
# yet installed in the sysroot. However, we just want to add the link directory
15+
# and a dependency here, since actually linking the library is decided on by
16+
# passing one of the -fstack-protector options.
17+
# -lssp is contained inside LibC, so that case is handled by the above and a linker
18+
# script.
19+
target_link_directories(${target_name} PRIVATE "$<TARGET_FILE_DIR:ssp_nonshared>")
20+
add_dependencies(${target_name} ssp_nonshared)
1221
endfunction()
1322

1423
function(serenity_install_headers target_name)

Userland/DynamicLoader/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ set(SOURCES ${LOADER_SOURCES} ${AK_SOURCES} ${ELF_SOURCES} ${LIBC_SOURCES1} ${LI
3333

3434
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -nostdlib -pie -fpic -DNO_TLS")
3535

36-
set_source_files_properties (../Libraries/LibC/ssp.cpp PROPERTIES COMPILE_FLAGS
37-
"-fno-stack-protector")
36+
set_source_files_properties(../Libraries/LibC/ssp.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
37+
set_source_files_properties(../Libraries/LibC/ssp_nonshared.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
3838
# Prevent GCC from removing null checks by marking the `FILE*` argument non-null
3939
set_source_files_properties(../Libraries/LibC/stdio.cpp PROPERTIES COMPILE_FLAGS "-fno-builtin-fputc -fno-builtin-fputs -fno-builtin-fwrite")
4040

Userland/Libraries/LibC/CMakeLists.txt

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ set(LIBC_SOURCES
4646
shadow.cpp
4747
signal.cpp
4848
spawn.cpp
49+
ssp.cpp
4950
stat.cpp
5051
stdio.cpp
5152
stdlib.cpp
@@ -129,15 +130,10 @@ add_custom_command(
129130
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_OBJECTS:crtn> ${CMAKE_INSTALL_PREFIX}/usr/lib/crtn.o
130131
)
131132

132-
set_source_files_properties (ssp.cpp PROPERTIES COMPILE_FLAGS
133-
"-fno-stack-protector")
134-
add_library(ssp STATIC ssp.cpp)
135-
target_link_libraries(ssp PRIVATE NoCoverage)
136-
add_custom_command(
137-
TARGET ssp
138-
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_OBJECTS:ssp> ${CMAKE_INSTALL_PREFIX}/usr/lib/ssp.o
139-
)
140-
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libssp.a DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/lib/)
133+
set_source_files_properties (ssp_nonshared.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
134+
add_library(ssp_nonshared STATIC ssp_nonshared.cpp)
135+
target_link_libraries(ssp_nonshared PRIVATE NoCoverage)
136+
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libssp_nonshared.a DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/lib/)
141137

142138
set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES} ${ASM_SOURCES})
143139

@@ -149,18 +145,19 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
149145
set_source_files_properties(string.cpp wchar.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-loop-distribution -fno-tree-loop-distribute-patterns")
150146
endif()
151147

148+
set_source_files_properties(ssp.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
149+
152150
add_library(LibCStaticWithoutDeps STATIC ${SOURCES})
153151
target_link_libraries(LibCStaticWithoutDeps PUBLIC ssp LibTimeZone PRIVATE NoCoverage)
154152
add_dependencies(LibCStaticWithoutDeps LibSystem LibUBSanitizer)
155153

156154
add_custom_target(LibCStatic
157155
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:LibCStaticWithoutDeps>
158-
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:ssp>
159156
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:LibSystemStatic>
160157
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:LibUBSanitizerStatic>
161158
COMMAND ${CMAKE_AR} -rcs ${CMAKE_CURRENT_BINARY_DIR}/libc.a *.o
162159
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
163-
DEPENDS LibCStaticWithoutDeps ssp LibSystemStatic LibUBSanitizerStatic
160+
DEPENDS LibCStaticWithoutDeps LibSystemStatic LibUBSanitizerStatic
164161
)
165162

166163
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libc.a DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/lib/)
@@ -174,7 +171,7 @@ set_property(
174171
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nolibc")
175172
serenity_libc(LibC c)
176173
add_dependencies(LibC crti crt0 crt0_shared crtn)
177-
target_link_libraries(LibC ssp LibSystem LibTimeZone)
174+
target_link_libraries(LibC LibSystem LibTimeZone)
178175

179176
# We mark LibCStatic as a dependency of LibC because this triggers the build of the LibCStatic target
180177
add_dependencies(LibC LibCStatic)
@@ -183,3 +180,4 @@ add_dependencies(LibC LibCStatic)
183180
file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libpthread.so" "INPUT(libc.so)")
184181
file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libdl.so" "INPUT(libc.so)")
185182
file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libm.so" "INPUT(libc.so)")
183+
file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libssp.so" "INPUT(libc.so)")

Userland/Libraries/LibC/ssp.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,4 @@ __attribute__((noreturn)) void __stack_chk_fail()
2828
abort();
2929
}
3030

31-
__attribute__((noreturn)) void __stack_chk_fail_local()
32-
{
33-
__stack_chk_fail();
34-
}
35-
3631
} // extern "C"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <sys/internals.h>
8+
9+
#if defined __SSP__ || defined __SSP_ALL__
10+
# error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector"
11+
#endif
12+
13+
extern "C" {
14+
15+
__attribute__((noreturn)) void __stack_chk_fail_local()
16+
{
17+
__stack_chk_fail();
18+
}
19+
20+
} // extern "C"

Userland/Libraries/LibSanitizer/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
set(SOURCES
22
UBSanitizer.cpp
33
../LibC/ssp.cpp
4+
../LibC/ssp_nonshared.cpp
45
)
56

6-
set_source_files_properties (../LibC/ssp.cpp PROPERTIES COMPILE_FLAGS
7-
"-fno-stack-protector")
7+
set_source_files_properties(../LibC/ssp.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
8+
set_source_files_properties(../LibC/ssp_nonshared.cpp PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
89

910
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
1011
serenity_libc(LibUBSanitizer ubsan)

0 commit comments

Comments
 (0)