拆分内置插件文件的跨平台安全创建
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-22 02:38:11 +08:00
parent f2d675fb55
commit f732a255ce
3 changed files with 86 additions and 32 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}