Skip to content

Fix bugs found by clang-tidy triage; ratchet warning budget to zero - #3047

Merged
madeye merged 1 commit into
masterfrom
fix/clang-tidy-findings
Jul 15, 2026
Merged

madeye merged 1 commit into
masterfrom
fix/clang-tidy-findings

Conversation

@madeye

@madeye madeye commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Full triage of the 29 baseline clang-tidy findings from #3046: every finding was either fixed or verified as a false positive and annotated. The CI ratchet (MAX_WARNINGS) drops from 29 to 0, so any new clang-tidy finding now fails CI.

Real bugs fixed

  • manager.c — uninitialized pid passed to kill(): kill_server/stop_server checked fscanf(...) != EOF, which passes when the pid file contains garbage (fscanf returns 0), leaving pid uninitialized and signaling an arbitrary process — potentially catastrophic when ss-manager runs as root. Now parsed with fgets + the hardened ss_parse_int, requiring pid > 0.
  • utils.c — crash when HOME is unset: get_default_conf() called strlen(getenv("HOME")) without a NULL check (daemons started by init systems commonly have no HOME), and also left a dangling static pointer after free(), a latent use-after-free on repeated calls. Rewritten with a static buffer and a graceful fallback to the system config. Verified: env -u HOME ss-local now errors cleanly instead of segfaulting.
  • local.c — uninitialized fd handed to library callback: in UDP_ONLY mode start_ss_local_server() never set listen_ctx.fd but still passed it to the callback. Initialized to -1.

Improvements

  • Upstream-server selection in ss-local/ss-redir/ss-tunnel now uses libsodium randombytes_uniform() instead of rand() % n with srand(time(NULL)) — unbiased and unpredictable, no seeding needed.
  • FATAL() is now noreturn, teaching the compiler and analyzers about control flow (eliminates a family of analyzer false positives).
  • Removed two dead stores (manager.c, udprelay.c).

False positives (NOLINT with rationale)

uthash macro internals (use-after-free / div-by-zero models), symmetric server<->remote back-pointer cleanup, getpeername/cork_ip_init postconditions the analyzer can't see, binary protocol buffers flagged by C-string checks, and one intentional dead store in vendored json.c.

Verification

  • macOS: Release + ASan/UBSan builds, 12/12 ctest, 3/3 stress-test ciphers, ss-manager target compiles under -Werror.
  • Linux (ubuntu:24.04 at CI parity): full build incl. ss-manager, 12/12 ctest, 3/3 stress, clang-tidy-18: zero warnings.

🤖 Generated with Claude Code

Real bugs fixed:
- manager.c: kill_server/stop_server checked fscanf() != EOF, so malformed
  pid file content left pid uninitialized and passed it to kill(). Parse
  with fgets + ss_parse_int and require pid > 0.
- utils.c: get_default_conf() crashed on strlen(NULL) when HOME is unset
  (e.g. daemons started by init) and left a dangling static pointer after
  free(), a latent use-after-free on repeated calls. Use a static buffer
  and fall back to the system config when HOME is missing.
- local.c: in UDP_ONLY mode, start_ss_local_server() passed uninitialized
  listen_ctx.fd to the library callback. Initialize it to -1.

Improvements:
- Replace rand()/srand(time(NULL)) upstream-server selection in ss-local,
  ss-redir and ss-tunnel with libsodium randombytes_uniform(): unbiased,
  unpredictable, and no seeding required (cert-msc30/msc32).
- Mark FATAL() noreturn so both the compiler and analyzers understand
  control flow (removes a family of analyzer false positives).
- Drop two dead stores (manager.c restore_sigchld, udprelay.c src_addr_len).

All remaining findings were verified as false positives and carry NOLINT
comments with rationale (uthash macro internals, symmetric back-pointer
cleanup, analyzer-invisible postconditions). clang-tidy-18 on Linux now
reports zero warnings, so MAX_WARNINGS drops from 29 to 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@madeye
madeye merged commit dd2704c into master Jul 15, 2026
8 checks passed
@madeye
madeye deleted the fix/clang-tidy-findings branch July 15, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant