Skip to content

Data race on EOFOnWriteFromServerToClient in forwardConnection #146

Description

@perk11

main.go:15851627

Two goroutines concurrently read/write the shared *bool
EOFOnWriteFromServerToClient (allocated via new(bool) by whichever finishes
first) with no synchronization. Both goroutines check == nil, then
assign the pointer and write through it; the final if *EOFOnWriteFromServerToClient
at line 1626 (after wg.Wait()) reads it from the parent goroutine.

  • The go test -race run passes only because in practice both copy loops
    tend to complete-and-close in a serialized way under the test workload; it is
    not guaranteed to trigger. It is a genuine data race per the Go memory model.
  • It is also pre-existing (introduced in commit 051d3048, before this
    branch), but since this branch's whole purpose is concurrency hardening it is
    worth closing now.

Fix: drop the shared-pointer pattern. wg.Wait() already happens-before
both goroutine exits, so a single bool per goroutine written before wg.Done()
and read after wg.Wait() is race-free:

var eofServerToClient bool
go func() {
    defer wg.Done()
    ... copy clientReader -> serviceConnection ...
    eofServerToClient = true   // written before wg.Done()
    serviceConnection.Close()
}()
go func() {
    defer wg.Done()
    ... copy serviceConnection -> clientConnection ...
    // eofServerToClient stays false
    clientConnection.Close()
}()
wg.Wait()
// reads after happens-before edge — safe
var reason string
if eofServerToClient { ... }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions