mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-17 07:39:22 +00:00
runc rc95 contains a fix for CVE-2021-30465. runc rc94 provides fixes and improvements. One notable change is cgroup manager's Set now accept Resources rather than Cgroup (see https://github.com/opencontainers/runc/pull/2906). Modify the code accordingly. Also update runc dependencies (as hinted by hack/lint-depdendencies.sh): github.com/cilium/ebpf v0.5.0 github.com/containerd/console v1.0.2 github.com/coreos/go-systemd/v22 v22.3.1 github.com/godbus/dbus/v5 v5.0.4 github.com/moby/sys/mountinfo v0.4.1 golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 github.com/google/go-cmp v0.5.4 github.com/kr/pretty v0.2.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package validate
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/configs"
|
|
)
|
|
|
|
// rootlessEUID makes sure that the config can be applied when runc
|
|
// is being executed as a non-root user (euid != 0) in the current user namespace.
|
|
func (v *ConfigValidator) rootlessEUID(config *configs.Config) error {
|
|
if !config.RootlessEUID {
|
|
return nil
|
|
}
|
|
if err := rootlessEUIDMappings(config); err != nil {
|
|
return err
|
|
}
|
|
if err := rootlessEUIDMount(config); err != nil {
|
|
return err
|
|
}
|
|
|
|
// XXX: We currently can't verify the user config at all, because
|
|
// configs.Config doesn't store the user-related configs. So this
|
|
// has to be verified by setupUser() in init_linux.go.
|
|
|
|
return nil
|
|
}
|
|
|
|
func hasIDMapping(id int, mappings []configs.IDMap) bool {
|
|
for _, m := range mappings {
|
|
if id >= m.ContainerID && id < m.ContainerID+m.Size {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func rootlessEUIDMappings(config *configs.Config) error {
|
|
if !config.Namespaces.Contains(configs.NEWUSER) {
|
|
return errors.New("rootless container requires user namespaces")
|
|
}
|
|
|
|
if len(config.UidMappings) == 0 {
|
|
return errors.New("rootless containers requires at least one UID mapping")
|
|
}
|
|
if len(config.GidMappings) == 0 {
|
|
return errors.New("rootless containers requires at least one GID mapping")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// mount verifies that the user isn't trying to set up any mounts they don't have
|
|
// the rights to do. In addition, it makes sure that no mount has a `uid=` or
|
|
// `gid=` option that doesn't resolve to root.
|
|
func rootlessEUIDMount(config *configs.Config) error {
|
|
// XXX: We could whitelist allowed devices at this point, but I'm not
|
|
// convinced that's a good idea. The kernel is the best arbiter of
|
|
// access control.
|
|
|
|
for _, mount := range config.Mounts {
|
|
// Check that the options list doesn't contain any uid= or gid= entries
|
|
// that don't resolve to root.
|
|
for _, opt := range strings.Split(mount.Data, ",") {
|
|
if strings.HasPrefix(opt, "uid=") {
|
|
var uid int
|
|
n, err := fmt.Sscanf(opt, "uid=%d", &uid)
|
|
if n != 1 || err != nil {
|
|
// Ignore unknown mount options.
|
|
continue
|
|
}
|
|
if !hasIDMapping(uid, config.UidMappings) {
|
|
return errors.New("cannot specify uid= mount options for unmapped uid in rootless containers")
|
|
}
|
|
}
|
|
|
|
if strings.HasPrefix(opt, "gid=") {
|
|
var gid int
|
|
n, err := fmt.Sscanf(opt, "gid=%d", &gid)
|
|
if n != 1 || err != nil {
|
|
// Ignore unknown mount options.
|
|
continue
|
|
}
|
|
if !hasIDMapping(gid, config.GidMappings) {
|
|
return errors.New("cannot specify gid= mount options for unmapped gid in rootless containers")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|