Merge pull request from GHSA-xr7r-f8xq-vfvv · opencontainers/runc@a9833ff (original) (raw)
`@@ -77,16 +77,16 @@ var (
`
77
77
`// TestMode is set to true by unit tests that need "fake" cgroupfs.
`
78
78
`TestMode bool
`
79
79
``
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
`
84
84
`)
`
85
85
``
86
86
`func prepareOpenat2() error {
`
87
87
`prepOnce.Do(func() {
`
88
88
`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,
`
90
90
` })
`
91
91
`if err != nil {
`
92
92
`prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
`
`@@ -97,15 +97,16 @@ func prepareOpenat2() error {
`
97
97
` }
`
98
98
`return
`
99
99
` }
`
``
100
`+
file := os.NewFile(uintptr(fd), cgroupfsDir)
`
``
101
+
100
102
`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 {
`
102
104
`prepErr = &os.PathError{Op: "statfs", Path: cgroupfsDir, Err: err}
`
103
105
`logrus.Warnf("falling back to securejoin: %s", prepErr)
`
104
106
`return
`
105
107
` }
`
106
108
``
107
``
`-
cgroupFd = fd
`
108
``
-
``
109
`+
cgroupRootHandle = file
`
109
110
`resolveFlags = unix.RESOLVE_BENEATH | unix.RESOLVE_NO_MAGICLINKS
`
110
111
`if st.Type == unix.CGROUP2_SUPER_MAGIC {
`
111
112
`// cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks
`
`@@ -132,28 +133,28 @@ func openFile(dir, file string, flags int) (*os.File, error) {
`
132
133
`return openFallback(path, flags, mode)
`
133
134
` }
`
134
135
``
135
``
`-
fd, err := unix.Openat2(cgroupFd, relPath,
`
``
136
`+
fd, err := unix.Openat2(int(cgroupRootHandle.Fd()), relPath,
`
136
137
`&unix.OpenHow{
`
137
138
`Resolve: resolveFlags,
`
138
139
`Flags: uint64(flags) | unix.O_CLOEXEC,
`
139
140
`Mode: uint64(mode),
`
140
141
` })
`
141
142
`if err != nil {
`
142
143
`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
`
144
145
`// (happens when this package is incorrectly used
`
145
146
`// across the chroot/pivot_root/mntns boundary, or
`
146
147
`// when /sys/fs/cgroup is remounted).
`
147
148
`//
`
148
149
`// 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()))
`
151
152
`fdDest, _ := os.Readlink("/proc/self/fd/" + fdStr)
`
152
153
`if fdDest != cgroupfsDir {
`
153
``
`-
// Wrap the error so it is clear that cgroupFd
`
``
154
`+
// Wrap the error so it is clear that cgroupRootHandle
`
154
155
`// 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)
`
157
158
` }
`
158
159
`return nil, err
`
159
160
` }
`