ONNX
security
malware-detection
Vigil / source /pkg /compactscan /preflight.go
turentomer's picture
Publish self-contained Vigil distribution
d2507b5 verified
Raw
History Blame Contribute Delete
2.56 kB
package compactscan
import (
"errors"
"io/fs"
"os"
"path/filepath"
)
// preflightMaxFiles mirrors the whole-bundle scanner's discovery bound. It
// counts SKILL.md as well as siblings, so an accepted tree always fits within
// the scanner without producing a partial-scan note.
const preflightMaxFiles = 4096
// preflightPackage validates the complete package tree without reading member
// content. In particular, this runs before bundle.Scan, whose analysis path is
// intentionally willing to inspect symlink targets. Compact scoring is
// stricter: no link or special file may be opened at all.
func preflightPackage(rootPath string) error {
rootInfo, err := os.Lstat(rootPath)
if err != nil {
return errors.New("inspect package root")
}
if rootInfo.Mode()&os.ModeSymlink != 0 || !rootInfo.IsDir() {
return errors.New("package root is not an unlinked directory")
}
root, err := os.OpenRoot(rootPath)
if err != nil {
return errors.New("open package root")
}
defer root.Close()
fileCount := 0
err = filepath.WalkDir(rootPath, func(path string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return errors.New("walk package tree")
}
if path == rootPath {
return nil
}
rel, err := filepath.Rel(rootPath, path)
if err != nil || rel == "." || filepath.IsAbs(rel) || hasTraversal(rel) {
return errors.New("package tree contains a non-canonical member")
}
info, err := root.Lstat(rel)
if err != nil {
return errors.New("package member changed during preflight")
}
if info.Mode()&os.ModeSymlink != 0 {
return errors.New("package tree contains a symlink")
}
if info.IsDir() {
return nil
}
if !info.Mode().IsRegular() {
return errors.New("package tree contains a non-regular file")
}
fileCount++
if fileCount > preflightMaxFiles {
return errors.New("package tree exceeds the file limit")
}
file, err := openPreflightFile(root, rel)
if err != nil {
return errors.New("open package member during preflight")
}
opened, statErr := file.Stat()
if statErr != nil {
_ = file.Close()
return errors.New("stat package member during preflight")
}
links, linkErr := openedHardLinkCount(file, opened)
closeErr := file.Close()
if linkErr != nil || closeErr != nil || !opened.Mode().IsRegular() || !os.SameFile(info, opened) {
return errors.New("package member changed during preflight")
}
if links != 1 {
return errors.New("package tree contains a hard-linked file")
}
return nil
})
if err != nil {
return err
}
return nil
}