Skip to content

ssh: fix deadlock on unexpected global responses (CVE-2026-39830) - backport to v0.39.0#4

Open
yiraeChristineKim wants to merge 1 commit into
openshift-sustaining:masterfrom
yiraeChristineKim:sec-patch-v0.39.1
Open

ssh: fix deadlock on unexpected global responses (CVE-2026-39830) - backport to v0.39.0#4
yiraeChristineKim wants to merge 1 commit into
openshift-sustaining:masterfrom
yiraeChristineKim:sec-patch-v0.39.1

Conversation

@yiraeChristineKim

Copy link
Copy Markdown

Summary

Backport of upstream fix golang/crypto@4e7a7384ecbc onto v0.39.0 for Go 1.23 compatibility (HyperShift release-4.19).

CVE-2026-39830 / GO-2026-5017

A malicious SSH peer could send unsolicited global request responses to fill the internal globalResponses channel buffer (size 1), causing handleGlobalPacket to block indefinitely and stall the connection's read loop. Calling Close() could not release the blocked goroutine, resulting in a resource leak per connection.

Fix: replace the blocking send in handleGlobalPacket with a conditional non-blocking send gated on globalSentPending. A drain loop in SendRequest discards any stale buffered responses before sending a new request.

Why a backport?

The upstream fix shipped in v0.52.0 which requires go 1.25.0. The HyperShift release-4.19 branch builds with Go 1.23 (rhel_9_golang_1.23 / go-toolset:1.23.6). This backport keeps go 1.23.0 in go.mod so it can be used as a replace directive.

Requested action

Once reviewed, please:

  1. Create branch sustaining-v0.39.1 in this repo from the v0.39.0 tag with this fix applied
  2. Create tag v0.39.1-sec.1

This will allow updating HyperShift's go.mod from:

replace golang.org/x/crypto => github.com/yiraeChristineKim/crypto v0.39.1-sec.1

to:

replace golang.org/x/crypto => github.com/openshift-sustaining/crypto v0.39.1-sec.1

Jira: https://redhat.atlassian.net/browse/ACM-35720
Upstream fix: golang@4e7a7384ecbc
CVE: CVE-2026-39830

Made with Cursor

Backport of upstream fix golang/crypto@4e7a7384ecbc onto v0.39.0 for
Go 1.23 compatibility (release-4.19). The go.mod go directive remains
at 1.23.0; no go 1.25 language features are used.

Previously, handleGlobalPacket blocked on sending to globalResponses
(buffer size 1), allowing a malicious SSH peer to stall the connection
read loop permanently.

Fix: replace the blocking send with a conditional non-blocking send
gated on globalSentPending. A drain loop in SendRequest discards any
stale buffered responses before sending a new request.

CVE: CVE-2026-39830
GO: GO-2026-5017
Upstream: golang@4e7a7384ecbc
Co-authored-by: Cursor <cursoragent@cursor.com>
@yiraeChristineKim

Copy link
Copy Markdown
Author

Update: The branch has been rebased to resolve the conflict in ssh/mux.go.

The only difference was the drain loop form. This branch now matches master's version exactly (handling closed channel with case _, ok := <-m.globalResponses), which is more defensive and handles graceful connection close.

A new tag v0.39.1-sec.2 has been pushed to the source fork with the corrected content. The hypershift go.mod replace directive now points to v0.39.1-sec.2.

Note on immutability: Go module proxies cache module content per-version permanently. v0.39.1-sec.1 was already cached with the old drain loop, so a new tag (sec.2) was required rather than force-reusing sec.1.

Once a maintainer with write access creates branch sustaining-v0.39.1 + tag v0.39.1-sec.2 in this repo (openshift-sustaining/crypto), the hypershift replace directive can be updated from yiraeChristineKim/crypto to openshift-sustaining/crypto.

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