carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package rootstate
2
3import (
4 "os"
5 "path/filepath"
6
7 "github.com/carlosframework/platform/internal/safefile"
8 "golang.org/x/sys/unix"
9)
10
11func OpenTrustedFile(path string) (*os.File, error) {
12 if !filepath.IsAbs(path) || filepath.Clean(path) != path || path == "/" {
13 return nil, os.ErrPermission
14 }
15 s, err := Open(filepath.Dir(path), false, true)
16 if err != nil {
17 return nil, err
18 }
19 defer s.Close()
20 d := s.(*directory)
21 f, err := safefile.OpenFileAt(int(d.file.Fd()), filepath.Base(path), os.O_RDONLY, 0)
22 if err != nil {
23 return nil, err
24 }
25 if err := trusted(int(f.Fd()), 0, unix.S_IFREG); err != nil {
26 f.Close()
27 return nil, err
28 }
29 return f, nil
30}
31
32func Identity(f *os.File) (FileIdentity, error) {
33 var st unix.Stat_t
34 if err := unix.Fstat(int(f.Fd()), &st); err != nil {
35 return FileIdentity{}, err
36 }
37 return FileIdentity{Device: uint64(st.Dev), Inode: st.Ino}, nil
38}
39
40func CheckPublicConfig(f *os.File) error {
41 var st unix.Stat_t
42 if err := unix.Fstat(int(f.Fd()), &st); err != nil {
43 return err
44 }
45 if st.Uid != 0 || st.Gid != 0 || st.Mode&07777 != 0644 || st.Mode&unix.S_IFMT != unix.S_IFREG || st.Nlink != 1 {
46 return os.ErrPermission
47 }
48 return nil
49}
50