Repository: opencontainers/runc
File: libcontainer/configs/validate/validator.go (Go)

Code before:
				return fmt.Errorf("invalid netns path: %w", hostnetErr)
			}
			if hostnet {
				return fmt.Errorf("sysctl %q not allowed in host network namespace", s)
			}
			continue
		}
		if config.Namespaces.Contains(configs.NEWUTS) {
			switch s {
			case "kernel.domainname":
				// This is namespaced and there's no explicit OCI field for it.
				continue
			case "kernel.hostname":
				// This is namespaced but there's a conflicting (dedicated) OCI field for it.
				return fmt.Errorf("sysctl %q is not allowed as it conflicts with the OCI %q field", s, "hostname")
			}
		}

		if strings.HasPrefix(s, "user.") {
			// while it is technically true that a non-userns
			// container can write to /proc/sys/user on behalf of
			// the init_user_ns, it was not previously supported,
			// and doesn't guarantee that someone else spawns a
			// different container and writes there, changing the
			// values. So let's refuse that for now, until someone
			// needs it.
			if !config.Namespaces.Contains(configs.NEWUSER) {
				return fmt.Errorf("setting ucounts without a user namespace not allowed: %v", s)
			}
			continue
		}

		return fmt.Errorf("sysctl %q is not in a separate kernel namespace", s)
	}

	return nil
}

func intelrdtCheck(config *configs.Config) error {
	if config.IntelRdt != nil {
		if !intelRdt.isEnabled() {
			return fmt.Errorf("intelRdt is specified in config, but Intel RDT is not enabled")
		}

		switch clos := config.IntelRdt.ClosID; {
		case clos == ".", clos == "..", len(clos) > 1 && strings.Contains(clos, "/"):
			return fmt.Errorf("invalid intelRdt.ClosID %q", clos)
		}

		if !intelRdt.isCATEnabled() && config.IntelRdt.L3CacheSchema != "" {
			return errors.New("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled")

Review comment (suggestion):
Well, it's more that this would be adding vectors for container breakouts without a strong need for it.

Yes, `config.json` is meant to be assumed to not be malicious but the past decade of runc CVEs that we've had to deal with makes it clear higher-level runtimes don't really share our view...

I would rework this comment a bit to make it sound less like a back-compat issue, but I don't really mind either way.

Code after:
				return fmt.Errorf("invalid netns path: %w", hostnetErr)
			}
			if hostnet {
				return fmt.Errorf("sysctl %q not allowed in host network namespace", s)
			}
			continue
		}
		if config.Namespaces.Contains(configs.NEWUTS) {
			switch s {
			case "kernel.domainname":
				// This is namespaced and there's no explicit OCI field for it.
				continue
			case "kernel.hostname":
				// This is namespaced but there's a conflicting (dedicated) OCI field for it.
				return fmt.Errorf("sysctl %q is not allowed as it conflicts with the OCI %q field", s, "hostname")
			}
		}

		if strings.HasPrefix(s, "user.") {

			// while it is technically true that a non-userns
			// container can write to /proc/sys/user on behalf of
			// the init_user_ns, it was not previously supported,
			// and doesn't guarantee that someone else spawns a
			// different container and writes there, changing the
			// values. in particular, setting something like
			// max_user_namespaces to non-zero could be a vector to
			// use 0-days where the admin had previously disabled
			// them.
			//
			// additionally, this setting affects other host
			// processes that are not container related.
			//
			// so let's refuse this unless we know for sure it
			// won't touch anything else.
			if !config.Namespaces.Contains(configs.NEWUSER) {
				return fmt.Errorf("setting ucounts without a user namespace not allowed: %v", s)
			}
			continue
		}

		return fmt.Errorf("sysctl %q is not in a separate kernel namespace", s)
	}

	return nil
}

func intelrdtCheck(config *configs.Config) error {
	if config.IntelRdt != nil {
		if !intelRdt.isEnabled() {
			return fmt.Errorf("intelRdt is specified in config, but Intel RDT is not enabled")