Repository: opencontainers/runc
File: libcontainer/specconv/spec_linux.go (Go)

Code before:
		}
	}

	return dedupedAllowDevs, nil
}

func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
	if spec.Linux != nil {
		config.UIDMappings = toConfigIDMap(spec.Linux.UIDMappings)
		config.GIDMappings = toConfigIDMap(spec.Linux.GIDMappings)
	}
	if path := config.Namespaces.PathOf(configs.NEWUSER); path != "" {
		// Cache the current userns mappings in our configuration, so that we
		// can calculate uid and gid mappings within runc. These mappings are
		// never used for configuring the container if the path is set.
		uidMap, gidMap, err := userns.GetUserNamespaceMappings(path)
		if err != nil {
			return fmt.Errorf("failed to cache mappings for userns: %w", err)
		}
		// We cannot allow uid or gid mappings to be set if we are also asked
		// to join a userns.
		if config.UIDMappings != nil || config.GIDMappings != nil {
			// FIXME: It turns out that containerd and CRIO pass both a userns
			// path and the mappings of the namespace in the same config.json.
			// Such a configuration is technically not valid according to
			// runtime-spec, but we previously ignored this behaviour and thus
			// cannot regress it. But we also don't want to produce broken
			// behaviour if the mapping doesn't match the userns. So (for now)
			// we output a warning if the actual userns mappings match the
			// configuration, otherwise we return an error.
			if !userns.IsSameMapping(uidMap, config.UIDMappings) ||
				!userns.IsSameMapping(gidMap, config.GIDMappings) {
				return errors.New("user namespaces enabled, but both namespace path and non-matching mapping specified -- you may only provide one")
			}
			logrus.Warnf("config.json has both a userns path to join and a matching userns mapping specified -- you may only provide one. runc 1.3 and later will return an error with this configuration.")
		}

		config.UIDMappings = uidMap
		config.GIDMappings = gidMap
		logrus.WithFields(logrus.Fields{
			"uid_map": uidMap,
			"gid_map": gidMap,
		}).Debugf("config uses path-based userns configuration -- current uid and gid mappings cached")
	}
	rootUID, err := config.HostRootUID()
	if err != nil {
		return err
	}
	rootGID, err := config.HostRootGID()
	if err != nil {
		return err

Review comment (suggestion):
As I was saying in the issue, I'm not sure we just ignored but if it wasn't *required* to do it in order to join an existing userns with a path param. I think we might have forced users to specify both.

Code after:
		}
	}

	return dedupedAllowDevs, nil
}

func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
	if spec.Linux != nil {
		config.UIDMappings = toConfigIDMap(spec.Linux.UIDMappings)
		config.GIDMappings = toConfigIDMap(spec.Linux.GIDMappings)
	}
	if path := config.Namespaces.PathOf(configs.NEWUSER); path != "" {
		// Cache the current userns mappings in our configuration, so that we
		// can calculate uid and gid mappings within runc. These mappings are
		// never used for configuring the container if the path is set.
		uidMap, gidMap, err := userns.GetUserNamespaceMappings(path)
		if err != nil {
			return fmt.Errorf("failed to cache mappings for userns: %w", err)
		}
		// We cannot allow uid or gid mappings to be set if we are also asked
		// to join a userns.
		if config.UIDMappings != nil || config.GIDMappings != nil {
			// FIXME: It turns out that containerd and CRIO pass both a userns
			// path and the mappings of the namespace in the same config.json.
			// Such a configuration is technically not valid, but we used to
			// require mappings be specified, and thus users worked around our
			// bug -- so we can't regress it at the moment. But we also don't
			// want to produce broken behaviour if the mapping doesn't match
			// the userns. So (for now) we output a warning if the actual
			// userns mappings match the configuration, otherwise we return an
			// error.
			if !userns.IsSameMapping(uidMap, config.UIDMappings) ||
				!userns.IsSameMapping(gidMap, config.GIDMappings) {
				return errors.New("user namespaces enabled, but both namespace path and non-matching mapping specified -- you may only provide one")
			}
			logrus.Warnf("config.json has both a userns path to join and a matching userns mapping specified -- you may only provide one. Future versions of runc may return an error with this configuration, please report a bug on <https://github.com/opencontainers/runc> if you see this warning and cannot update your configuration.")
		}

		config.UIDMappings = uidMap
		config.GIDMappings = gidMap
		logrus.WithFields(logrus.Fields{
			"uid_map": uidMap,
			"gid_map": gidMap,
		}).Debugf("config uses path-based userns configuration -- current uid and gid mappings cached")
	}
	rootUID, err := config.HostRootUID()
	if err != nil {
		return err
	}
	rootGID, err := config.HostRootGID()
	if err != nil {