carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1//go:build unix
2
3package activator
4
5import (
6 "errors"
7 "os"
8 "syscall"
9
10 "golang.org/x/sys/unix"
11)
12
13// openOwnEnvNoFollow opens a flat row's own env file (<host>.env, or its
14// sibling <host>.config.env) and refuses, in the open itself, what a
15// same-uid sibling (spec §7.2) could have planted at the name: a symlink,
16// by O_NOFOLLOW; and a FIFO or a device, by opening O_NONBLOCK (so the open
17// never waits for a writer that will not come) and then accepting only a
18// regular file from fstat. There is no window between a check and the
19// open. A refused link is the bare errOwnEnvSymlink and a refused non-file
20// the bare errOwnEnvNotRegular: the caller names the path, once. The
21// descriptor is handed back blocking: a regular file never blocks, and the
22// appends and fsyncs that follow want ordinary semantics. A nested row's
23// file needs none of this: instancefs.OpenBeneath does the same with
24// openat2.
25func openOwnEnvNoFollow(path string, flag int, perm os.FileMode) (*os.File, error) {
26 f, err := os.OpenFile(path, flag|unix.O_NOFOLLOW|unix.O_NONBLOCK, perm)
27 if errors.Is(err, unix.ELOOP) {
28 return nil, errOwnEnvSymlink
29 }
30 if err != nil {
31 return nil, err
32 }
33 st, err := f.Stat()
34 if err != nil {
35 f.Close()
36 return nil, err
37 }
38 if !st.Mode().IsRegular() {
39 f.Close()
40 return nil, errOwnEnvNotRegular
41 }
42 if err := syscall.SetNonblock(int(f.Fd()), false); err != nil {
43 f.Close()
44 return nil, err
45 }
46 return f, nil
47}
48