Skip to content

runtime: append can write out of bounds during data races #73563

@ikonst

Description

@ikonst

When concurrently appending to the same slice, it's easy to get it to memcpy past the end due to struct (slice in this case) copy being non-atomic, i.e. if cap is copied before arr, concurrent code can use old arr with a new cap.

My issue isn't with the non-atomicity of the copy, or with slices being unsafe for data races, and I'm not making a case for communicating by sharing memory ;) Rather, it's about the failure mode being not only data loss in the particular slice (to be expected in a data structure that's not thread-safe) but also spooky actions at a distance (random heap writes, "impossible" crashes).

In practical programs, concurrent appends may be inadvertent. Packages use slices casually, in ways the author might not think to advertise, and the user might not think to inspect. Suppose a debug logging mechanism using a global slice - a slice which is not even read by anyone except when debugging - and then suppose someone starts concurrently calling a function which uses the logging function. This could result in a heap corruption that would be difficult to track down.

There might be practical solutions, e.g.

  • make it so that arr is copied before cap
  • store the capacity in the head of the arr buffer rather than in cap

(Apologies if an obvious dup, I couldn't find one.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions