Skip to content

Fix gosec G118 findings on main - #1064

Open
kaidaguerre wants to merge 2 commits into
mainfrom
issue-1063-gosec-g118-main
Open

Fix gosec G118 findings on main#1064
kaidaguerre wants to merge 2 commits into
mainfrom
issue-1063-gosec-g118-main

Conversation

@kaidaguerre

Copy link
Copy Markdown
Contributor

Summary

The lint CI on main uses golangci/golangci-lint-action with version: latest. The currently-resolved gosec ruleset flags 3 pre-existing G118 (context-propagation) findings in code that predates this change. These break the lint CI gate on main.

These findings already have equivalent fixes on v1.5.x (which pins version: v2.11.4 and is lint-clean) — they were simply never back-ported to main. This PR applies the same resolution to main.

Verified with golangci-lint v2.11.4 rebuilt from source with GOTOOLCHAIN=go1.26.1 (the locally-installed binary is built with an older Go and refuses go1.26 modules), run exactly as CI does: golangci-lint run --timeout=10m ./....

Exact gosec G118 messages (before fix)

Site G118 message
internal/cmdconfig/cmd_hooks.go:101:47 context cancellation function returned by WithCancel/WithTimeout/WithDeadline is not called
internal/dashboardserver/api.go:23:2 Goroutine uses context.Background/TODO while request-scoped context is available
internal/db_client/db_client_execute.go:159:35 context cancellation function returned by WithCancel/WithTimeout/WithDeadline is not called

Per-site fix

internal/cmdconfig/cmd_hooks.go:101 — The cancel func is intentionally stored in the package-level tasksCancelFn, whose ownership belongs to postRunHook. postRunHook previously only called it on the timeout select branch, leaking the context on the channel-closed branch. Changed postRunHook to defer tasksCancelFn() so the context is cancelled on every exit path (a real correctness improvement). gosec's lost-cancel detector cannot trace cancel ownership through a package-level global (it only handles struct fields and direct returns), so a specific, justified //nolint:gosec is added — this is the documented judgement call for this site.

internal/dashboardserver/api.go:23 — The graceful-shutdown context was context.WithTimeout(context.Background(), 5*time.Second) inside a goroutine that has a request-scoped ctx available. Real code fix: derive from context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second). ctx is already Done() at that point (we only reach this line after <-ctx.Done()), so WithoutCancel propagates the request context lineage without inheriting the already-fired cancellation that would otherwise make the shutdown context immediately expired. (Identical to the existing v1.5.x resolution.)

internal/db_client/db_client_execute.go:159 — The cancel func is deliberately discarded; the existing //nolint:govet comment (since 2024) documents that pgx prematurely closes the PG connection if this cancel fires in defer. The deadline timer still bounds the context lifetime, so there is no unbounded leak. Extended the existing directive to //nolint:govet,gosec with the G118 justification — judgement call: genuine deliberate-design false positive (matches the existing v1.5.x resolution).

Judgement calls (nolint)

Two sites use a narrowly-scoped, explained //nolint:gosec (config requires require-explanation + require-specific):

  • cmd_hooks.go:101 — gosec limitation: cannot follow cancel ownership through a package global. The defer tasksCancelFn() change makes cancellation guaranteed on all paths regardless.
  • db_client_execute.go:159 — deliberate, long-documented design (pgx connection-cancellation behaviour); deadline timer still bounds the context.

api.go is a real code fix, no nolint.

Verification

  • golangci-lint v2.11.4 (built GOTOOLCHAIN=go1.26.1), run --timeout=10m ./...: 3 issues → 0 issues. Zero new issues introduced.
  • GOTOOLCHAIN=auto go build ./...: clean (exit 0).
  • GOTOOLCHAIN=auto go test ./...: 6 test packages pass, 0 fail, exit 0.
  • v1.5.x verified with the same binary: 0 issues (not affected — already fixed there). This is a main-only PR.

Why this matters

This unblocks the lint CI gate on main, which is currently failing on these 3 pre-existing findings independently of any other change — including the pgx v5.9.2 backport PR #1062, whose lint CI is blocked by exactly these findings.

Fixes #1063

The golangci-lint 'version: latest' resolved by the lint CI action on main
now bundles a gosec ruleset that flags 3 pre-existing G118 context-propagation
findings. These already have equivalent fixes on v1.5.x that were never
back-ported to main; this commit applies the same resolution.

- internal/cmdconfig/cmd_hooks.go:101
  G118: context cancellation function returned by WithCancel/WithTimeout/
  WithDeadline is not called. The cancel ownership is intentionally
  transferred to the package-level tasksCancelFn. postRunHook now defers
  tasksCancelFn() so the context is cancelled on every exit path (previously
  only the timeout branch cancelled it, leaking the context on the
  channel-closed path). gosec cannot trace cancel ownership through a
  package global, so a specific, justified //nolint:gosec is added.

- internal/dashboardserver/api.go:23
  G118: Goroutine uses context.Background/TODO while request-scoped context
  is available. The graceful-shutdown context now derives from the
  request-scoped ctx via context.WithoutCancel(ctx) (ctx is already Done at
  that point) instead of context.Background(), propagating context lineage.

- internal/db_client/db_client_execute.go:159
  G118: context cancellation function returned by WithCancel/WithTimeout/
  WithDeadline is not called. The cancel is deliberately discarded (existing
  //nolint:govet documents that pgx prematurely closes the PG connection if
  this cancel fires in defer); the deadline timer still bounds the context.
  Extended the existing directive to //nolint:govet,gosec with the G118
  justification.

Fixes #1063
@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions Bot added the stale label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants