Merge pull request #122552 from yankay/runc/update-to-1.1.11
Bump runc to v1.1.11
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -53,7 +53,7 @@ require (
 | 
				
			|||||||
	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
 | 
						github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
 | 
				
			||||||
	github.com/onsi/ginkgo/v2 v2.13.2
 | 
						github.com/onsi/ginkgo/v2 v2.13.2
 | 
				
			||||||
	github.com/onsi/gomega v1.30.0
 | 
						github.com/onsi/gomega v1.30.0
 | 
				
			||||||
	github.com/opencontainers/runc v1.1.10
 | 
						github.com/opencontainers/runc v1.1.11
 | 
				
			||||||
	github.com/opencontainers/selinux v1.11.0
 | 
						github.com/opencontainers/selinux v1.11.0
 | 
				
			||||||
	github.com/pkg/errors v0.9.1
 | 
						github.com/pkg/errors v0.9.1
 | 
				
			||||||
	github.com/pmezard/go-difflib v1.0.0
 | 
						github.com/pmezard/go-difflib v1.0.0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							@@ -659,8 +659,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
 | 
				
			|||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 | 
					github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 | 
				
			||||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
 | 
					github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
 | 
				
			||||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 | 
					github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 | 
				
			||||||
github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40=
 | 
					github.com/opencontainers/runc v1.1.11 h1:9LjxyVlE0BPMRP2wuQDRlHV4941Jp9rc3F0+YKimopA=
 | 
				
			||||||
github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M=
 | 
					github.com/opencontainers/runc v1.1.11/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
 | 
				
			||||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 | 
					github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 | 
				
			||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 | 
					github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 | 
				
			||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R5M2qXZiK/mWPMT4VldCOiSL9HIAMuxQZWdG0CSM5+4=
 | 
					github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R5M2qXZiK/mWPMT4VldCOiSL9HIAMuxQZWdG0CSM5+4=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -170,6 +170,10 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	stats.MemoryStats.SwapUsage = swapUsage
 | 
						stats.MemoryStats.SwapUsage = swapUsage
 | 
				
			||||||
 | 
						stats.MemoryStats.SwapOnlyUsage = cgroups.MemoryData{
 | 
				
			||||||
 | 
							Usage:   swapUsage.Usage - memoryUsage.Usage,
 | 
				
			||||||
 | 
							Failcnt: swapUsage.Failcnt - memoryUsage.Failcnt,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	kernelUsage, err := getMemoryData(path, "kmem")
 | 
						kernelUsage, err := getMemoryData(path, "kmem")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -100,7 +100,7 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
 | 
				
			|||||||
	memoryUsage, err := getMemoryDataV2(dirPath, "")
 | 
						memoryUsage, err := getMemoryDataV2(dirPath, "")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if errors.Is(err, unix.ENOENT) && dirPath == UnifiedMountpoint {
 | 
							if errors.Is(err, unix.ENOENT) && dirPath == UnifiedMountpoint {
 | 
				
			||||||
			// The root cgroup does not have memory.{current,max}
 | 
								// The root cgroup does not have memory.{current,max,peak}
 | 
				
			||||||
			// so emulate those using data from /proc/meminfo and
 | 
								// so emulate those using data from /proc/meminfo and
 | 
				
			||||||
			// /sys/fs/cgroup/memory.stat
 | 
								// /sys/fs/cgroup/memory.stat
 | 
				
			||||||
			return rootStatsFromMeminfo(stats)
 | 
								return rootStatsFromMeminfo(stats)
 | 
				
			||||||
@@ -108,10 +108,12 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	stats.MemoryStats.Usage = memoryUsage
 | 
						stats.MemoryStats.Usage = memoryUsage
 | 
				
			||||||
	swapUsage, err := getMemoryDataV2(dirPath, "swap")
 | 
						swapOnlyUsage, err := getMemoryDataV2(dirPath, "swap")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						stats.MemoryStats.SwapOnlyUsage = swapOnlyUsage
 | 
				
			||||||
 | 
						swapUsage := swapOnlyUsage
 | 
				
			||||||
	// As cgroup v1 reports SwapUsage values as mem+swap combined,
 | 
						// As cgroup v1 reports SwapUsage values as mem+swap combined,
 | 
				
			||||||
	// while in cgroup v2 swap values do not include memory,
 | 
						// while in cgroup v2 swap values do not include memory,
 | 
				
			||||||
	// report combined mem+swap for v1 compatibility.
 | 
						// report combined mem+swap for v1 compatibility.
 | 
				
			||||||
@@ -119,6 +121,9 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
 | 
				
			|||||||
	if swapUsage.Limit != math.MaxUint64 {
 | 
						if swapUsage.Limit != math.MaxUint64 {
 | 
				
			||||||
		swapUsage.Limit += memoryUsage.Limit
 | 
							swapUsage.Limit += memoryUsage.Limit
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// The `MaxUsage` of mem+swap cannot simply combine mem with
 | 
				
			||||||
 | 
						// swap. So set it to 0 for v1 compatibility.
 | 
				
			||||||
 | 
						swapUsage.MaxUsage = 0
 | 
				
			||||||
	stats.MemoryStats.SwapUsage = swapUsage
 | 
						stats.MemoryStats.SwapUsage = swapUsage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -133,6 +138,7 @@ func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	usage := moduleName + ".current"
 | 
						usage := moduleName + ".current"
 | 
				
			||||||
	limit := moduleName + ".max"
 | 
						limit := moduleName + ".max"
 | 
				
			||||||
 | 
						maxUsage := moduleName + ".peak"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	value, err := fscommon.GetCgroupParamUint(path, usage)
 | 
						value, err := fscommon.GetCgroupParamUint(path, usage)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -152,6 +158,14 @@ func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	memoryData.Limit = value
 | 
						memoryData.Limit = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// `memory.peak` since kernel 5.19
 | 
				
			||||||
 | 
						// `memory.swap.peak` since kernel 6.5
 | 
				
			||||||
 | 
						value, err = fscommon.GetCgroupParamUint(path, maxUsage)
 | 
				
			||||||
 | 
						if err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
 | 
							return cgroups.MemoryData{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						memoryData.MaxUsage = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return memoryData, nil
 | 
						return memoryData, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -78,6 +78,8 @@ type MemoryStats struct {
 | 
				
			|||||||
	Usage MemoryData `json:"usage,omitempty"`
 | 
						Usage MemoryData `json:"usage,omitempty"`
 | 
				
			||||||
	// usage of memory + swap
 | 
						// usage of memory + swap
 | 
				
			||||||
	SwapUsage MemoryData `json:"swap_usage,omitempty"`
 | 
						SwapUsage MemoryData `json:"swap_usage,omitempty"`
 | 
				
			||||||
 | 
						// usage of swap only
 | 
				
			||||||
 | 
						SwapOnlyUsage MemoryData `json:"swap_only_usage,omitempty"`
 | 
				
			||||||
	// usage of kernel memory
 | 
						// usage of kernel memory
 | 
				
			||||||
	KernelUsage MemoryData `json:"kernel_usage,omitempty"`
 | 
						KernelUsage MemoryData `json:"kernel_usage,omitempty"`
 | 
				
			||||||
	// usage of kernel TCP memory
 | 
						// usage of kernel TCP memory
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -21,9 +21,9 @@ type Rlimit struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// IDMap represents UID/GID Mappings for User Namespaces.
 | 
					// IDMap represents UID/GID Mappings for User Namespaces.
 | 
				
			||||||
type IDMap struct {
 | 
					type IDMap struct {
 | 
				
			||||||
	ContainerID int `json:"container_id"`
 | 
						ContainerID int64 `json:"container_id"`
 | 
				
			||||||
	HostID      int `json:"host_id"`
 | 
						HostID      int64 `json:"host_id"`
 | 
				
			||||||
	Size        int `json:"size"`
 | 
						Size        int64 `json:"size"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Seccomp represents syscall restrictions
 | 
					// Seccomp represents syscall restrictions
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/config_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/config_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,10 @@
 | 
				
			|||||||
package configs
 | 
					package configs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "errors"
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	errNoUIDMap   = errors.New("User namespaces enabled, but no uid mappings found.")
 | 
						errNoUIDMap   = errors.New("User namespaces enabled, but no uid mappings found.")
 | 
				
			||||||
@@ -16,11 +20,18 @@ func (c Config) HostUID(containerId int) (int, error) {
 | 
				
			|||||||
		if c.UidMappings == nil {
 | 
							if c.UidMappings == nil {
 | 
				
			||||||
			return -1, errNoUIDMap
 | 
								return -1, errNoUIDMap
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		id, found := c.hostIDFromMapping(containerId, c.UidMappings)
 | 
							id, found := c.hostIDFromMapping(int64(containerId), c.UidMappings)
 | 
				
			||||||
		if !found {
 | 
							if !found {
 | 
				
			||||||
			return -1, errNoUserMap
 | 
								return -1, errNoUserMap
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return id, nil
 | 
							// If we are a 32-bit binary running on a 64-bit system, it's possible
 | 
				
			||||||
 | 
							// the mapped user is too large to store in an int, which means we
 | 
				
			||||||
 | 
							// cannot do the mapping. We can't just return an int64, because
 | 
				
			||||||
 | 
							// os.Setuid() takes an int.
 | 
				
			||||||
 | 
							if id > math.MaxInt {
 | 
				
			||||||
 | 
								return -1, fmt.Errorf("mapping for uid %d (host id %d) is larger than native integer size (%d)", containerId, id, math.MaxInt)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return int(id), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Return unchanged id.
 | 
						// Return unchanged id.
 | 
				
			||||||
	return containerId, nil
 | 
						return containerId, nil
 | 
				
			||||||
@@ -39,11 +50,18 @@ func (c Config) HostGID(containerId int) (int, error) {
 | 
				
			|||||||
		if c.GidMappings == nil {
 | 
							if c.GidMappings == nil {
 | 
				
			||||||
			return -1, errNoGIDMap
 | 
								return -1, errNoGIDMap
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		id, found := c.hostIDFromMapping(containerId, c.GidMappings)
 | 
							id, found := c.hostIDFromMapping(int64(containerId), c.GidMappings)
 | 
				
			||||||
		if !found {
 | 
							if !found {
 | 
				
			||||||
			return -1, errNoGroupMap
 | 
								return -1, errNoGroupMap
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return id, nil
 | 
							// If we are a 32-bit binary running on a 64-bit system, it's possible
 | 
				
			||||||
 | 
							// the mapped user is too large to store in an int, which means we
 | 
				
			||||||
 | 
							// cannot do the mapping. We can't just return an int64, because
 | 
				
			||||||
 | 
							// os.Setgid() takes an int.
 | 
				
			||||||
 | 
							if id > math.MaxInt {
 | 
				
			||||||
 | 
								return -1, fmt.Errorf("mapping for gid %d (host id %d) is larger than native integer size (%d)", containerId, id, math.MaxInt)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return int(id), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Return unchanged id.
 | 
						// Return unchanged id.
 | 
				
			||||||
	return containerId, nil
 | 
						return containerId, nil
 | 
				
			||||||
@@ -57,7 +75,7 @@ func (c Config) HostRootGID() (int, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Utility function that gets a host ID for a container ID from user namespace map
 | 
					// Utility function that gets a host ID for a container ID from user namespace map
 | 
				
			||||||
// if that ID is present in the map.
 | 
					// if that ID is present in the map.
 | 
				
			||||||
func (c Config) hostIDFromMapping(containerID int, uMap []IDMap) (int, bool) {
 | 
					func (c Config) hostIDFromMapping(containerID int64, uMap []IDMap) (int64, bool) {
 | 
				
			||||||
	for _, m := range uMap {
 | 
						for _, m := range uMap {
 | 
				
			||||||
		if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
 | 
							if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
 | 
				
			||||||
			hostID := m.HostID + (containerID - m.ContainerID)
 | 
								hostID := m.HostID + (containerID - m.ContainerID)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -28,25 +28,18 @@ func (v *ConfigValidator) rootlessEUID(config *configs.Config) error {
 | 
				
			|||||||
	return nil
 | 
						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 {
 | 
					func rootlessEUIDMappings(config *configs.Config) error {
 | 
				
			||||||
	if !config.Namespaces.Contains(configs.NEWUSER) {
 | 
						if !config.Namespaces.Contains(configs.NEWUSER) {
 | 
				
			||||||
		return errors.New("rootless container requires user namespaces")
 | 
							return errors.New("rootless container requires user namespaces")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// We only require mappings if we are not joining another userns.
 | 
				
			||||||
	if len(config.UidMappings) == 0 {
 | 
						if path := config.Namespaces.PathOf(configs.NEWUSER); path == "" {
 | 
				
			||||||
		return errors.New("rootless containers requires at least one UID mapping")
 | 
							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")
 | 
							if len(config.GidMappings) == 0 {
 | 
				
			||||||
 | 
								return errors.New("rootless containers requires at least one GID mapping")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -70,8 +63,8 @@ func rootlessEUIDMount(config *configs.Config) error {
 | 
				
			|||||||
					// Ignore unknown mount options.
 | 
										// Ignore unknown mount options.
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if !hasIDMapping(uid, config.UidMappings) {
 | 
									if _, err := config.HostUID(uid); err != nil {
 | 
				
			||||||
					return errors.New("cannot specify uid= mount options for unmapped uid in rootless containers")
 | 
										return fmt.Errorf("cannot specify uid=%d mount option for rootless container: %w", uid, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,8 +75,8 @@ func rootlessEUIDMount(config *configs.Config) error {
 | 
				
			|||||||
					// Ignore unknown mount options.
 | 
										// Ignore unknown mount options.
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if !hasIDMapping(gid, config.GidMappings) {
 | 
									if _, err := config.HostGID(gid); err != nil {
 | 
				
			||||||
					return errors.New("cannot specify gid= mount options for unmapped gid in rootless containers")
 | 
										return fmt.Errorf("cannot specify gid=%d mount option for rootless container: %w", gid, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -109,11 +109,19 @@ func (v *ConfigValidator) security(config *configs.Config) error {
 | 
				
			|||||||
func (v *ConfigValidator) usernamespace(config *configs.Config) error {
 | 
					func (v *ConfigValidator) usernamespace(config *configs.Config) error {
 | 
				
			||||||
	if config.Namespaces.Contains(configs.NEWUSER) {
 | 
						if config.Namespaces.Contains(configs.NEWUSER) {
 | 
				
			||||||
		if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) {
 | 
							if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) {
 | 
				
			||||||
			return errors.New("USER namespaces aren't enabled in the kernel")
 | 
								return errors.New("user namespaces aren't enabled in the kernel")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							hasPath := config.Namespaces.PathOf(configs.NEWUSER) != ""
 | 
				
			||||||
 | 
							hasMappings := config.UidMappings != nil || config.GidMappings != nil
 | 
				
			||||||
 | 
							if !hasPath && !hasMappings {
 | 
				
			||||||
 | 
								return errors.New("user namespaces enabled, but no namespace path to join nor mappings to apply specified")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// The hasPath && hasMappings validation case is handled in specconv --
 | 
				
			||||||
 | 
							// we cache the mappings in Config during specconv in the hasPath case,
 | 
				
			||||||
 | 
							// so we cannot do that validation here.
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if config.UidMappings != nil || config.GidMappings != nil {
 | 
							if config.UidMappings != nil || config.GidMappings != nil {
 | 
				
			||||||
			return errors.New("User namespace mappings specified, but USER namespace isn't enabled in the config")
 | 
								return errors.New("user namespace mappings specified, but user namespace isn't enabled in the config")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2268,7 +2268,7 @@ func ignoreTerminateErrors(err error) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func requiresRootOrMappingTool(c *configs.Config) bool {
 | 
					func requiresRootOrMappingTool(c *configs.Config) bool {
 | 
				
			||||||
	gidMap := []configs.IDMap{
 | 
						gidMap := []configs.IDMap{
 | 
				
			||||||
		{ContainerID: 0, HostID: os.Getegid(), Size: 1},
 | 
							{ContainerID: 0, HostID: int64(os.Getegid()), Size: 1},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return !reflect.DeepEqual(c.GidMappings, gidMap)
 | 
						return !reflect.DeepEqual(c.GidMappings, gidMap)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								vendor/github.com/opencontainers/runc/libcontainer/userns/userns_maps.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/github.com/opencontainers/runc/libcontainer/userns/userns_maps.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <sched.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * All of the code here is run inside an aync-signal-safe context, so we need
 | 
				
			||||||
 | 
					 * to be careful to not call any functions that could cause issues. In theory,
 | 
				
			||||||
 | 
					 * since we are a Go program, there are fewer restrictions in practice, it's
 | 
				
			||||||
 | 
					 * better to be safe than sorry.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The only exception is exit, which we need to call to make sure we don't
 | 
				
			||||||
 | 
					 * return into runc.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bail(int pipefd, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(args, fmt);
 | 
				
			||||||
 | 
						vdprintf(pipefd, fmt, args);
 | 
				
			||||||
 | 
						va_end(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int spawn_userns_cat(char *userns_path, char *path, int outfd, int errfd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char buffer[4096] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pid_t child = fork();
 | 
				
			||||||
 | 
						if (child != 0)
 | 
				
			||||||
 | 
							return child;
 | 
				
			||||||
 | 
						/* in child */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Join the target userns. */
 | 
				
			||||||
 | 
						int nsfd = open(userns_path, O_RDONLY);
 | 
				
			||||||
 | 
						if (nsfd < 0)
 | 
				
			||||||
 | 
							bail(errfd, "open userns path %s failed: %m", userns_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int err = setns(nsfd, CLONE_NEWUSER);
 | 
				
			||||||
 | 
						if (err < 0)
 | 
				
			||||||
 | 
							bail(errfd, "setns %s failed: %m", userns_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close(nsfd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Pipe the requested file contents. */
 | 
				
			||||||
 | 
						int fd = open(path, O_RDONLY);
 | 
				
			||||||
 | 
						if (fd < 0)
 | 
				
			||||||
 | 
							bail(errfd, "open %s in userns %s failed: %m", path, userns_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int nread, ntotal = 0;
 | 
				
			||||||
 | 
						while ((nread = read(fd, buffer, sizeof(buffer))) != 0) {
 | 
				
			||||||
 | 
							if (nread < 0)
 | 
				
			||||||
 | 
								bail(errfd, "read bytes from %s failed (after %d total bytes read): %m", path, ntotal);
 | 
				
			||||||
 | 
							ntotal += nread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int nwritten = 0;
 | 
				
			||||||
 | 
							while (nwritten < nread) {
 | 
				
			||||||
 | 
								int n = write(outfd, buffer, nread - nwritten);
 | 
				
			||||||
 | 
								if (n < 0)
 | 
				
			||||||
 | 
									bail(errfd, "write %d bytes from %s failed (after %d bytes written): %m",
 | 
				
			||||||
 | 
									     nread - nwritten, path, nwritten);
 | 
				
			||||||
 | 
								nwritten += n;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (nread != nwritten)
 | 
				
			||||||
 | 
								bail(errfd, "mismatch for bytes read and written: %d read != %d written", nread, nwritten);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close(fd);
 | 
				
			||||||
 | 
						close(outfd);
 | 
				
			||||||
 | 
						close(errfd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We must exit here, otherwise we would return into a forked runc. */
 | 
				
			||||||
 | 
						exit(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										186
									
								
								vendor/github.com/opencontainers/runc/libcontainer/userns/userns_maps_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								vendor/github.com/opencontainers/runc/libcontainer/userns/userns_maps_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
				
			|||||||
 | 
					//go:build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package userns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"unsafe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/opencontainers/runc/libcontainer/configs"
 | 
				
			||||||
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					extern int spawn_userns_cat(char *userns_path, char *path, int outfd, int errfd);
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					import "C"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseIdmapData(data []byte) (ms []configs.IDMap, err error) {
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(bytes.NewReader(data))
 | 
				
			||||||
 | 
						for scanner.Scan() {
 | 
				
			||||||
 | 
							var m configs.IDMap
 | 
				
			||||||
 | 
							line := scanner.Text()
 | 
				
			||||||
 | 
							if _, err := fmt.Sscanf(line, "%d %d %d", &m.ContainerID, &m.HostID, &m.Size); err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("parsing id map failed: invalid format in line %q: %w", line, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ms = append(ms, m)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := scanner.Err(); err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("parsing id map failed: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ms, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Do something equivalent to nsenter --user=<nsPath> cat <path>, but more
 | 
				
			||||||
 | 
					// efficiently. Returns the contents of the requested file from within the user
 | 
				
			||||||
 | 
					// namespace.
 | 
				
			||||||
 | 
					func spawnUserNamespaceCat(nsPath string, path string) ([]byte, error) {
 | 
				
			||||||
 | 
						rdr, wtr, err := os.Pipe()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("create pipe for userns spawn failed: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rdr.Close()
 | 
				
			||||||
 | 
						defer wtr.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errRdr, errWtr, err := os.Pipe()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("create error pipe for userns spawn failed: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer errRdr.Close()
 | 
				
			||||||
 | 
						defer errWtr.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cNsPath := C.CString(nsPath)
 | 
				
			||||||
 | 
						defer C.free(unsafe.Pointer(cNsPath))
 | 
				
			||||||
 | 
						cPath := C.CString(path)
 | 
				
			||||||
 | 
						defer C.free(unsafe.Pointer(cPath))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						childPid := C.spawn_userns_cat(cNsPath, cPath, C.int(wtr.Fd()), C.int(errWtr.Fd()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if childPid < 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("failed to spawn fork for userns")
 | 
				
			||||||
 | 
						} else if childPid == 0 {
 | 
				
			||||||
 | 
							// this should never happen
 | 
				
			||||||
 | 
							panic("runc executing inside fork child -- unsafe state!")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We are in the parent -- close the write end of the pipe before reading.
 | 
				
			||||||
 | 
						wtr.Close()
 | 
				
			||||||
 | 
						output, err := io.ReadAll(rdr)
 | 
				
			||||||
 | 
						rdr.Close()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("reading from userns spawn failed: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ditto for the error pipe.
 | 
				
			||||||
 | 
						errWtr.Close()
 | 
				
			||||||
 | 
						errOutput, err := io.ReadAll(errRdr)
 | 
				
			||||||
 | 
						errRdr.Close()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("reading from userns spawn error pipe failed: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						errOutput = bytes.TrimSpace(errOutput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Clean up the child.
 | 
				
			||||||
 | 
						child, err := os.FindProcess(int(childPid))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("could not find userns spawn process: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						state, err := child.Wait()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("failed to wait for userns spawn process: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !state.Success() {
 | 
				
			||||||
 | 
							errStr := string(errOutput)
 | 
				
			||||||
 | 
							if errStr == "" {
 | 
				
			||||||
 | 
								errStr = fmt.Sprintf("unknown error (status code %d)", state.ExitCode())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("userns spawn: %s", errStr)
 | 
				
			||||||
 | 
						} else if len(errOutput) > 0 {
 | 
				
			||||||
 | 
							// We can just ignore weird output in the error pipe if the process
 | 
				
			||||||
 | 
							// didn't bail(), but for completeness output for debugging.
 | 
				
			||||||
 | 
							logrus.Debugf("userns spawn succeeded but unexpected error message found: %s", string(errOutput))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// The subprocess succeeded, return whatever it wrote to the pipe.
 | 
				
			||||||
 | 
						return output, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetUserNamespaceMappings(nsPath string) (uidMap, gidMap []configs.IDMap, err error) {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							pid         int
 | 
				
			||||||
 | 
							extra       rune
 | 
				
			||||||
 | 
							tryFastPath bool
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// nsPath is usually of the form /proc/<pid>/ns/user, which means that we
 | 
				
			||||||
 | 
						// already have a pid that is part of the user namespace and thus we can
 | 
				
			||||||
 | 
						// just use the pid to read from /proc/<pid>/*id_map.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Note that Sscanf doesn't consume the whole input, so we check for any
 | 
				
			||||||
 | 
						// trailing data with %c. That way, we can be sure the pattern matched
 | 
				
			||||||
 | 
						// /proc/$pid/ns/user _exactly_ iff n === 1.
 | 
				
			||||||
 | 
						if n, _ := fmt.Sscanf(nsPath, "/proc/%d/ns/user%c", &pid, &extra); n == 1 {
 | 
				
			||||||
 | 
							tryFastPath = pid > 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, mapType := range []struct {
 | 
				
			||||||
 | 
							name  string
 | 
				
			||||||
 | 
							idMap *[]configs.IDMap
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"uid_map", &uidMap},
 | 
				
			||||||
 | 
							{"gid_map", &gidMap},
 | 
				
			||||||
 | 
						} {
 | 
				
			||||||
 | 
							var mapData []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if tryFastPath {
 | 
				
			||||||
 | 
								path := fmt.Sprintf("/proc/%d/%s", pid, mapType.name)
 | 
				
			||||||
 | 
								data, err := os.ReadFile(path)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									// Do not error out here -- we need to try the slow path if the
 | 
				
			||||||
 | 
									// fast path failed.
 | 
				
			||||||
 | 
									logrus.Debugf("failed to use fast path to read %s from userns %s (error: %s), falling back to slow userns-join path", mapType.name, nsPath, err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									mapData = data
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								logrus.Debugf("cannot use fast path to read %s from userns %s, falling back to slow userns-join path", mapType.name, nsPath)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if mapData == nil {
 | 
				
			||||||
 | 
								// We have to actually join the namespace if we cannot take the
 | 
				
			||||||
 | 
								// fast path. The path is resolved with respect to the child
 | 
				
			||||||
 | 
								// process, so just use /proc/self.
 | 
				
			||||||
 | 
								data, err := spawnUserNamespaceCat(nsPath, "/proc/self/"+mapType.name)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								mapData = data
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							idMap, err := parseIdmapData(mapData)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, nil, fmt.Errorf("failed to parse %s of userns %s: %w", mapType.name, nsPath, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							*mapType.idMap = idMap
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return uidMap, gidMap, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsSameMapping returns whether or not the two id mappings are the same. Note
 | 
				
			||||||
 | 
					// that if the order of the mappings is different, or a mapping has been split,
 | 
				
			||||||
 | 
					// the mappings will be considered different.
 | 
				
			||||||
 | 
					func IsSameMapping(a, b []configs.IDMap) bool {
 | 
				
			||||||
 | 
						if len(a) != len(b) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for idx := range a {
 | 
				
			||||||
 | 
							if a[idx] != b[idx] {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -591,7 +591,7 @@ github.com/onsi/gomega/types
 | 
				
			|||||||
# github.com/opencontainers/go-digest v1.0.0
 | 
					# github.com/opencontainers/go-digest v1.0.0
 | 
				
			||||||
## explicit; go 1.13
 | 
					## explicit; go 1.13
 | 
				
			||||||
github.com/opencontainers/go-digest
 | 
					github.com/opencontainers/go-digest
 | 
				
			||||||
# github.com/opencontainers/runc v1.1.10
 | 
					# github.com/opencontainers/runc v1.1.11
 | 
				
			||||||
## explicit; go 1.17
 | 
					## explicit; go 1.17
 | 
				
			||||||
github.com/opencontainers/runc/libcontainer
 | 
					github.com/opencontainers/runc/libcontainer
 | 
				
			||||||
github.com/opencontainers/runc/libcontainer/apparmor
 | 
					github.com/opencontainers/runc/libcontainer/apparmor
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user