There appears to be a race condition involving the buffers used by the cmdOutput function. I have a fix for this that I'll submit a PR for, just creating this issue to reference there and provide more context.
The cmd output buffer used gets returned to the sync.Pool at the end of cmdOutput, but the value of .Bytes() is also returned. Bytes provides a slice that is "valid for use only until the next buffer modification", so because the buffer was returned to the pool, it can get used by a different caller of cmdOutput and result in simultaneous reads+writes of the same slice.
This was found in the firecracker-containerd repo when running one of our processes built with the -race flag, though we've only seen the race reported rather than any actual issues as a result of it yet. The process is a wrapper around containerd's v2 runc shim, which is where it picks up the transitive dependency on go-runc.
Here's example output of the race detector from that process:
There appears to be a race condition involving the buffers used by the cmdOutput function. I have a fix for this that I'll submit a PR for, just creating this issue to reference there and provide more context.
The cmd output buffer used gets returned to the
sync.Pool
at the end ofcmdOutput
, but the value of.Bytes()
is also returned.Bytes
provides a slice that is "valid for use only until the next buffer modification", so because the buffer was returned to the pool, it can get used by a different caller ofcmdOutput
and result in simultaneous reads+writes of the same slice.This was found in the firecracker-containerd repo when running one of our processes built with the
-race
flag, though we've only seen the race reported rather than any actual issues as a result of it yet. The process is a wrapper around containerd's v2 runc shim, which is where it picks up the transitive dependency ongo-runc
.Here's example output of the race detector from that process: