diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 476ebdd6aa..6f2bf7b803 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -139,7 +139,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { potentiallyUnderRuntimeDir := []string{cli.Config.ExecRoot} if cli.Pidfile != "" { - if err := pidfile.Write(cli.Pidfile); err != nil { + if err = pidfile.Write(cli.Pidfile, os.Getpid()); err != nil { return errors.Wrap(err, "failed to start daemon") } potentiallyUnderRuntimeDir = append(potentiallyUnderRuntimeDir, cli.Pidfile) diff --git a/pkg/pidfile/pidfile.go b/pkg/pidfile/pidfile.go index 09a415b11a..48a90387a6 100644 --- a/pkg/pidfile/pidfile.go +++ b/pkg/pidfile/pidfile.go @@ -32,12 +32,17 @@ func checkPIDFileAlreadyExists(path string) error { // Write writes a "PID file" at the specified path. It returns an error if the // file exists and contains a valid PID of a running process, or when failing // to write the file. -func Write(path string) error { +func Write(path string, pid int) error { + if pid < 1 { + // We might be running as PID 1 when running docker-in-docker, + // but 0 or negative PIDs are not acceptable. + return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid) + } if err := checkPIDFileAlreadyExists(path); err != nil { return err } if err := system.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err } - return os.WriteFile(path, []byte(strconv.Itoa(os.Getpid())), 0o644) + return os.WriteFile(path, []byte(strconv.Itoa(pid)), 0o644) } diff --git a/pkg/pidfile/pidfile_test.go b/pkg/pidfile/pidfile_test.go index df3169acdb..09996c6765 100644 --- a/pkg/pidfile/pidfile_test.go +++ b/pkg/pidfile/pidfile_test.go @@ -1,18 +1,25 @@ package pidfile // import "github.com/docker/docker/pkg/pidfile" import ( + "os" "path/filepath" "testing" ) func TestWrite(t *testing.T) { path := filepath.Join(t.TempDir(), "testfile") - err := Write(path) + + err := Write(path, 0) + if err == nil { + t.Fatal("writing PID < 1 should fail") + } + + err = Write(path, os.Getpid()) if err != nil { t.Fatal("Could not create test file", err) } - err = Write(path) + err = Write(path, os.Getpid()) if err == nil { t.Fatal("Test file creation not blocked") }