@@ -77,16 +77,16 @@ var (
7777 // TestMode is set to true by unit tests that need "fake" cgroupfs.
7878 TestMode bool
7979
80- cgroupFd int = - 1
81- prepOnce sync.Once
82- prepErr error
83- resolveFlags uint64
80+ cgroupRootHandle * os. File
81+ prepOnce sync.Once
82+ prepErr error
83+ resolveFlags uint64
8484)
8585
8686func prepareOpenat2 () error {
8787 prepOnce .Do (func () {
8888 fd , err := unix .Openat2 (- 1 , cgroupfsDir , & unix.OpenHow {
89- Flags : unix .O_DIRECTORY | unix .O_PATH ,
89+ Flags : unix .O_DIRECTORY | unix .O_PATH | unix . O_CLOEXEC ,
9090 })
9191 if err != nil {
9292 prepErr = & os.PathError {Op : "openat2" , Path : cgroupfsDir , Err : err }
@@ -97,15 +97,16 @@ func prepareOpenat2() error {
9797 }
9898 return
9999 }
100+ file := os .NewFile (uintptr (fd ), cgroupfsDir )
101+
100102 var st unix.Statfs_t
101- if err = unix .Fstatfs (fd , & st ); err != nil {
103+ if err : = unix .Fstatfs (int ( file . Fd ()) , & st ); err != nil {
102104 prepErr = & os.PathError {Op : "statfs" , Path : cgroupfsDir , Err : err }
103105 logrus .Warnf ("falling back to securejoin: %s" , prepErr )
104106 return
105107 }
106108
107- cgroupFd = fd
108-
109+ cgroupRootHandle = file
109110 resolveFlags = unix .RESOLVE_BENEATH | unix .RESOLVE_NO_MAGICLINKS
110111 if st .Type == unix .CGROUP2_SUPER_MAGIC {
111112 // cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks
@@ -132,28 +133,28 @@ func openFile(dir, file string, flags int) (*os.File, error) {
132133 return openFallback (path , flags , mode )
133134 }
134135
135- fd , err := unix .Openat2 (cgroupFd , relPath ,
136+ fd , err := unix .Openat2 (int ( cgroupRootHandle . Fd ()) , relPath ,
136137 & unix.OpenHow {
137138 Resolve : resolveFlags ,
138139 Flags : uint64 (flags ) | unix .O_CLOEXEC ,
139140 Mode : uint64 (mode ),
140141 })
141142 if err != nil {
142143 err = & os.PathError {Op : "openat2" , Path : path , Err : err }
143- // Check if cgroupFd is still opened to cgroupfsDir
144+ // Check if cgroupRootHandle is still opened to cgroupfsDir
144145 // (happens when this package is incorrectly used
145146 // across the chroot/pivot_root/mntns boundary, or
146147 // when /sys/fs/cgroup is remounted).
147148 //
148149 // TODO: if such usage will ever be common, amend this
149- // to reopen cgroupFd and retry openat2.
150- fdStr := strconv .Itoa (cgroupFd )
150+ // to reopen cgroupRootHandle and retry openat2.
151+ fdStr := strconv .Itoa (int ( cgroupRootHandle . Fd ()) )
151152 fdDest , _ := os .Readlink ("/proc/self/fd/" + fdStr )
152153 if fdDest != cgroupfsDir {
153- // Wrap the error so it is clear that cgroupFd
154+ // Wrap the error so it is clear that cgroupRootHandle
154155 // is opened to an unexpected/wrong directory.
155- err = fmt .Errorf ("cgroupFd %s unexpectedly opened to %s != %s: %w" ,
156- fdStr , fdDest , cgroupfsDir , err )
156+ err = fmt .Errorf ("cgroupRootHandle %d unexpectedly opened to %s != %s: %w" ,
157+ cgroupRootHandle . Fd () , fdDest , cgroupfsDir , err )
157158 }
158159 return nil , err
159160 }
0 commit comments