diff --git a/backend/hooks/bundle.go b/backend/hooks/bundle.go index d19aa9fa..ef65a0d2 100644 --- a/backend/hooks/bundle.go +++ b/backend/hooks/bundle.go @@ -1,9 +1,7 @@ package hooks import ( - "bytes" "errors" - "io" "io/fs" "os" "path/filepath" @@ -52,33 +50,3 @@ func pluginRoot() (string, error) { bundledRoot = root return root, nil } - -func writeBundledPlugin(path string, data []byte) error { - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) - if err != nil { - return err - } - remove := true - defer func() { - if remove { - _ = os.Remove(path) - } - }() - if _, err := io.Copy(file, bytes.NewReader(data)); err != nil { - _ = file.Close() - return err - } - if err := file.Sync(); err != nil { - _ = file.Close() - return err - } - if err := file.Chmod(0700); err != nil { - _ = file.Close() - return err - } - if err := file.Close(); err != nil { - return err - } - remove = false - return nil -} diff --git a/backend/hooks/bundle_file_linux.go b/backend/hooks/bundle_file_linux.go new file mode 100644 index 00000000..17fea932 --- /dev/null +++ b/backend/hooks/bundle_file_linux.go @@ -0,0 +1,47 @@ +//go:build linux + +package hooks + +import ( + "bytes" + "errors" + "io" + "os" + + "golang.org/x/sys/unix" +) + +func writeBundledPlugin(path string, data []byte) error { + fd, err := unix.Open(path, unix.O_WRONLY|unix.O_CREAT|unix.O_EXCL|unix.O_CLOEXEC|unix.O_NOFOLLOW, 0600) + if err != nil { + return err + } + file := os.NewFile(uintptr(fd), path) + if file == nil { + _ = unix.Close(fd) + return errors.New("create bundled plugin returned an invalid file") + } + remove := true + defer func() { + if remove { + _ = unix.Unlink(path) + } + }() + if _, err := io.Copy(file, bytes.NewReader(data)); err != nil { + _ = file.Close() + return err + } + if err := file.Sync(); err != nil { + _ = file.Close() + return err + } + if err := file.Chmod(0700); err != nil { + _ = file.Close() + return err + } + if err := file.Close(); err != nil { + return err + } + remove = false + return nil +} diff --git a/backend/hooks/bundle_file_windows.go b/backend/hooks/bundle_file_windows.go new file mode 100644 index 00000000..c9c48a7f --- /dev/null +++ b/backend/hooks/bundle_file_windows.go @@ -0,0 +1,39 @@ +//go:build windows + +package hooks + +import ( + "bytes" + "io" + "os" +) + +func writeBundledPlugin(path string, data []byte) error { + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) // #nosec G304 -- the path is an entry under a private temporary bundle root. + if err != nil { + return err + } + remove := true + defer func() { + if remove { + _ = os.Remove(path) + } + }() + if _, err := io.Copy(file, bytes.NewReader(data)); err != nil { + _ = file.Close() + return err + } + if err := file.Sync(); err != nil { + _ = file.Close() + return err + } + if err := file.Chmod(0700); err != nil { + _ = file.Close() + return err + } + if err := file.Close(); err != nil { + return err + } + remove = false + return nil +}