mirror of
https://github.com/securego/gosec.git
synced 2026-06-20 00:15:59 +02:00
Fix G118 false positive on cancel called inside goroutine closure (#1592)
The isCancelCalled function did not handle *ssa.MakeClosure, so when
a cancel function was captured as a free variable in a closure
(e.g. go func() { cancel() }()), gosec could not see the call inside
the closure body and reported a false positive.
Add a MakeClosure case that follows the cancel value into the closure's
FreeVars, allowing the existing call-detection logic to find the
invocation.
Fixes #1590
This commit is contained in:
@@ -725,6 +725,17 @@ func isCancelCalled(cancelValue ssa.Value, allFuncs []*ssa.Function) bool {
|
||||
if r.X == current {
|
||||
queue = append(queue, r)
|
||||
}
|
||||
case *ssa.MakeClosure:
|
||||
// The cancel value is captured as a free variable in a closure.
|
||||
// Find the corresponding FreeVar inside the closure body and
|
||||
// follow it so that calls within the closure are detected.
|
||||
if fn, ok := r.Fn.(*ssa.Function); ok {
|
||||
for i, binding := range r.Bindings {
|
||||
if binding == current && i < len(fn.FreeVars) {
|
||||
queue = append(queue, fn.FreeVars[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
case *ssa.Return:
|
||||
// Cancel function is returned to the caller — responsibility
|
||||
// is transferred; treat as "called".
|
||||
|
||||
@@ -1551,5 +1551,21 @@ func initDatabase(ctx context.Context) (*sql.DB, func(), error) {
|
||||
}
|
||||
return db, cancelFunc, nil
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
|
||||
// Safe: cancel called inside goroutine closure (issue #1590)
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
cancel()
|
||||
}()
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user