fix(G118): eliminate false positive when cancel is called via struct field in a closure#1596
Merged
ccojocar merged 2 commits intosecurego:masterfrom Mar 10, 2026
Merged
Conversation
…d post-construction When a cancel function is assigned to a struct field after construction (e.g. s.cancel = cancel), the SSA FieldAddr for the store is a distinct value from any FieldAddr created later for defer s.cancel() or inside a closure. The existing isCancelCalledViaStructField only matched receiver methods and missed these patterns. Add isFieldCalledInAnyFunc which scans all SSA functions (including closures) for a FieldAddr with matching struct pointer type and field index, then checks whether the loaded value is called. As a side effect, this also resolves the known false positive for nested struct field access. fixes: 1595
ccojocar
approved these changes
Mar 10, 2026
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1596 +/- ##
==========================================
+ Coverage 80.89% 80.90% +0.01%
==========================================
Files 104 104
Lines 9929 9947 +18
==========================================
+ Hits 8032 8048 +16
- Misses 1407 1408 +1
- Partials 490 491 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ravisastryk
added a commit
to ravisastryk/gosec
that referenced
this pull request
Mar 12, 2026
G118 was incorrectly reporting context cancellation function not called when the cancel function was assigned to a package-level variable (e.g., in init()) and called in a separate function (e.g., signal handler). Root cause: isCancelCalled() lacked special handling for *ssa.Global (package-level variables), causing cross-function tracking to fail. Solution: Add dedicated tracking for package-level globals, similar to the struct field handling added in PR securego#1596. The fix includes: - Check in *ssa.Store case to detect global variable assignments - isGlobalCalledInAnyFunc() helper to search all functions for calls - isValueCalled() generalized helper for BFS value tracking
ravisastryk
added a commit
to ravisastryk/gosec
that referenced
this pull request
Mar 12, 2026
G118 was incorrectly reporting context cancellation function not called when the cancel function was assigned to a package-level variable (e.g., in init()) and called in a separate function (e.g., signal handler). Root cause: isCancelCalled() lacked special handling for *ssa.Global (package-level variables), causing cross-function tracking to fail. Solution: Add dedicated tracking for package-level globals, similar to the struct field handling added in PR securego#1596. The fix includes: - Check in *ssa.Store case to detect global variable assignments - isGlobalCalledInAnyFunc() helper to search all functions for calls - isValueCalled() generalized helper for BFS value tracking
ccojocar
pushed a commit
that referenced
this pull request
Mar 12, 2026
#1602) * fix(G118): eliminate false positive for package-level cancel variables G118 was incorrectly reporting context cancellation function not called when the cancel function was assigned to a package-level variable (e.g., in init()) and called in a separate function (e.g., signal handler). Root cause: isCancelCalled() lacked special handling for *ssa.Global (package-level variables), causing cross-function tracking to fail. Solution: Add dedicated tracking for package-level globals, similar to the struct field handling added in PR #1596. The fix includes: - Check in *ssa.Store case to detect global variable assignments - isGlobalCalledInAnyFunc() helper to search all functions for calls - isValueCalled() generalized helper for BFS value tracking * additional test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix G118 false positive when cancel is called via struct field in a closure
Fixes #1595
Problem
G118 fires a false positive when a cancel function is stored into a struct field after construction and later invoked through that field inside a deferred closure:
The existing fix from #1593 handles the constructor + return pattern but not this one. Here the struct is never returned — the call lives in a closure, which SSA compiles into a separate
*ssa.Function. TheisCancelCalledBFS traces referrers of theFieldAddrfrom theStore, but that value has no referrers bridging to the closure’s ownFieldAddr, so the call is never seen.Fix
Adds
isFieldCalledInAnyFuncwhich scans all SSA functions (including closures) for aFieldAddrmatching the same struct pointer type and field index. If any such address is loaded and used as a call or defer target, the cancel is considered handled.Called from the
Store+FieldAddrbranch inisCancelCalled, after the existingisStructFieldReturnedFromFunccheck.Testing