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

` }

`