Files
shadowsocks-libev/cmake/ProjectOptions.cmake
T
Max LvandClaude 50f1ae54f7 Fix findings from the security audit (#3083)
* Fix findings from the security audit

Remote:
- TCP: handshake/connect deadlines follow --timeout instead of a 24h
  minimum, so idle sockets can no longer fill the connection pool.
- ACL: IPv4-mapped IPv6 addresses are matched against the IPv4 lists.
- UDP server now enforces the peer ACL and the outbound block list.
- ACL loading fails closed on bad files or invalid entries.
- TCP half-close is relayed instead of tearing the connection down.
- AEAD-2022 UDP sessions are created only after timestamp/replay checks.

ss-manager:
- Owner-only conf files (deleted on remove), 0600 control socket,
  umask 022, safe working directory, loopback-only IP addresses,
  per-user sender check on Linux, plugins only over the UNIX socket.
- Port canonicalisation, list() overflow, add/remove waits for the
  server, stale pid files can't signal unrelated processes.

Also: plugins drop to --user, daemonize readiness/pid file handling,
resolver cancellation, replay-filter fail-closed, key wiping, spec
strictness in AEAD/2022 parsing, JSON surrogate validation, ss:// plugin
name checks, embedding API state reset, Android protect_socket replies.

Adds tests/test_server_acl.py and tests/test_half_close.py and extends
the manager, ACL, AEAD-2022 and ssurl tests.

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix CI on Ubuntu 26.04 runners; use string_view over raw string pointers

- Define _GLIBCXX_NO_ASSERTIONS: libstdc++ 15 enables assertions at -O0,
  which pulls __glibcxx_assert_fail (C++ runtime) into the programs.
- test_redir_qemu: boot the guest with -cpu max so the runner's glibc
  loader runs under TCG.
- find_program: std::string_view PATH splitting into a fixed buffer, no
  heap and no null snprintf destination (GCC -Wformat-truncation).
- manager: parse /proc/net/udp numbers with strtoul (cert-err34-c);
  walk /proc/<pid>/cmdline with std::string_view.
- ssurl: sanitise the tag through std::span.

Co-Authored-By: Claude <noreply@anthropic.com>

* coverage: tolerate gcov 15 lambda inconsistencies in lcov 2

Co-Authored-By: Claude <noreply@anthropic.com>

* resolver: replace init's cleanup lambda with a member; lcov --list ignores inconsistent

gcov 15 marks the lambda as not hit while its lines are, which lcov 2
rejects.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-28 09:34:36 +08:00

79 lines
3.9 KiB
CMake

include(CheckCCompilerFlag)
option(DISABLE_SSP "Disable stack protector" OFF)
if(NOT DISABLE_SSP AND NOT MSVC)
check_c_compiler_flag(-fstack-protector-strong HAS_STACK_PROTECTOR)
endif()
function(ss_project_options target)
set_property(TARGET ${target} PROPERTY NO_SYSTEM_FROM_IMPORTED TRUE)
target_include_directories(${target} BEFORE PRIVATE ${MBEDTLS_INCLUDE_DIRS})
if(WIN32)
target_compile_definitions(${target} PRIVATE WIN32_LEAN_AND_MEAN __USE_MINGW_ANSI_STDIO=1)
# MinGW can otherwise pull in libwinpthread/libgcc from the toolchain,
# even when all explicitly selected dependencies are static archives.
get_target_property(ss_target_type ${target} TYPE)
# Zig already supplies its own runtime for DLLs; its -static switch
# changes the output kind instead of just selecting static libraries.
if(NOT ss_target_type STREQUAL "SHARED_LIBRARY" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${target} PRIVATE -static)
endif()
endif()
if(MSVC)
target_compile_options(${target} PRIVATE /W4)
if(SS_WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE /WX)
endif()
else()
target_compile_options(${target} PRIVATE -Wall -Wno-deprecated-declarations -fno-strict-aliasing)
# C++ sources: no exceptions or RTTI, and no locks around function
# statics (the event loop is single-threaded). New C++ code also opts
# into -Wextra through ss_strict_warnings(); modules ported from C get
# it when they are rewritten.
target_compile_options(${target} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-threadsafe-statics>)
# libstdc++ 15 enables its assertions at -O0, and they call
# __glibcxx_assert_fail from the C++ runtime, which the programs and
# libshadowsocks-c must not need (scripts/check_cxx_runtime.py).
target_compile_definitions(${target} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:_GLIBCXX_NO_ASSERTIONS>)
# GCC's C++ -Wall adds -Wsign-compare and -Wclass-memaccess, which C's
# -Wall does not have. Modules converted from C keep the warning set
# they were written against; ss_strict_warnings() turns both back on.
target_compile_options(${target} PRIVATE
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-sign-compare -Wno-class-memaccess>)
if(SS_WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE -Werror)
endif()
if(HAS_STACK_PROTECTOR)
target_compile_options(${target} PRIVATE -fstack-protector-strong)
endif()
if(MINGW OR CYGWIN)
target_compile_options(${target} PRIVATE -mno-ms-bitfields)
endif()
endif()
if(LINUX)
target_compile_definitions(${target} PRIVATE _GNU_SOURCE)
endif()
if(ENABLE_SANITIZERS)
if(MSVC)
message(FATAL_ERROR "ASan + UBSan requires GCC or Clang")
endif()
target_compile_options(${target} PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer)
target_link_options(${target} PRIVATE -fsanitize=address,undefined)
endif()
if(ENABLE_COVERAGE)
target_compile_options(${target} PRIVATE -O0 --coverage)
target_link_options(${target} PRIVATE --coverage)
endif()
endfunction()
# Extra warnings for source files written as C++ from the start (src/core,
# src/event, src/crypto and their tests). Per file, so targets that also
# compile converted C modules keep those at -Wall. Source properties are
# directory-scoped: call this from the directory that defines the targets.
function(ss_strict_warnings)
if(NOT MSVC)
set_source_files_properties(${ARGN} PROPERTIES COMPILE_OPTIONS
"-Wextra;$<$<CXX_COMPILER_ID:GNU>:-Wsign-compare>;$<$<CXX_COMPILER_ID:GNU>:-Wclass-memaccess>")
endif()
endfunction()