MCPcopy
hub / github.com/opencontainers/runc / mountFd

Function mountFd

libcontainer/mount_linux.go:253–344  ·  view source on GitHub ↗

mountFd creates a "mount source fd" (either through open_tree(2) or just open(O_PATH)) based on the provided configuration. This function must be called from within the container's mount namespace. In the case of idmapped mount configurations, the returned mount source will be an open_tree(2) file

(nsHandles *userns.Handles, m *configs.Mount)

Source from the content-addressed store, hash-verified

251//
252// This helper is only intended to be used by goCreateMountSources.
253func mountFd(nsHandles *userns.Handles, m *configs.Mount) (_ *mountSource, retErr error) {
254 if !m.IsBind() {
255 return nil, errors.New("new mount api: only bind-mounts are supported")
256 }
257 if nsHandles == nil {
258 nsHandles = new(userns.Handles)
259 defer nsHandles.Release()
260 }
261
262 var mountFile *os.File
263 var sourceType mountSourceType
264 defer func() {
265 if retErr != nil && mountFile != nil {
266 mountFile.Close()
267 }
268 }()
269
270 // Ideally, we would use OPEN_TREE_CLONE for everything, because we can
271 // be sure that the file descriptor cannot be used to escape outside of
272 // the mount root. Unfortunately, OPEN_TREE_CLONE is far more expensive
273 // than open(2) because it requires doing mounts inside a new anonymous
274 // mount namespace. So we use open(2) for standard bind-mounts, and
275 // OPEN_TREE_CLONE when we need to set mount attributes here.
276 //
277 // While passing open(2)'d paths from the host rootfs isn't exactly the
278 // safest thing in the world, the files will not survive across
279 // execve(2) and "runc init" is non-dumpable so it should not be
280 // possible for a malicious container process to gain access to the
281 // file descriptors. We also don't do any of this for "runc exec",
282 // lessening the risk even further.
283 if m.IsIDMapped() {
284 flags := uint(unix.OPEN_TREE_CLONE | unix.OPEN_TREE_CLOEXEC)
285 if m.Flags&unix.MS_REC == unix.MS_REC {
286 flags |= unix.AT_RECURSIVE
287 }
288 fd, err := unix.OpenTree(unix.AT_FDCWD, m.Source, flags)
289 if err != nil {
290 return nil, &os.PathError{Op: "open_tree(OPEN_TREE_CLONE)", Path: m.Source, Err: err}
291 }
292 mountFile = os.NewFile(uintptr(fd), m.Source)
293 sourceType = mountSourceOpenTree
294
295 // Configure the id mapping.
296 var usernsFile *os.File
297 if m.IDMapping.UserNSPath == "" {
298 usernsFile, err = nsHandles.Get(userns.Mapping{
299 UIDMappings: m.IDMapping.UIDMappings,
300 GIDMappings: m.IDMapping.GIDMappings,
301 })
302 if err != nil {
303 return nil, fmt.Errorf("failed to create userns for %s id-mapping: %w", m.Source, err)
304 }
305 } else {
306 usernsFile, err = os.Open(m.IDMapping.UserNSPath)
307 if err != nil {
308 return nil, fmt.Errorf("failed to open existing userns for %s id-mapping: %w", m.Source, err)
309 }
310 }

Callers 1

goCreateMountSourcesMethod · 0.85

Calls 5

ReleaseMethod · 0.80
IsIDMappedMethod · 0.80
GetMethod · 0.80
IsBindMethod · 0.45
CloseMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…