Skip to content

Commit e669926

Browse files
committed
fix an error caused by fd reuse race when starting runc init
There is a race situation when we are opening a file, if there is a small fd was closed at that time, maybe it will be reused by safeExe. Because of Go stdlib fds shuffling bug, if the fd of safeExe is too small, go stdlib will dup3 it to another fd, or dup3 a other fd to this fd, then it will cause the fd type cmd.Path refers to a random path, and it can lead to an error "permission denied" when starting the process. Please see #4294 and <golang/go#61751>. So we should not use the original fd of safeExe, but use the fd after shuffled by Go stdlib. Because Go stdlib will guarantee this fd refers to the correct file. Signed-off-by: lfbzhm <[email protected]>
1 parent ca8ca3c commit e669926

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

libcontainer/container_linux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ func (c *Container) newParentProcess(p *Process) (parentProcess, error) {
618618
)
619619
}
620620

621+
// TODO: After https://go-review.googlesource.com/c/go/+/515799 included
622+
// in go versions supported by us, we can remove this logic.
621623
if safeExe != nil {
622624
// Due to a Go stdlib bug, we need to add safeExe to the set of
623625
// ExtraFiles otherwise it is possible for the stdlib to clobber the fd
@@ -628,6 +630,18 @@ func (c *Container) newParentProcess(p *Process) (parentProcess, error) {
628630
//
629631
// See <https://github.com/golang/go/issues/61751>.
630632
cmd.ExtraFiles = append(cmd.ExtraFiles, safeExe)
633+
634+
// There is a race situation when we are opening a file, if there is a
635+
// small fd was closed at that time, maybe it will be reused by safeExe.
636+
// Because of Go stdlib fds shuffling bug, if the fd of safeExe is too
637+
// small, go stdlib will dup3 it to another fd, or dup3 a other fd to this
638+
// fd, then it will cause the fd type cmd.Path refers to a random path,
639+
// and it can lead to an error "permission denied" when starting the process.
640+
// Please see #4294.
641+
// So we should not use the original fd of safeExe, but use the fd after
642+
// shuffled by Go stdlib. Because Go stdlib will guarantee this fd refers to
643+
// the correct file.
644+
cmd.Path = "/proc/self/fd/" + strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1)
631645
}
632646

633647
// NOTE: when running a container with no PID namespace and the parent

0 commit comments

Comments
 (0)