vendor: cadvisor v0.38.4
This commit is contained in:
7
vendor/github.com/opencontainers/runc/libcontainer/cgroups/BUILD
generated
vendored
7
vendor/github.com/opencontainers/runc/libcontainer/cgroups/BUILD
generated
vendored
@@ -12,16 +12,17 @@ go_library(
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/opencontainers/runc/libcontainer/cgroups",
|
||||
importpath = "github.com/opencontainers/runc/libcontainer/cgroups",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = select({
|
||||
deps = [
|
||||
"//vendor/github.com/cyphar/filepath-securejoin:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"//vendor/github.com/docker/go-units:go_default_library",
|
||||
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//vendor/github.com/docker/go-units:go_default_library",
|
||||
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go
generated
vendored
@@ -22,12 +22,8 @@ func (s *BlkioGroup) Name() string {
|
||||
return "blkio"
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("blkio")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *BlkioGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -74,10 +70,6 @@ func (s *BlkioGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BlkioGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("blkio"))
|
||||
}
|
||||
|
||||
/*
|
||||
examples:
|
||||
|
||||
|
24
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
generated
vendored
24
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
generated
vendored
@@ -21,17 +21,7 @@ func (s *CpuGroup) Name() string {
|
||||
return "cpu"
|
||||
}
|
||||
|
||||
func (s *CpuGroup) Apply(d *cgroupData) error {
|
||||
// We always want to join the cpu group, to allow fair cpu scheduling
|
||||
// on a container basis
|
||||
path, err := d.path("cpu")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return s.ApplyDir(path, d.config, d.pid)
|
||||
}
|
||||
|
||||
func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error {
|
||||
func (s *CpuGroup) Apply(path string, d *cgroupData) error {
|
||||
// This might happen if we have no cpu cgroup mounted.
|
||||
// Just do nothing and don't fail.
|
||||
if path == "" {
|
||||
@@ -43,12 +33,12 @@ func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error
|
||||
// We should set the real-Time group scheduling settings before moving
|
||||
// in the process because if the process is already in SCHED_RR mode
|
||||
// and no RT bandwidth is set, adding it will fail.
|
||||
if err := s.SetRtSched(path, cgroup); err != nil {
|
||||
if err := s.SetRtSched(path, d.config); err != nil {
|
||||
return err
|
||||
}
|
||||
// because we are not using d.join we need to place the pid into the procs file
|
||||
// unlike the other subsystems
|
||||
return cgroups.WriteCgroupProc(path, pid)
|
||||
// Since we are not using join(), we need to place the pid
|
||||
// into the procs file unlike other subsystems.
|
||||
return cgroups.WriteCgroupProc(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -96,10 +86,6 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return s.SetRtSched(path, cgroup)
|
||||
}
|
||||
|
||||
func (s *CpuGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("cpu"))
|
||||
}
|
||||
|
||||
func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
f, err := os.Open(filepath.Join(path, "cpu.stat"))
|
||||
if err != nil {
|
||||
|
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go
generated
vendored
@@ -40,24 +40,18 @@ func (s *CpuacctGroup) Name() string {
|
||||
return "cpuacct"
|
||||
}
|
||||
|
||||
func (s *CpuacctGroup) Apply(d *cgroupData) error {
|
||||
// we just want to join this group even though we don't set anything
|
||||
if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
func (s *CpuacctGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *CpuacctGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *CpuacctGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("cpuacct"))
|
||||
}
|
||||
|
||||
func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
if !cgroups.PathExists(path) {
|
||||
return nil
|
||||
}
|
||||
userModeUsage, kernelModeUsage, err := getCpuUsageBreakdown(path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
generated
vendored
@@ -23,12 +23,8 @@ func (s *CpusetGroup) Name() string {
|
||||
return "cpuset"
|
||||
}
|
||||
|
||||
func (s *CpusetGroup) Apply(d *cgroupData) error {
|
||||
dir, err := d.path("cpuset")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return s.ApplyDir(dir, d.config, d.pid)
|
||||
func (s *CpusetGroup) Apply(path string, d *cgroupData) error {
|
||||
return s.ApplyDir(path, d.config, d.pid)
|
||||
}
|
||||
|
||||
func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -45,10 +41,6 @@ func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *CpusetGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("cpuset"))
|
||||
}
|
||||
|
||||
func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
generated
vendored
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
generated
vendored
@@ -22,17 +22,16 @@ func (s *DevicesGroup) Name() string {
|
||||
return "devices"
|
||||
}
|
||||
|
||||
func (s *DevicesGroup) Apply(d *cgroupData) error {
|
||||
func (s *DevicesGroup) Apply(path string, d *cgroupData) error {
|
||||
if d.config.SkipDevices {
|
||||
return nil
|
||||
}
|
||||
_, err := d.join("devices")
|
||||
if err != nil {
|
||||
// We will return error even it's `not found` error, devices
|
||||
// cgroup is hard requirement for container's security.
|
||||
return err
|
||||
if path == "" {
|
||||
// Return error here, since devices cgroup
|
||||
// is a hard requirement for container's security.
|
||||
return errSubsystemDoesNotExist
|
||||
}
|
||||
return nil
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func loadEmulator(path string) (*devices.Emulator, error) {
|
||||
@@ -106,10 +105,6 @@ func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DevicesGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("devices"))
|
||||
}
|
||||
|
||||
func (s *DevicesGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go
generated
vendored
@@ -22,12 +22,8 @@ func (s *FreezerGroup) Name() string {
|
||||
return "freezer"
|
||||
}
|
||||
|
||||
func (s *FreezerGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("freezer")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *FreezerGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -61,10 +57,6 @@ func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FreezerGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("freezer"))
|
||||
}
|
||||
|
||||
func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
105
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go
generated
vendored
105
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go
generated
vendored
@@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
subsystemsLegacy = subsystemSet{
|
||||
subsystems = []subsystem{
|
||||
&CpusetGroup{},
|
||||
&DevicesGroup{},
|
||||
&MemoryGroup{},
|
||||
@@ -38,26 +38,13 @@ var (
|
||||
|
||||
var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist")
|
||||
|
||||
type subsystemSet []subsystem
|
||||
|
||||
func (s subsystemSet) Get(name string) (subsystem, error) {
|
||||
for _, ss := range s {
|
||||
if ss.Name() == name {
|
||||
return ss, nil
|
||||
}
|
||||
}
|
||||
return nil, errSubsystemDoesNotExist
|
||||
}
|
||||
|
||||
type subsystem interface {
|
||||
// Name returns the name of the subsystem.
|
||||
Name() string
|
||||
// Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
|
||||
GetStats(path string, stats *cgroups.Stats) error
|
||||
// Removes the cgroup represented by 'cgroupData'.
|
||||
Remove(*cgroupData) error
|
||||
// Creates and joins the cgroup represented by 'cgroupData'.
|
||||
Apply(*cgroupData) error
|
||||
Apply(path string, c *cgroupData) error
|
||||
// Set the cgroup represented by cgroup.
|
||||
Set(path string, cgroup *configs.Cgroup) error
|
||||
}
|
||||
@@ -81,6 +68,56 @@ func NewManager(cg *configs.Cgroup, paths map[string]string, rootless bool) cgro
|
||||
var cgroupRootLock sync.Mutex
|
||||
var cgroupRoot string
|
||||
|
||||
const defaultCgroupRoot = "/sys/fs/cgroup"
|
||||
|
||||
func tryDefaultCgroupRoot() string {
|
||||
var st, pst unix.Stat_t
|
||||
|
||||
// (1) it should be a directory...
|
||||
err := unix.Lstat(defaultCgroupRoot, &st)
|
||||
if err != nil || st.Mode&unix.S_IFDIR == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// (2) ... and a mount point ...
|
||||
err = unix.Lstat(filepath.Dir(defaultCgroupRoot), &pst)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if st.Dev == pst.Dev {
|
||||
// parent dir has the same dev -- not a mount point
|
||||
return ""
|
||||
}
|
||||
|
||||
// (3) ... of 'tmpfs' fs type.
|
||||
var fst unix.Statfs_t
|
||||
err = unix.Statfs(defaultCgroupRoot, &fst)
|
||||
if err != nil || fst.Type != unix.TMPFS_MAGIC {
|
||||
return ""
|
||||
}
|
||||
|
||||
// (4) it should have at least 1 entry ...
|
||||
dir, err := os.Open(defaultCgroupRoot)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
names, err := dir.Readdirnames(1)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if len(names) < 1 {
|
||||
return ""
|
||||
}
|
||||
// ... which is a cgroup mount point.
|
||||
err = unix.Statfs(filepath.Join(defaultCgroupRoot, names[0]), &fst)
|
||||
if err != nil || fst.Type != unix.CGROUP_SUPER_MAGIC {
|
||||
return ""
|
||||
}
|
||||
|
||||
return defaultCgroupRoot
|
||||
}
|
||||
|
||||
// Gets the cgroupRoot.
|
||||
func getCgroupRoot() (string, error) {
|
||||
cgroupRootLock.Lock()
|
||||
@@ -90,6 +127,14 @@ func getCgroupRoot() (string, error) {
|
||||
return cgroupRoot, nil
|
||||
}
|
||||
|
||||
// fast path
|
||||
cgroupRoot = tryDefaultCgroupRoot()
|
||||
if cgroupRoot != "" {
|
||||
return cgroupRoot, nil
|
||||
}
|
||||
|
||||
// slow path: parse mountinfo, find the first mount where fs=cgroup
|
||||
// (e.g. "/sys/fs/cgroup/memory"), use its parent.
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -166,10 +211,6 @@ func isIgnorableError(rootless bool, err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *manager) getSubsystems() subsystemSet {
|
||||
return subsystemsLegacy
|
||||
}
|
||||
|
||||
func (m *manager) Apply(pid int) (err error) {
|
||||
if m.cgroups == nil {
|
||||
return nil
|
||||
@@ -199,7 +240,7 @@ func (m *manager) Apply(pid int) (err error) {
|
||||
return cgroups.EnterPid(m.paths, pid)
|
||||
}
|
||||
|
||||
for _, sys := range m.getSubsystems() {
|
||||
for _, sys := range subsystems {
|
||||
p, err := d.path(sys.Name())
|
||||
if err != nil {
|
||||
// The non-presence of the devices subsystem is
|
||||
@@ -211,7 +252,7 @@ func (m *manager) Apply(pid int) (err error) {
|
||||
}
|
||||
m.paths[sys.Name()] = p
|
||||
|
||||
if err := sys.Apply(d); err != nil {
|
||||
if err := sys.Apply(p, d); err != nil {
|
||||
// In the case of rootless (including euid=0 in userns), where an
|
||||
// explicit cgroup path hasn't been set, we don't bail on error in
|
||||
// case of permission problems. Cases where limits have been set
|
||||
@@ -250,9 +291,9 @@ func (m *manager) GetStats() (*cgroups.Stats, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
stats := cgroups.NewStats()
|
||||
for name, path := range m.paths {
|
||||
sys, err := m.getSubsystems().Get(name)
|
||||
if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) {
|
||||
for _, sys := range subsystems {
|
||||
path := m.paths[sys.Name()]
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
if err := sys.GetStats(path, stats); err != nil {
|
||||
@@ -275,7 +316,7 @@ func (m *manager) Set(container *configs.Config) error {
|
||||
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
for _, sys := range m.getSubsystems() {
|
||||
for _, sys := range subsystems {
|
||||
path := m.paths[sys.Name()]
|
||||
if err := sys.Set(path, container.Cgroups); err != nil {
|
||||
if m.rootless && sys.Name() == "devices" {
|
||||
@@ -374,18 +415,14 @@ func (raw *cgroupData) path(subsystem string) (string, error) {
|
||||
return filepath.Join(parentPath, raw.innerPath), nil
|
||||
}
|
||||
|
||||
func (raw *cgroupData) join(subsystem string) (string, error) {
|
||||
path, err := raw.path(subsystem)
|
||||
if err != nil {
|
||||
return "", err
|
||||
func join(path string, pid int) error {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path, nil
|
||||
return cgroups.WriteCgroupProc(path, pid)
|
||||
}
|
||||
|
||||
func removePath(p string, err error) error {
|
||||
|
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
generated
vendored
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go
generated
vendored
@@ -19,12 +19,8 @@ func (s *HugetlbGroup) Name() string {
|
||||
return "hugetlb"
|
||||
}
|
||||
|
||||
func (s *HugetlbGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("hugetlb")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *HugetlbGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *HugetlbGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -37,12 +33,11 @@ func (s *HugetlbGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *HugetlbGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("hugetlb"))
|
||||
}
|
||||
|
||||
func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
hugetlbStats := cgroups.HugetlbStats{}
|
||||
if !cgroups.PathExists(path) {
|
||||
return nil
|
||||
}
|
||||
for _, pageSize := range HugePageSizes {
|
||||
usage := strings.Join([]string{"hugetlb", pageSize, "usage_in_bytes"}, ".")
|
||||
value, err := fscommon.GetCgroupParamUint(path, usage)
|
||||
|
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
17
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
@@ -37,11 +37,8 @@ func (s *MemoryGroup) Name() string {
|
||||
return "memory"
|
||||
}
|
||||
|
||||
func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
|
||||
path, err := d.path("memory")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
} else if path == "" {
|
||||
func (s *MemoryGroup) Apply(path string, d *cgroupData) (err error) {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
if memoryAssigned(d.config) {
|
||||
@@ -66,11 +63,7 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
|
||||
|
||||
// We need to join memory cgroup after set memory limits, because
|
||||
// kmem.limit_in_bytes can only be set when the cgroup is empty.
|
||||
_, err = d.join("memory")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -165,10 +158,6 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemoryGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("memory"))
|
||||
}
|
||||
|
||||
func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
// Set stats from memory.stat.
|
||||
statsFile, err := os.Open(filepath.Join(path, "memory.stat"))
|
||||
|
11
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
generated
vendored
11
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
generated
vendored
@@ -16,10 +16,10 @@ func (s *NameGroup) Name() string {
|
||||
return s.GroupName
|
||||
}
|
||||
|
||||
func (s *NameGroup) Apply(d *cgroupData) error {
|
||||
func (s *NameGroup) Apply(path string, d *cgroupData) error {
|
||||
if s.Join {
|
||||
// ignore errors if the named cgroup does not exist
|
||||
d.join(s.GroupName)
|
||||
join(path, d.pid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -28,13 +28,6 @@ func (s *NameGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NameGroup) Remove(d *cgroupData) error {
|
||||
if s.Join {
|
||||
removePath(d.path(s.GroupName))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NameGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
generated
vendored
@@ -17,12 +17,8 @@ func (s *NetClsGroup) Name() string {
|
||||
return "net_cls"
|
||||
}
|
||||
|
||||
func (s *NetClsGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("net_cls")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *NetClsGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -35,10 +31,6 @@ func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetClsGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("net_cls"))
|
||||
}
|
||||
|
||||
func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go
generated
vendored
@@ -15,12 +15,8 @@ func (s *NetPrioGroup) Name() string {
|
||||
return "net_prio"
|
||||
}
|
||||
|
||||
func (s *NetPrioGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("net_prio")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *NetPrioGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -33,10 +29,6 @@ func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetPrioGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("net_prio"))
|
||||
}
|
||||
|
||||
func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go
generated
vendored
@@ -14,22 +14,14 @@ func (s *PerfEventGroup) Name() string {
|
||||
return "perf_event"
|
||||
}
|
||||
|
||||
func (s *PerfEventGroup) Apply(d *cgroupData) error {
|
||||
// we just want to join this group even though we don't set anything
|
||||
if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *PerfEventGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *PerfEventGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PerfEventGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("perf_event"))
|
||||
}
|
||||
|
||||
func (s *PerfEventGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return nil
|
||||
}
|
||||
|
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
generated
vendored
15
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go
generated
vendored
@@ -19,12 +19,8 @@ func (s *PidsGroup) Name() string {
|
||||
return "pids"
|
||||
}
|
||||
|
||||
func (s *PidsGroup) Apply(d *cgroupData) error {
|
||||
_, err := d.join("pids")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *PidsGroup) Apply(path string, d *cgroupData) error {
|
||||
return join(path, d.pid)
|
||||
}
|
||||
|
||||
func (s *PidsGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
@@ -44,11 +40,10 @@ func (s *PidsGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PidsGroup) Remove(d *cgroupData) error {
|
||||
return removePath(d.path("pids"))
|
||||
}
|
||||
|
||||
func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
if !cgroups.PathExists(path) {
|
||||
return nil
|
||||
}
|
||||
current, err := fscommon.GetCgroupParamUint(path, "pids.current")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse pids.current - %s", err)
|
||||
|
19
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go
generated
vendored
19
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go
generated
vendored
@@ -41,18 +41,7 @@ type subsystem interface {
|
||||
|
||||
var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist")
|
||||
|
||||
type subsystemSet []subsystem
|
||||
|
||||
func (s subsystemSet) Get(name string) (subsystem, error) {
|
||||
for _, ss := range s {
|
||||
if ss.Name() == name {
|
||||
return ss, nil
|
||||
}
|
||||
}
|
||||
return nil, errSubsystemDoesNotExist
|
||||
}
|
||||
|
||||
var legacySubsystems = subsystemSet{
|
||||
var legacySubsystems = []subsystem{
|
||||
&fs.CpusetGroup{},
|
||||
&fs.DevicesGroup{},
|
||||
&fs.MemoryGroup{},
|
||||
@@ -355,9 +344,9 @@ func (m *legacyManager) GetStats() (*cgroups.Stats, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
stats := cgroups.NewStats()
|
||||
for name, path := range m.paths {
|
||||
sys, err := legacySubsystems.Get(name)
|
||||
if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) {
|
||||
for _, sys := range legacySubsystems {
|
||||
path := m.paths[sys.Name()]
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
if err := sys.GetStats(path, stats); err != nil {
|
||||
|
57
vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go
generated
vendored
57
vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go
generated
vendored
@@ -8,6 +8,10 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Code in this source file are specific to cgroup v1,
|
||||
@@ -15,6 +19,7 @@ import (
|
||||
|
||||
const (
|
||||
CgroupNamePrefix = "name="
|
||||
defaultPrefix = "/sys/fs/cgroup"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -43,11 +48,59 @@ func IsNotFound(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func tryDefaultPath(cgroupPath, subsystem string) string {
|
||||
if !strings.HasPrefix(defaultPrefix, cgroupPath) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// remove possible prefix
|
||||
subsystem = strings.TrimPrefix(subsystem, CgroupNamePrefix)
|
||||
|
||||
// Make sure we're still under defaultPrefix, and resolve
|
||||
// a possible symlink (like cpu -> cpu,cpuacct).
|
||||
path, err := securejoin.SecureJoin(defaultPrefix, subsystem)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// (1) path should be a directory.
|
||||
st, err := os.Lstat(path)
|
||||
if err != nil || !st.IsDir() {
|
||||
return ""
|
||||
}
|
||||
|
||||
// (2) path should be a mount point.
|
||||
pst, err := os.Lstat(filepath.Dir(path))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if st.Sys().(*syscall.Stat_t).Dev == pst.Sys().(*syscall.Stat_t).Dev {
|
||||
// parent dir has the same dev -- path is not a mount point
|
||||
return ""
|
||||
}
|
||||
|
||||
// (3) path should have 'cgroup' fs type.
|
||||
fst := unix.Statfs_t{}
|
||||
err = unix.Statfs(path, &fst)
|
||||
if err != nil || fst.Type != unix.CGROUP_SUPER_MAGIC {
|
||||
return ""
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
// https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
|
||||
func FindCgroupMountpoint(cgroupPath, subsystem string) (string, error) {
|
||||
if IsCgroup2UnifiedMode() {
|
||||
return "", errUnified
|
||||
}
|
||||
|
||||
// Avoid parsing mountinfo by trying the default path first, if possible.
|
||||
if path := tryDefaultPath(cgroupPath, subsystem); path != "" {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
mnt, _, err := FindCgroupMountpointAndRoot(cgroupPath, subsystem)
|
||||
return mnt, err
|
||||
}
|
||||
@@ -57,9 +110,7 @@ func FindCgroupMountpointAndRoot(cgroupPath, subsystem string) (string, string,
|
||||
return "", "", errUnified
|
||||
}
|
||||
|
||||
// We are not using mount.GetMounts() because it's super-inefficient,
|
||||
// parsing it directly sped up x10 times because of not using Sscanf.
|
||||
// It was one of two major performance drawbacks in container start.
|
||||
// Avoid parsing mountinfo by checking if subsystem is valid/available.
|
||||
if !isSubsystemAvailable(subsystem) {
|
||||
return "", "", NewNotFoundError(subsystem)
|
||||
}
|
||||
|
41
vendor/github.com/opencontainers/runc/libcontainer/configs/BUILD
generated
vendored
41
vendor/github.com/opencontainers/runc/libcontainer/configs/BUILD
generated
vendored
@@ -9,6 +9,8 @@ go_library(
|
||||
"config.go",
|
||||
"config_linux.go",
|
||||
"device.go",
|
||||
"device_unix.go",
|
||||
"device_windows.go",
|
||||
"hugepage_limit.go",
|
||||
"intelrdt.go",
|
||||
"interface_priority_map.go",
|
||||
@@ -27,13 +29,50 @@ go_library(
|
||||
"//vendor/github.com/opencontainers/runtime-spec/specs-go:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/sirupsen/logrus:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:aix": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"//vendor/github.com/coreos/go-systemd/v22/dbus:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:darwin": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:dragonfly": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:freebsd": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:illumos": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:ios": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:js": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//vendor/github.com/coreos/go-systemd/v22/dbus:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:nacl": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:netbsd": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:openbsd": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:plan9": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:solaris": [
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
|
9
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
9
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
@@ -239,15 +239,6 @@ const (
|
||||
Poststop = "poststop"
|
||||
)
|
||||
|
||||
// TODO move this to runtime-spec
|
||||
// See: https://github.com/opencontainers/runtime-spec/pull/1046
|
||||
const (
|
||||
Creating = "creating"
|
||||
Created = "created"
|
||||
Running = "running"
|
||||
Stopped = "stopped"
|
||||
)
|
||||
|
||||
type Capabilities struct {
|
||||
// Bounding is the set of capabilities checked by the kernel.
|
||||
Bounding []string
|
||||
|
12
vendor/github.com/opencontainers/runc/libcontainer/configs/device.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/configs/device.go
generated
vendored
@@ -1,20 +1,15 @@
|
||||
package configs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
Wildcard = -1
|
||||
)
|
||||
|
||||
// TODO Windows: This can be factored out in the future
|
||||
|
||||
type Device struct {
|
||||
DeviceRule
|
||||
|
||||
@@ -173,10 +168,3 @@ func (d *DeviceRule) CgroupString() string {
|
||||
}
|
||||
return fmt.Sprintf("%c %s:%s %s", d.Type, major, minor, d.Permissions)
|
||||
}
|
||||
|
||||
func (d *DeviceRule) Mkdev() (uint64, error) {
|
||||
if d.Major == Wildcard || d.Minor == Wildcard {
|
||||
return 0, errors.New("cannot mkdev() device with wildcards")
|
||||
}
|
||||
return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
|
||||
}
|
||||
|
16
vendor/github.com/opencontainers/runc/libcontainer/configs/device_unix.go
generated
vendored
Normal file
16
vendor/github.com/opencontainers/runc/libcontainer/configs/device_unix.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// +build !windows
|
||||
|
||||
package configs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (d *DeviceRule) Mkdev() (uint64, error) {
|
||||
if d.Major == Wildcard || d.Minor == Wildcard {
|
||||
return 0, errors.New("cannot mkdev() device with wildcards")
|
||||
}
|
||||
return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
|
||||
}
|
5
vendor/github.com/opencontainers/runc/libcontainer/configs/device_windows.go
generated
vendored
Normal file
5
vendor/github.com/opencontainers/runc/libcontainer/configs/device_windows.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package configs
|
||||
|
||||
func (d *DeviceRule) Mkdev() (uint64, error) {
|
||||
return 0, nil
|
||||
}
|
144
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
144
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
@@ -764,6 +764,7 @@ func (c *linuxContainer) checkCriuVersion(minVersion int) error {
|
||||
}
|
||||
|
||||
criu := criu.MakeCriu()
|
||||
criu.SetCriuPath(c.criuPath)
|
||||
var err error
|
||||
c.criuVersion, err = criu.GetCriuVersion()
|
||||
if err != nil {
|
||||
@@ -836,6 +837,78 @@ func (c *linuxContainer) handleCriuConfigurationFile(rpcOpts *criurpc.CriuOpts)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *linuxContainer) criuSupportsExtNS(t configs.NamespaceType) bool {
|
||||
var minVersion int
|
||||
switch t {
|
||||
case configs.NEWNET:
|
||||
// CRIU supports different external namespace with different released CRIU versions.
|
||||
// For network namespaces to work we need at least criu 3.11.0 => 31100.
|
||||
minVersion = 31100
|
||||
case configs.NEWPID:
|
||||
// For PID namespaces criu 31500 is needed.
|
||||
minVersion = 31500
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return c.checkCriuVersion(minVersion) == nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) criuNsToKey(t configs.NamespaceType) string {
|
||||
return "extRoot" + strings.Title(configs.NsName(t)) + "NS"
|
||||
}
|
||||
|
||||
func (c *linuxContainer) handleCheckpointingExternalNamespaces(rpcOpts *criurpc.CriuOpts, t configs.NamespaceType) error {
|
||||
if !c.criuSupportsExtNS(t) {
|
||||
return nil
|
||||
}
|
||||
|
||||
nsPath := c.config.Namespaces.PathOf(t)
|
||||
if nsPath == "" {
|
||||
return nil
|
||||
}
|
||||
// CRIU expects the information about an external namespace
|
||||
// like this: --external <TYPE>[<inode>]:<key>
|
||||
// This <key> is always 'extRoot<TYPE>NS'.
|
||||
var ns unix.Stat_t
|
||||
if err := unix.Stat(nsPath, &ns); err != nil {
|
||||
return err
|
||||
}
|
||||
criuExternal := fmt.Sprintf("%s[%d]:%s", configs.NsName(t), ns.Ino, c.criuNsToKey(t))
|
||||
rpcOpts.External = append(rpcOpts.External, criuExternal)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File, t configs.NamespaceType) error {
|
||||
if !c.criuSupportsExtNS(t) {
|
||||
return nil
|
||||
}
|
||||
|
||||
nsPath := c.config.Namespaces.PathOf(t)
|
||||
if nsPath == "" {
|
||||
return nil
|
||||
}
|
||||
// CRIU wants the information about an existing namespace
|
||||
// like this: --inherit-fd fd[<fd>]:<key>
|
||||
// The <key> needs to be the same as during checkpointing.
|
||||
// We are always using 'extRoot<TYPE>NS' as the key in this.
|
||||
nsFd, err := os.Open(nsPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("If a specific network namespace is defined it must exist: %s", err)
|
||||
return fmt.Errorf("Requested network namespace %v does not exist", nsPath)
|
||||
}
|
||||
inheritFd := new(criurpc.InheritFd)
|
||||
inheritFd.Key = proto.String(c.criuNsToKey(t))
|
||||
// The offset of four is necessary because 0, 1, 2 and 3 is already
|
||||
// used by stdin, stdout, stderr, 'criu swrk' socket.
|
||||
inheritFd.Fd = proto.Int32(int32(4 + len(*extraFiles)))
|
||||
rpcOpts.InheritFd = append(rpcOpts.InheritFd, inheritFd)
|
||||
// All open FDs need to be transferred to CRIU via extraFiles
|
||||
*extraFiles = append(*extraFiles, nsFd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
@@ -909,25 +982,13 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
// will expect that the namespace exists during restore.
|
||||
// This basically means that CRIU will ignore the namespace
|
||||
// and expect to be setup correctly.
|
||||
nsPath := c.config.Namespaces.PathOf(configs.NEWNET)
|
||||
if nsPath != "" {
|
||||
// For this to work we need at least criu 3.11.0 => 31100.
|
||||
// As there was already a successful version check we will
|
||||
// not error out if it fails. runc will just behave as it used
|
||||
// to do and ignore external network namespaces.
|
||||
err := c.checkCriuVersion(31100)
|
||||
if err == nil {
|
||||
// CRIU expects the information about an external namespace
|
||||
// like this: --external net[<inode>]:<key>
|
||||
// This <key> is always 'extRootNetNS'.
|
||||
var netns unix.Stat_t
|
||||
err = unix.Stat(nsPath, &netns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
criuExternal := fmt.Sprintf("net[%d]:extRootNetNS", netns.Ino)
|
||||
rpcOpts.External = append(rpcOpts.External, criuExternal)
|
||||
}
|
||||
if err := c.handleCheckpointingExternalNamespaces(&rpcOpts, configs.NEWNET); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Same for possible external PID namespaces
|
||||
if err := c.handleCheckpointingExternalNamespaces(&rpcOpts, configs.NEWPID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// CRIU can use cgroup freezer; when rpcOpts.FreezeCgroup
|
||||
@@ -1251,33 +1312,13 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
// Same as during checkpointing. If the container has a specific network namespace
|
||||
// assigned to it, this now expects that the checkpoint will be restored in a
|
||||
// already created network namespace.
|
||||
nsPath := c.config.Namespaces.PathOf(configs.NEWNET)
|
||||
if nsPath != "" {
|
||||
// For this to work we need at least criu 3.11.0 => 31100.
|
||||
// As there was already a successful version check we will
|
||||
// not error out if it fails. runc will just behave as it used
|
||||
// to do and ignore external network namespaces.
|
||||
err := c.checkCriuVersion(31100)
|
||||
if err == nil {
|
||||
// CRIU wants the information about an existing network namespace
|
||||
// like this: --inherit-fd fd[<fd>]:<key>
|
||||
// The <key> needs to be the same as during checkpointing.
|
||||
// We are always using 'extRootNetNS' as the key in this.
|
||||
netns, err := os.Open(nsPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("If a specific network namespace is defined it must exist: %s", err)
|
||||
return fmt.Errorf("Requested network namespace %v does not exist", nsPath)
|
||||
}
|
||||
defer netns.Close()
|
||||
inheritFd := new(criurpc.InheritFd)
|
||||
inheritFd.Key = proto.String("extRootNetNS")
|
||||
// The offset of four is necessary because 0, 1, 2 and 3 is already
|
||||
// used by stdin, stdout, stderr, 'criu swrk' socket.
|
||||
inheritFd.Fd = proto.Int32(int32(4 + len(extraFiles)))
|
||||
req.Opts.InheritFd = append(req.Opts.InheritFd, inheritFd)
|
||||
// All open FDs need to be transferred to CRIU via extraFiles
|
||||
extraFiles = append(extraFiles, netns)
|
||||
}
|
||||
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWNET); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Same for PID namespaces.
|
||||
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWPID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This will modify the rootfs of the container in the same way runc
|
||||
@@ -1345,7 +1386,14 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
req.Opts.InheritFd = append(req.Opts.InheritFd, inheritFd)
|
||||
}
|
||||
}
|
||||
return c.criuSwrk(process, req, criuOpts, extraFiles)
|
||||
err = c.criuSwrk(process, req, criuOpts, extraFiles)
|
||||
|
||||
// Now that CRIU is done let's close all opened FDs CRIU needed.
|
||||
for _, fd := range extraFiles {
|
||||
fd.Close()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *linuxContainer) criuApplyCgroups(pid int, req *criurpc.CriuReq) error {
|
||||
@@ -1863,7 +1911,7 @@ func (c *linuxContainer) currentOCIState() (*specs.State, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.Status = status.String()
|
||||
state.Status = specs.ContainerState(status.String())
|
||||
if status != Stopped {
|
||||
if c.initProcess != nil {
|
||||
state.Pid = c.initProcess.pid()
|
||||
|
6
vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
generated
vendored
@@ -19,7 +19,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/logs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/opencontainers/runc/libcontainer/utils"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -400,7 +400,7 @@ func (p *initProcess) start() (retErr error) {
|
||||
}
|
||||
// initProcessStartTime hasn't been set yet.
|
||||
s.Pid = p.cmd.Process.Pid
|
||||
s.Status = configs.Creating
|
||||
s.Status = specs.StateCreating
|
||||
hooks := p.config.Config.Hooks
|
||||
|
||||
if err := hooks[configs.Prestart].RunHooks(s); err != nil {
|
||||
@@ -433,7 +433,7 @@ func (p *initProcess) start() (retErr error) {
|
||||
}
|
||||
// initProcessStartTime hasn't been set yet.
|
||||
s.Pid = p.cmd.Process.Pid
|
||||
s.Status = configs.Creating
|
||||
s.Status = specs.StateCreating
|
||||
hooks := p.config.Config.Hooks
|
||||
|
||||
if err := hooks[configs.Prestart].RunHooks(s); err != nil {
|
||||
|
9
vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
generated
vendored
9
vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -100,7 +101,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
|
||||
|
||||
s := iConfig.SpecState
|
||||
s.Pid = unix.Getpid()
|
||||
s.Status = configs.Creating
|
||||
s.Status = specs.StateCreating
|
||||
if err := iConfig.Config.Hooks[configs.CreateContainer].RunHooks(s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -110,7 +111,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
|
||||
} else if config.Namespaces.Contains(configs.NEWNS) {
|
||||
err = pivotRoot(config.Rootfs)
|
||||
} else {
|
||||
err = chroot(config.Rootfs)
|
||||
err = chroot()
|
||||
}
|
||||
if err != nil {
|
||||
return newSystemErrorWithCause(err, "jailing process inside rootfs")
|
||||
@@ -836,10 +837,10 @@ func msMoveRoot(rootfs string) error {
|
||||
if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return chroot(rootfs)
|
||||
return chroot()
|
||||
}
|
||||
|
||||
func chroot(rootfs string) error {
|
||||
func chroot() error {
|
||||
if err := unix.Chroot("."); err != nil {
|
||||
return err
|
||||
}
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
generated
vendored
@@ -13,9 +13,9 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/keys"
|
||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -210,7 +210,7 @@ func (l *linuxStandardInit) Init() error {
|
||||
|
||||
s := l.config.SpecState
|
||||
s.Pid = unix.Getpid()
|
||||
s.Status = configs.Created
|
||||
s.Status = specs.StateCreated
|
||||
if err := l.config.Config.Hooks[configs.StartContainer].RunHooks(s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
4
vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
generated
vendored
4
vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
generated
vendored
@@ -8,7 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -70,7 +70,7 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Status = configs.Stopped
|
||||
s.Status = specs.StateStopped
|
||||
|
||||
if err := hooks[configs.Poststop].RunHooks(s); err != nil {
|
||||
return err
|
||||
|
15
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
15
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
@@ -90,7 +90,7 @@ type User struct {
|
||||
// GID is the group id.
|
||||
GID uint32 `json:"gid" platform:"linux,solaris"`
|
||||
// Umask is the umask for the init process.
|
||||
Umask uint32 `json:"umask,omitempty" platform:"linux,solaris"`
|
||||
Umask *uint32 `json:"umask,omitempty" platform:"linux,solaris"`
|
||||
// AdditionalGids are additional group ids set for the container's process.
|
||||
AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux,solaris"`
|
||||
// Username is the user name.
|
||||
@@ -635,12 +635,13 @@ type LinuxSeccompAction string
|
||||
|
||||
// Define actions for Seccomp rules
|
||||
const (
|
||||
ActKill LinuxSeccompAction = "SCMP_ACT_KILL"
|
||||
ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP"
|
||||
ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
|
||||
ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
|
||||
ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
|
||||
ActLog LinuxSeccompAction = "SCMP_ACT_LOG"
|
||||
ActKill LinuxSeccompAction = "SCMP_ACT_KILL"
|
||||
ActKillProcess LinuxSeccompAction = "SCMP_ACT_KILL_PROCESS"
|
||||
ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP"
|
||||
ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
|
||||
ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
|
||||
ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
|
||||
ActLog LinuxSeccompAction = "SCMP_ACT_LOG"
|
||||
)
|
||||
|
||||
// LinuxSeccompOperator used to match syscall arguments in Seccomp
|
||||
|
20
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
20
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
@@ -1,5 +1,23 @@
|
||||
package specs
|
||||
|
||||
// ContainerState represents the state of a container.
|
||||
type ContainerState string
|
||||
|
||||
const (
|
||||
// StateCreating indicates that the container is being created
|
||||
StateCreating ContainerState = "creating"
|
||||
|
||||
// StateCreated indicates that the runtime has finished the create operation
|
||||
StateCreated ContainerState = "created"
|
||||
|
||||
// StateRunning indicates that the container process has executed the
|
||||
// user-specified program but has not exited
|
||||
StateRunning ContainerState = "running"
|
||||
|
||||
// StateStopped indicates that the container process has exited
|
||||
StateStopped ContainerState = "stopped"
|
||||
)
|
||||
|
||||
// State holds information about the runtime state of the container.
|
||||
type State struct {
|
||||
// Version is the version of the specification that is supported.
|
||||
@@ -7,7 +25,7 @@ type State struct {
|
||||
// ID is the container ID
|
||||
ID string `json:"id"`
|
||||
// Status is the runtime status of the container.
|
||||
Status string `json:"status"`
|
||||
Status ContainerState `json:"status"`
|
||||
// Pid is the process ID for the container process.
|
||||
Pid int `json:"pid,omitempty"`
|
||||
// Bundle is the path to the container's bundle directory.
|
||||
|
10
vendor/github.com/opencontainers/selinux/go-selinux/BUILD
generated
vendored
10
vendor/github.com/opencontainers/selinux/go-selinux/BUILD
generated
vendored
@@ -3,6 +3,8 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"selinux.go",
|
||||
"selinux_linux.go",
|
||||
"selinux_stub.go",
|
||||
"xattrs.go",
|
||||
@@ -10,15 +12,17 @@ go_library(
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/opencontainers/selinux/go-selinux",
|
||||
importpath = "github.com/opencontainers/selinux/go-selinux",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = select({
|
||||
deps = [
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"//vendor/github.com/opencontainers/selinux/pkg/pwalk:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/willf/bitset:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//vendor/github.com/opencontainers/selinux/pkg/pwalk:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/willf/bitset:go_default_library",
|
||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
|
21
vendor/github.com/opencontainers/selinux/go-selinux/doc.go
generated
vendored
Normal file
21
vendor/github.com/opencontainers/selinux/go-selinux/doc.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Package selinux provides a high-level interface for interacting with selinux.
|
||||
|
||||
This package uses a selinux build tag to enable the selinux functionality. This
|
||||
allows non-linux and linux users who do not have selinux support to still use
|
||||
tools that rely on this library.
|
||||
|
||||
To compile with full selinux support use the -tags=selinux option in your build
|
||||
and test commands.
|
||||
|
||||
Usage:
|
||||
|
||||
import "github.com/opencontainers/selinux/go-selinux"
|
||||
|
||||
// Ensure that selinux is enforcing mode.
|
||||
if selinux.EnforceMode() != selinux.Enforcing {
|
||||
selinux.SetEnforceMode(selinux.Enforcing)
|
||||
}
|
||||
|
||||
*/
|
||||
package selinux
|
2
vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
generated
vendored
2
vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
generated
vendored
@@ -73,9 +73,9 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
|
||||
selinux.ReleaseLabel(processLabel)
|
||||
}
|
||||
processLabel = pcon.Get()
|
||||
mountLabel = mcon.Get()
|
||||
selinux.ReserveLabel(processLabel)
|
||||
}
|
||||
mountLabel = mcon.Get()
|
||||
}
|
||||
return processLabel, mountLabel, nil
|
||||
}
|
||||
|
1
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
1
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
@@ -30,7 +30,6 @@ func Relabel(path string, fileLabel string, shared bool) error {
|
||||
// DisableSecOpt returns a security opt that can disable labeling
|
||||
// support for future container processes
|
||||
func DisableSecOpt() []string {
|
||||
// TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil"
|
||||
return nil
|
||||
}
|
||||
|
||||
|
249
vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
generated
vendored
Normal file
249
vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
package selinux
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// Enforcing constant indicate SELinux is in enforcing mode
|
||||
Enforcing = 1
|
||||
// Permissive constant to indicate SELinux is in permissive mode
|
||||
Permissive = 0
|
||||
// Disabled constant to indicate SELinux is disabled
|
||||
Disabled = -1
|
||||
|
||||
// DefaultCategoryRange is the upper bound on the category range
|
||||
DefaultCategoryRange = uint32(1024)
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
||||
// ErrEmptyPath is returned when an empty path has been specified.
|
||||
ErrEmptyPath = errors.New("empty path")
|
||||
|
||||
// InvalidLabel is returned when an invalid label is specified.
|
||||
InvalidLabel = errors.New("Invalid Label")
|
||||
|
||||
// ErrIncomparable is returned two levels are not comparable
|
||||
ErrIncomparable = errors.New("incomparable levels")
|
||||
// ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level
|
||||
ErrLevelSyntax = errors.New("invalid level syntax")
|
||||
|
||||
// CategoryRange allows the upper bound on the category range to be adjusted
|
||||
CategoryRange = DefaultCategoryRange
|
||||
)
|
||||
|
||||
// Context is a representation of the SELinux label broken into 4 parts
|
||||
type Context map[string]string
|
||||
|
||||
// SetDisabled disables SELinux support for the package
|
||||
func SetDisabled() {
|
||||
setDisabled()
|
||||
}
|
||||
|
||||
// GetEnabled returns whether SELinux is currently enabled.
|
||||
func GetEnabled() bool {
|
||||
return getEnabled()
|
||||
}
|
||||
|
||||
// ClassIndex returns the int index for an object class in the loaded policy,
|
||||
// or -1 and an error
|
||||
func ClassIndex(class string) (int, error) {
|
||||
return classIndex(class)
|
||||
}
|
||||
|
||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||
func SetFileLabel(fpath string, label string) error {
|
||||
return setFileLabel(fpath, label)
|
||||
}
|
||||
|
||||
// FileLabel returns the SELinux label for this path or returns an error.
|
||||
func FileLabel(fpath string) (string, error) {
|
||||
return fileLabel(fpath)
|
||||
}
|
||||
|
||||
// SetFSCreateLabel tells kernel the label to create all file system objects
|
||||
// created by this task. Setting label="" to return to default.
|
||||
func SetFSCreateLabel(label string) error {
|
||||
return setFSCreateLabel(label)
|
||||
}
|
||||
|
||||
// FSCreateLabel returns the default label the kernel which the kernel is using
|
||||
// for file system objects created by this task. "" indicates default.
|
||||
func FSCreateLabel() (string, error) {
|
||||
return fsCreateLabel()
|
||||
}
|
||||
|
||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
||||
func CurrentLabel() (string, error) {
|
||||
return currentLabel()
|
||||
}
|
||||
|
||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
||||
func PidLabel(pid int) (string, error) {
|
||||
return pidLabel(pid)
|
||||
}
|
||||
|
||||
// ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||
// that are executed by the current process thread, or an error.
|
||||
func ExecLabel() (string, error) {
|
||||
return execLabel()
|
||||
}
|
||||
|
||||
// CanonicalizeContext takes a context string and writes it to the kernel
|
||||
// the function then returns the context that the kernel will use. Use this
|
||||
// function to check if two contexts are equivalent
|
||||
func CanonicalizeContext(val string) (string, error) {
|
||||
return canonicalizeContext(val)
|
||||
}
|
||||
|
||||
// ComputeCreateContext requests the type transition from source to target for
|
||||
// class from the kernel.
|
||||
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||
return computeCreateContext(source, target, class)
|
||||
}
|
||||
|
||||
// CalculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
|
||||
// of a source and target range.
|
||||
// The glblub is calculated as the greater of the low sensitivities and
|
||||
// the lower of the high sensitivities and the and of each category bitset.
|
||||
func CalculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||
return calculateGlbLub(sourceRange, targetRange)
|
||||
}
|
||||
|
||||
// SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||
// that are executed by the current process thread, or an error.
|
||||
func SetExecLabel(label string) error {
|
||||
return setExecLabel(label)
|
||||
}
|
||||
|
||||
// SetTaskLabel sets the SELinux label for the current thread, or an error.
|
||||
// This requires the dyntransition permission.
|
||||
func SetTaskLabel(label string) error {
|
||||
return setTaskLabel(label)
|
||||
}
|
||||
|
||||
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||
// label to the next socket that gets created
|
||||
func SetSocketLabel(label string) error {
|
||||
return setSocketLabel(label)
|
||||
}
|
||||
|
||||
// SocketLabel retrieves the current socket label setting
|
||||
func SocketLabel() (string, error) {
|
||||
return socketLabel()
|
||||
}
|
||||
|
||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
||||
func PeerLabel(fd uintptr) (string, error) {
|
||||
return peerLabel(fd)
|
||||
}
|
||||
|
||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||
// label to the next kernel keyring that gets created
|
||||
func SetKeyLabel(label string) error {
|
||||
return setKeyLabel(label)
|
||||
}
|
||||
|
||||
// KeyLabel retrieves the current kernel keyring label setting
|
||||
func KeyLabel() (string, error) {
|
||||
return keyLabel()
|
||||
}
|
||||
|
||||
// Get returns the Context as a string
|
||||
func (c Context) Get() string {
|
||||
return c.get()
|
||||
}
|
||||
|
||||
// NewContext creates a new Context struct from the specified label
|
||||
func NewContext(label string) (Context, error) {
|
||||
return newContext(label)
|
||||
}
|
||||
|
||||
// ClearLabels clears all reserved labels
|
||||
func ClearLabels() {
|
||||
clearLabels()
|
||||
}
|
||||
|
||||
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
||||
func ReserveLabel(label string) {
|
||||
reserveLabel(label)
|
||||
}
|
||||
|
||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||
func EnforceMode() int {
|
||||
return enforceMode()
|
||||
}
|
||||
|
||||
// SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||
// Disabled is not valid, since this needs to be set at boot time.
|
||||
func SetEnforceMode(mode int) error {
|
||||
return setEnforceMode(mode)
|
||||
}
|
||||
|
||||
// DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||
// Permissive or Disabled. Note this is is just the default at boot time.
|
||||
// EnforceMode tells you the systems current mode.
|
||||
func DefaultEnforceMode() int {
|
||||
return defaultEnforceMode()
|
||||
}
|
||||
|
||||
// ReleaseLabel un-reserves the MLS/MCS Level field of the specified label,
|
||||
// allowing it to be used by another process.
|
||||
func ReleaseLabel(label string) {
|
||||
releaseLabel(label)
|
||||
}
|
||||
|
||||
// ROFileLabel returns the specified SELinux readonly file label
|
||||
func ROFileLabel() string {
|
||||
return roFileLabel()
|
||||
}
|
||||
|
||||
// KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||
// for kvm containers by the calling process.
|
||||
func KVMContainerLabels() (string, string) {
|
||||
return kvmContainerLabels()
|
||||
}
|
||||
|
||||
// InitContainerLabels returns the default processLabel and file labels to be
|
||||
// used for containers running an init system like systemd by the calling process.
|
||||
func InitContainerLabels() (string, string) {
|
||||
return initContainerLabels()
|
||||
}
|
||||
|
||||
// ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||
// container labeling by the calling process.
|
||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
||||
return containerLabels()
|
||||
}
|
||||
|
||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
||||
func SecurityCheckContext(val string) error {
|
||||
return securityCheckContext(val)
|
||||
}
|
||||
|
||||
// CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||
// the dest label.
|
||||
func CopyLevel(src, dest string) (string, error) {
|
||||
return copyLevel(src, dest)
|
||||
}
|
||||
|
||||
// Chcon changes the fpath file object to the SELinux label label.
|
||||
// If fpath is a directory and recurse is true, then Chcon walks the
|
||||
// directory tree setting the label.
|
||||
func Chcon(fpath string, label string, recurse bool) error {
|
||||
return chcon(fpath, label, recurse)
|
||||
}
|
||||
|
||||
// DupSecOpt takes an SELinux process label and returns security options that
|
||||
// can be used to set the SELinux Type and Level for future container processes.
|
||||
func DupSecOpt(src string) ([]string, error) {
|
||||
return dupSecOpt(src)
|
||||
}
|
||||
|
||||
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
||||
// labeling support for future container processes.
|
||||
func DisableSecOpt() []string {
|
||||
return disableSecOpt()
|
||||
}
|
481
vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
generated
vendored
481
vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
generated
vendored
@@ -20,17 +20,12 @@ import (
|
||||
|
||||
"github.com/opencontainers/selinux/pkg/pwalk"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/willf/bitset"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
// Enforcing constant indicate SELinux is in enforcing mode
|
||||
Enforcing = 1
|
||||
// Permissive constant to indicate SELinux is in permissive mode
|
||||
Permissive = 0
|
||||
// Disabled constant to indicate SELinux is disabled
|
||||
Disabled = -1
|
||||
|
||||
minSensLen = 2
|
||||
contextFile = "/usr/share/containers/selinux/contexts"
|
||||
selinuxDir = "/etc/selinux/"
|
||||
selinuxConfig = selinuxDir + "config"
|
||||
@@ -49,17 +44,27 @@ type selinuxState struct {
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
||||
// ErrEmptyPath is returned when an empty path has been specified.
|
||||
ErrEmptyPath = errors.New("empty path")
|
||||
// InvalidLabel is returned when an invalid label is specified.
|
||||
InvalidLabel = errors.New("Invalid Label")
|
||||
type level struct {
|
||||
sens uint
|
||||
cats *bitset.BitSet
|
||||
}
|
||||
|
||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||
roFileLabel string
|
||||
state = selinuxState{
|
||||
type mlsRange struct {
|
||||
low *level
|
||||
high *level
|
||||
}
|
||||
|
||||
type levelItem byte
|
||||
|
||||
const (
|
||||
sensitivity levelItem = 's'
|
||||
category levelItem = 'c'
|
||||
)
|
||||
|
||||
var (
|
||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||
readOnlyFileLabel string
|
||||
state = selinuxState{
|
||||
mcsList: make(map[string]bool),
|
||||
}
|
||||
|
||||
@@ -68,9 +73,6 @@ var (
|
||||
haveThreadSelf bool
|
||||
)
|
||||
|
||||
// Context is a representation of the SELinux label broken into 4 parts
|
||||
type Context map[string]string
|
||||
|
||||
func (s *selinuxState) setEnable(enabled bool) bool {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
@@ -97,8 +99,8 @@ func (s *selinuxState) getEnabled() bool {
|
||||
return s.setEnable(enabled)
|
||||
}
|
||||
|
||||
// SetDisabled disables selinux support for the package
|
||||
func SetDisabled() {
|
||||
// setDisabled disables SELinux support for the package
|
||||
func setDisabled() {
|
||||
state.setEnable(false)
|
||||
}
|
||||
|
||||
@@ -190,15 +192,15 @@ func (s *selinuxState) getSELinuxfs() string {
|
||||
|
||||
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
||||
// filesystem or an empty string if no mountpoint is found. Selinuxfs is
|
||||
// a proc-like pseudo-filesystem that exposes the selinux policy API to
|
||||
// a proc-like pseudo-filesystem that exposes the SELinux policy API to
|
||||
// processes. The existence of an selinuxfs mount is used to determine
|
||||
// whether selinux is currently enabled or not.
|
||||
// whether SELinux is currently enabled or not.
|
||||
func getSelinuxMountPoint() string {
|
||||
return state.getSELinuxfs()
|
||||
}
|
||||
|
||||
// GetEnabled returns whether selinux is currently enabled.
|
||||
func GetEnabled() bool {
|
||||
// getEnabled returns whether SELinux is currently enabled.
|
||||
func getEnabled() bool {
|
||||
return state.getEnabled()
|
||||
}
|
||||
|
||||
@@ -282,8 +284,9 @@ func readCon(fpath string) (string, error) {
|
||||
return strings.Trim(retval, "\x00"), nil
|
||||
}
|
||||
|
||||
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
||||
func ClassIndex(class string) (int, error) {
|
||||
// classIndex returns the int index for an object class in the loaded policy,
|
||||
// or -1 and an error
|
||||
func classIndex(class string) (int, error) {
|
||||
permpath := fmt.Sprintf("class/%s/index", class)
|
||||
indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
|
||||
|
||||
@@ -299,8 +302,8 @@ func ClassIndex(class string) (int, error) {
|
||||
return index, nil
|
||||
}
|
||||
|
||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||
func SetFileLabel(fpath string, label string) error {
|
||||
// setFileLabel sets the SELinux label for this path or returns an error.
|
||||
func setFileLabel(fpath string, label string) error {
|
||||
if fpath == "" {
|
||||
return ErrEmptyPath
|
||||
}
|
||||
@@ -310,8 +313,8 @@ func SetFileLabel(fpath string, label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileLabel returns the SELinux label for this path or returns an error.
|
||||
func FileLabel(fpath string) (string, error) {
|
||||
// fileLabel returns the SELinux label for this path or returns an error.
|
||||
func fileLabel(fpath string) (string, error) {
|
||||
if fpath == "" {
|
||||
return "", ErrEmptyPath
|
||||
}
|
||||
@@ -327,37 +330,31 @@ func FileLabel(fpath string) (string, error) {
|
||||
return string(label), nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetFSCreateLabel tells kernel the label to create all file system objects
|
||||
created by this task. Setting label="" to return to default.
|
||||
*/
|
||||
func SetFSCreateLabel(label string) error {
|
||||
// setFSCreateLabel tells kernel the label to create all file system objects
|
||||
// created by this task. Setting label="" to return to default.
|
||||
func setFSCreateLabel(label string) error {
|
||||
return writeAttr("fscreate", label)
|
||||
}
|
||||
|
||||
/*
|
||||
FSCreateLabel returns the default label the kernel which the kernel is using
|
||||
for file system objects created by this task. "" indicates default.
|
||||
*/
|
||||
func FSCreateLabel() (string, error) {
|
||||
// fsCreateLabel returns the default label the kernel which the kernel is using
|
||||
// for file system objects created by this task. "" indicates default.
|
||||
func fsCreateLabel() (string, error) {
|
||||
return readAttr("fscreate")
|
||||
}
|
||||
|
||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
||||
func CurrentLabel() (string, error) {
|
||||
// currentLabel returns the SELinux label of the current process thread, or an error.
|
||||
func currentLabel() (string, error) {
|
||||
return readAttr("current")
|
||||
}
|
||||
|
||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
||||
func PidLabel(pid int) (string, error) {
|
||||
// pidLabel returns the SELinux label of the given pid, or an error.
|
||||
func pidLabel(pid int) (string, error) {
|
||||
return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
|
||||
}
|
||||
|
||||
/*
|
||||
ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||
that are executed by the current process thread, or an error.
|
||||
*/
|
||||
func ExecLabel() (string, error) {
|
||||
// ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||
// that are executed by the current process thread, or an error.
|
||||
func execLabel() (string, error) {
|
||||
return readAttr("exec")
|
||||
}
|
||||
|
||||
@@ -366,7 +363,7 @@ func writeCon(fpath, val string) error {
|
||||
return ErrEmptyPath
|
||||
}
|
||||
if val == "" {
|
||||
if !GetEnabled() {
|
||||
if !getEnabled() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -418,20 +415,17 @@ func writeAttr(attr, val string) error {
|
||||
return writeCon(attrPath(attr), val)
|
||||
}
|
||||
|
||||
/*
|
||||
CanonicalizeContext takes a context string and writes it to the kernel
|
||||
the function then returns the context that the kernel will use. This function
|
||||
can be used to see if two contexts are equivalent
|
||||
*/
|
||||
func CanonicalizeContext(val string) (string, error) {
|
||||
// canonicalizeContext takes a context string and writes it to the kernel
|
||||
// the function then returns the context that the kernel will use. Use this
|
||||
// function to check if two contexts are equivalent
|
||||
func canonicalizeContext(val string) (string, error) {
|
||||
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
|
||||
}
|
||||
|
||||
/*
|
||||
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
||||
*/
|
||||
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||
classidx, err := ClassIndex(class)
|
||||
// computeCreateContext requests the type transition from source to target for
|
||||
// class from the kernel.
|
||||
func computeCreateContext(source string, target string, class string) (string, error) {
|
||||
classidx, err := classIndex(class)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -439,6 +433,217 @@ func ComputeCreateContext(source string, target string, class string) (string, e
|
||||
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
|
||||
}
|
||||
|
||||
// catsToBitset stores categories in a bitset.
|
||||
func catsToBitset(cats string) (*bitset.BitSet, error) {
|
||||
bitset := &bitset.BitSet{}
|
||||
|
||||
catlist := strings.Split(cats, ",")
|
||||
for _, r := range catlist {
|
||||
ranges := strings.SplitN(r, ".", 2)
|
||||
if len(ranges) > 1 {
|
||||
catstart, err := parseLevelItem(ranges[0], category)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
catend, err := parseLevelItem(ranges[1], category)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := catstart; i <= catend; i++ {
|
||||
bitset.Set(i)
|
||||
}
|
||||
} else {
|
||||
cat, err := parseLevelItem(ranges[0], category)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bitset.Set(cat)
|
||||
}
|
||||
}
|
||||
|
||||
return bitset, nil
|
||||
}
|
||||
|
||||
// parseLevelItem parses and verifies that a sensitivity or category are valid
|
||||
func parseLevelItem(s string, sep levelItem) (uint, error) {
|
||||
if len(s) < minSensLen || levelItem(s[0]) != sep {
|
||||
return 0, ErrLevelSyntax
|
||||
}
|
||||
val, err := strconv.ParseUint(s[1:], 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return uint(val), nil
|
||||
}
|
||||
|
||||
// parseLevel fills a level from a string that contains
|
||||
// a sensitivity and categories
|
||||
func (l *level) parseLevel(levelStr string) error {
|
||||
lvl := strings.SplitN(levelStr, ":", 2)
|
||||
sens, err := parseLevelItem(lvl[0], sensitivity)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse sensitivity")
|
||||
}
|
||||
l.sens = sens
|
||||
if len(lvl) > 1 {
|
||||
cats, err := catsToBitset(lvl[1])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse categories")
|
||||
}
|
||||
l.cats = cats
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// rangeStrToMLSRange marshals a string representation of a range.
|
||||
func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) {
|
||||
mlsRange := &mlsRange{}
|
||||
levelSlice := strings.SplitN(rangeStr, "-", 2)
|
||||
|
||||
switch len(levelSlice) {
|
||||
// rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023
|
||||
case 2:
|
||||
mlsRange.high = &level{}
|
||||
if err := mlsRange.high.parseLevel(levelSlice[1]); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse high level %q", levelSlice[1])
|
||||
}
|
||||
fallthrough
|
||||
// rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023
|
||||
case 1:
|
||||
mlsRange.low = &level{}
|
||||
if err := mlsRange.low.parseLevel(levelSlice[0]); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse low level %q", levelSlice[0])
|
||||
}
|
||||
}
|
||||
|
||||
if mlsRange.high == nil {
|
||||
mlsRange.high = mlsRange.low
|
||||
}
|
||||
|
||||
return mlsRange, nil
|
||||
}
|
||||
|
||||
// bitsetToStr takes a category bitset and returns it in the
|
||||
// canonical selinux syntax
|
||||
func bitsetToStr(c *bitset.BitSet) string {
|
||||
var str string
|
||||
i, e := c.NextSet(0)
|
||||
len := 0
|
||||
for e {
|
||||
if len == 0 {
|
||||
if str != "" {
|
||||
str += ","
|
||||
}
|
||||
str += "c" + strconv.Itoa(int(i))
|
||||
}
|
||||
|
||||
next, e := c.NextSet(i + 1)
|
||||
if e {
|
||||
// consecutive cats
|
||||
if next == i+1 {
|
||||
len++
|
||||
i = next
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len == 1 {
|
||||
str += ",c" + strconv.Itoa(int(i))
|
||||
} else if len > 1 {
|
||||
str += ".c" + strconv.Itoa(int(i))
|
||||
}
|
||||
if !e {
|
||||
break
|
||||
}
|
||||
len = 0
|
||||
i = next
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
func (l1 *level) equal(l2 *level) bool {
|
||||
if l2 == nil || l1 == nil {
|
||||
return l1 == l2
|
||||
}
|
||||
if l1.sens != l2.sens {
|
||||
return false
|
||||
}
|
||||
return l1.cats.Equal(l2.cats)
|
||||
}
|
||||
|
||||
// String returns an mlsRange as a string.
|
||||
func (m mlsRange) String() string {
|
||||
low := "s" + strconv.Itoa(int(m.low.sens))
|
||||
if m.low.cats != nil && m.low.cats.Count() > 0 {
|
||||
low += ":" + bitsetToStr(m.low.cats)
|
||||
}
|
||||
|
||||
if m.low.equal(m.high) {
|
||||
return low
|
||||
}
|
||||
|
||||
high := "s" + strconv.Itoa(int(m.high.sens))
|
||||
if m.high.cats != nil && m.high.cats.Count() > 0 {
|
||||
high += ":" + bitsetToStr(m.high.cats)
|
||||
}
|
||||
|
||||
return low + "-" + high
|
||||
}
|
||||
|
||||
func max(a, b uint) uint {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func min(a, b uint) uint {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// calculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
|
||||
// of a source and target range.
|
||||
// The glblub is calculated as the greater of the low sensitivities and
|
||||
// the lower of the high sensitivities and the and of each category bitset.
|
||||
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||
s, err := rangeStrToMLSRange(sourceRange)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
t, err := rangeStrToMLSRange(targetRange)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if s.high.sens < t.low.sens || t.high.sens < s.low.sens {
|
||||
/* these ranges have no common sensitivities */
|
||||
return "", ErrIncomparable
|
||||
}
|
||||
|
||||
outrange := &mlsRange{low: &level{}, high: &level{}}
|
||||
|
||||
/* take the greatest of the low */
|
||||
outrange.low.sens = max(s.low.sens, t.low.sens)
|
||||
|
||||
/* take the least of the high */
|
||||
outrange.high.sens = min(s.high.sens, t.high.sens)
|
||||
|
||||
/* find the intersecting categories */
|
||||
if s.low.cats != nil && t.low.cats != nil {
|
||||
outrange.low.cats = s.low.cats.Intersection(t.low.cats)
|
||||
}
|
||||
if s.high.cats != nil && t.high.cats != nil {
|
||||
outrange.high.cats = s.high.cats.Intersection(t.high.cats)
|
||||
}
|
||||
|
||||
return outrange.String(), nil
|
||||
}
|
||||
|
||||
func readWriteCon(fpath string, val string) (string, error) {
|
||||
if fpath == "" {
|
||||
return "", ErrEmptyPath
|
||||
@@ -461,41 +666,37 @@ func readWriteCon(fpath string, val string) (string, error) {
|
||||
return strings.Trim(retval, "\x00"), nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||
that are executed by the current process thread, or an error.
|
||||
*/
|
||||
func SetExecLabel(label string) error {
|
||||
// setExecLabel sets the SELinux label that the kernel will use for any programs
|
||||
// that are executed by the current process thread, or an error.
|
||||
func setExecLabel(label string) error {
|
||||
return writeAttr("exec", label)
|
||||
}
|
||||
|
||||
/*
|
||||
SetTaskLabel sets the SELinux label for the current thread, or an error.
|
||||
This requires the dyntransition permission.
|
||||
*/
|
||||
func SetTaskLabel(label string) error {
|
||||
// setTaskLabel sets the SELinux label for the current thread, or an error.
|
||||
// This requires the dyntransition permission.
|
||||
func setTaskLabel(label string) error {
|
||||
return writeAttr("current", label)
|
||||
}
|
||||
|
||||
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||
// setSocketLabel takes a process label and tells the kernel to assign the
|
||||
// label to the next socket that gets created
|
||||
func SetSocketLabel(label string) error {
|
||||
func setSocketLabel(label string) error {
|
||||
return writeAttr("sockcreate", label)
|
||||
}
|
||||
|
||||
// SocketLabel retrieves the current socket label setting
|
||||
func SocketLabel() (string, error) {
|
||||
// socketLabel retrieves the current socket label setting
|
||||
func socketLabel() (string, error) {
|
||||
return readAttr("sockcreate")
|
||||
}
|
||||
|
||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
||||
func PeerLabel(fd uintptr) (string, error) {
|
||||
// peerLabel retrieves the label of the client on the other side of a socket
|
||||
func peerLabel(fd uintptr) (string, error) {
|
||||
return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
|
||||
}
|
||||
|
||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||
// setKeyLabel takes a process label and tells the kernel to assign the
|
||||
// label to the next kernel keyring that gets created
|
||||
func SetKeyLabel(label string) error {
|
||||
func setKeyLabel(label string) error {
|
||||
err := writeCon("/proc/self/attr/keycreate", label)
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
return nil
|
||||
@@ -506,21 +707,21 @@ func SetKeyLabel(label string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// KeyLabel retrieves the current kernel keyring label setting
|
||||
func KeyLabel() (string, error) {
|
||||
// keyLabel retrieves the current kernel keyring label setting
|
||||
func keyLabel() (string, error) {
|
||||
return readCon("/proc/self/attr/keycreate")
|
||||
}
|
||||
|
||||
// Get returns the Context as a string
|
||||
func (c Context) Get() string {
|
||||
// get returns the Context as a string
|
||||
func (c Context) get() string {
|
||||
if c["level"] != "" {
|
||||
return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"])
|
||||
}
|
||||
return fmt.Sprintf("%s:%s:%s", c["user"], c["role"], c["type"])
|
||||
}
|
||||
|
||||
// NewContext creates a new Context struct from the specified label
|
||||
func NewContext(label string) (Context, error) {
|
||||
// newContext creates a new Context struct from the specified label
|
||||
func newContext(label string) (Context, error) {
|
||||
c := make(Context)
|
||||
|
||||
if len(label) != 0 {
|
||||
@@ -538,15 +739,15 @@ func NewContext(label string) (Context, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ClearLabels clears all reserved labels
|
||||
func ClearLabels() {
|
||||
// clearLabels clears all reserved labels
|
||||
func clearLabels() {
|
||||
state.Lock()
|
||||
state.mcsList = make(map[string]bool)
|
||||
state.Unlock()
|
||||
}
|
||||
|
||||
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
||||
func ReserveLabel(label string) {
|
||||
// reserveLabel reserves the MLS/MCS level component of the specified label
|
||||
func reserveLabel(label string) {
|
||||
if len(label) != 0 {
|
||||
con := strings.SplitN(label, ":", 4)
|
||||
if len(con) > 3 {
|
||||
@@ -559,8 +760,8 @@ func selinuxEnforcePath() string {
|
||||
return path.Join(getSelinuxMountPoint(), "enforce")
|
||||
}
|
||||
|
||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||
func EnforceMode() int {
|
||||
// enforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||
func enforceMode() int {
|
||||
var enforce int
|
||||
|
||||
enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
|
||||
@@ -574,20 +775,16 @@ func EnforceMode() int {
|
||||
return enforce
|
||||
}
|
||||
|
||||
/*
|
||||
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||
Disabled is not valid, since this needs to be set at boot time.
|
||||
*/
|
||||
func SetEnforceMode(mode int) error {
|
||||
// setEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||
// Disabled is not valid, since this needs to be set at boot time.
|
||||
func setEnforceMode(mode int) error {
|
||||
return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
|
||||
}
|
||||
|
||||
/*
|
||||
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||
Permissive or Disabled. Note this is is just the default at boot time.
|
||||
EnforceMode tells you the systems current mode.
|
||||
*/
|
||||
func DefaultEnforceMode() int {
|
||||
// defaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||
// Permissive or Disabled. Note this is is just the default at boot time.
|
||||
// EnforceMode tells you the systems current mode.
|
||||
func defaultEnforceMode() int {
|
||||
switch readConfig(selinuxTag) {
|
||||
case "enforcing":
|
||||
return Enforcing
|
||||
@@ -667,11 +864,9 @@ func uniqMcs(catRange uint32) string {
|
||||
return mcs
|
||||
}
|
||||
|
||||
/*
|
||||
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
|
||||
Allowing it to be used by another process.
|
||||
*/
|
||||
func ReleaseLabel(label string) {
|
||||
// releaseLabel un-reserves the MLS/MCS Level field of the specified label,
|
||||
// allowing it to be used by another process.
|
||||
func releaseLabel(label string) {
|
||||
if len(label) != 0 {
|
||||
con := strings.SplitN(label, ":", 4)
|
||||
if len(con) > 3 {
|
||||
@@ -680,9 +875,9 @@ func ReleaseLabel(label string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ROFileLabel returns the specified SELinux readonly file label
|
||||
func ROFileLabel() string {
|
||||
return roFileLabel
|
||||
// roFileLabel returns the specified SELinux readonly file label
|
||||
func roFileLabel() string {
|
||||
return readOnlyFileLabel
|
||||
}
|
||||
|
||||
func openContextFile() (*os.File, error) {
|
||||
@@ -737,11 +932,9 @@ func loadLabels() map[string]string {
|
||||
return labels
|
||||
}
|
||||
|
||||
/*
|
||||
KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||
for kvm containers by the calling process.
|
||||
*/
|
||||
func KVMContainerLabels() (string, string) {
|
||||
// kvmContainerLabels returns the default processLabel and mountLabel to be used
|
||||
// for kvm containers by the calling process.
|
||||
func kvmContainerLabels() (string, string) {
|
||||
processLabel := labels["kvm_process"]
|
||||
if processLabel == "" {
|
||||
processLabel = labels["process"]
|
||||
@@ -750,11 +943,9 @@ func KVMContainerLabels() (string, string) {
|
||||
return addMcs(processLabel, labels["file"])
|
||||
}
|
||||
|
||||
/*
|
||||
InitContainerLabels returns the default processLabel and file labels to be
|
||||
used for containers running an init system like systemd by the calling process.
|
||||
*/
|
||||
func InitContainerLabels() (string, string) {
|
||||
// initContainerLabels returns the default processLabel and file labels to be
|
||||
// used for containers running an init system like systemd by the calling process.
|
||||
func initContainerLabels() (string, string) {
|
||||
processLabel := labels["init_process"]
|
||||
if processLabel == "" {
|
||||
processLabel = labels["process"]
|
||||
@@ -763,25 +954,23 @@ func InitContainerLabels() (string, string) {
|
||||
return addMcs(processLabel, labels["file"])
|
||||
}
|
||||
|
||||
/*
|
||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||
container labeling by the calling process.
|
||||
*/
|
||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
||||
if !GetEnabled() {
|
||||
// containerLabels returns an allocated processLabel and fileLabel to be used for
|
||||
// container labeling by the calling process.
|
||||
func containerLabels() (processLabel string, fileLabel string) {
|
||||
if !getEnabled() {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
processLabel = labels["process"]
|
||||
fileLabel = labels["file"]
|
||||
roFileLabel = labels["ro_file"]
|
||||
readOnlyFileLabel = labels["ro_file"]
|
||||
|
||||
if processLabel == "" || fileLabel == "" {
|
||||
return "", fileLabel
|
||||
}
|
||||
|
||||
if roFileLabel == "" {
|
||||
roFileLabel = fileLabel
|
||||
if readOnlyFileLabel == "" {
|
||||
readOnlyFileLabel = fileLabel
|
||||
}
|
||||
|
||||
return addMcs(processLabel, fileLabel)
|
||||
@@ -790,7 +979,7 @@ func ContainerLabels() (processLabel string, fileLabel string) {
|
||||
func addMcs(processLabel, fileLabel string) (string, string) {
|
||||
scon, _ := NewContext(processLabel)
|
||||
if scon["level"] != "" {
|
||||
mcs := uniqMcs(1024)
|
||||
mcs := uniqMcs(CategoryRange)
|
||||
scon["level"] = mcs
|
||||
processLabel = scon.Get()
|
||||
scon, _ = NewContext(fileLabel)
|
||||
@@ -800,16 +989,14 @@ func addMcs(processLabel, fileLabel string) (string, string) {
|
||||
return processLabel, fileLabel
|
||||
}
|
||||
|
||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
||||
func SecurityCheckContext(val string) error {
|
||||
// securityCheckContext validates that the SELinux label is understood by the kernel
|
||||
func securityCheckContext(val string) error {
|
||||
return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
|
||||
}
|
||||
|
||||
/*
|
||||
CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||
the dest label.
|
||||
*/
|
||||
func CopyLevel(src, dest string) (string, error) {
|
||||
// copyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||
// the dest label.
|
||||
func copyLevel(src, dest string) (string, error) {
|
||||
if src == "" {
|
||||
return "", nil
|
||||
}
|
||||
@@ -833,7 +1020,7 @@ func CopyLevel(src, dest string) (string, error) {
|
||||
return tcon.Get(), nil
|
||||
}
|
||||
|
||||
// Prevent users from relabing system files
|
||||
// Prevent users from relabeling system files
|
||||
func badPrefix(fpath string) error {
|
||||
if fpath == "" {
|
||||
return ErrEmptyPath
|
||||
@@ -848,10 +1035,10 @@ func badPrefix(fpath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chcon changes the fpath file object to the SELinux label label.
|
||||
// If fpath is a directory and recurse is true, Chcon will walk the
|
||||
// chcon changes the fpath file object to the SELinux label label.
|
||||
// If fpath is a directory and recurse is true, then chcon walks the
|
||||
// directory tree setting the label.
|
||||
func Chcon(fpath string, label string, recurse bool) error {
|
||||
func chcon(fpath string, label string, recurse bool) error {
|
||||
if fpath == "" {
|
||||
return ErrEmptyPath
|
||||
}
|
||||
@@ -876,9 +1063,9 @@ func Chcon(fpath string, label string, recurse bool) error {
|
||||
})
|
||||
}
|
||||
|
||||
// DupSecOpt takes an SELinux process label and returns security options that
|
||||
// dupSecOpt takes an SELinux process label and returns security options that
|
||||
// can be used to set the SELinux Type and Level for future container processes.
|
||||
func DupSecOpt(src string) ([]string, error) {
|
||||
func dupSecOpt(src string) ([]string, error) {
|
||||
if src == "" {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -903,8 +1090,8 @@ func DupSecOpt(src string) ([]string, error) {
|
||||
return dup, nil
|
||||
}
|
||||
|
||||
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
||||
// disableSecOpt returns a security opt that can be used to disable SELinux
|
||||
// labeling support for future container processes.
|
||||
func DisableSecOpt() []string {
|
||||
func disableSecOpt() []string {
|
||||
return []string{"disable"}
|
||||
}
|
||||
|
186
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
186
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
@@ -2,253 +2,147 @@
|
||||
|
||||
package selinux
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// Enforcing constant indicate SELinux is in enforcing mode
|
||||
Enforcing = 1
|
||||
// Permissive constant to indicate SELinux is in permissive mode
|
||||
Permissive = 0
|
||||
// Disabled constant to indicate SELinux is disabled
|
||||
Disabled = -1
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
||||
// ErrEmptyPath is returned when an empty path has been specified.
|
||||
ErrEmptyPath = errors.New("empty path")
|
||||
)
|
||||
|
||||
// Context is a representation of the SELinux label broken into 4 parts
|
||||
type Context map[string]string
|
||||
|
||||
// SetDisabled disables selinux support for the package
|
||||
func SetDisabled() {
|
||||
return
|
||||
func setDisabled() {
|
||||
}
|
||||
|
||||
// GetEnabled returns whether selinux is currently enabled.
|
||||
func GetEnabled() bool {
|
||||
func getEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
||||
func ClassIndex(class string) (int, error) {
|
||||
func classIndex(class string) (int, error) {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||
func SetFileLabel(fpath string, label string) error {
|
||||
func setFileLabel(fpath string, label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileLabel returns the SELinux label for this path or returns an error.
|
||||
func FileLabel(fpath string) (string, error) {
|
||||
func fileLabel(fpath string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetFSCreateLabel tells kernel the label to create all file system objects
|
||||
created by this task. Setting label="" to return to default.
|
||||
*/
|
||||
func SetFSCreateLabel(label string) error {
|
||||
func setFSCreateLabel(label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
FSCreateLabel returns the default label the kernel which the kernel is using
|
||||
for file system objects created by this task. "" indicates default.
|
||||
*/
|
||||
func FSCreateLabel() (string, error) {
|
||||
func fsCreateLabel() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
||||
func CurrentLabel() (string, error) {
|
||||
func currentLabel() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
||||
func PidLabel(pid int) (string, error) {
|
||||
func pidLabel(pid int) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
/*
|
||||
ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||
that are executed by the current process thread, or an error.
|
||||
*/
|
||||
func ExecLabel() (string, error) {
|
||||
func execLabel() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
/*
|
||||
CanonicalizeContext takes a context string and writes it to the kernel
|
||||
the function then returns the context that the kernel will use. This function
|
||||
can be used to see if two contexts are equivalent
|
||||
*/
|
||||
func CanonicalizeContext(val string) (string, error) {
|
||||
func canonicalizeContext(val string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
/*
|
||||
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
||||
*/
|
||||
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||
func computeCreateContext(source string, target string, class string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||
that are executed by the current process thread, or an error.
|
||||
*/
|
||||
func SetExecLabel(label string) error {
|
||||
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func setExecLabel(label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetTaskLabel sets the SELinux label for the current thread, or an error.
|
||||
This requires the dyntransition permission.
|
||||
*/
|
||||
func SetTaskLabel(label string) error {
|
||||
func setTaskLabel(label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetSocketLabel sets the SELinux label that the kernel will use for any programs
|
||||
that are executed by the current process thread, or an error.
|
||||
*/
|
||||
func SetSocketLabel(label string) error {
|
||||
func setSocketLabel(label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SocketLabel retrieves the current socket label setting
|
||||
func SocketLabel() (string, error) {
|
||||
func socketLabel() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
||||
func PeerLabel(fd uintptr) (string, error) {
|
||||
func peerLabel(fd uintptr) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||
// label to the next kernel keyring that gets created
|
||||
func SetKeyLabel(label string) error {
|
||||
func setKeyLabel(label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeyLabel retrieves the current kernel keyring label setting
|
||||
func KeyLabel() (string, error) {
|
||||
func keyLabel() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Get returns the Context as a string
|
||||
func (c Context) Get() string {
|
||||
func (c Context) get() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewContext creates a new Context struct from the specified label
|
||||
func NewContext(label string) (Context, error) {
|
||||
func newContext(label string) (Context, error) {
|
||||
c := make(Context)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ClearLabels clears all reserved MLS/MCS levels
|
||||
func ClearLabels() {
|
||||
return
|
||||
func clearLabels() {
|
||||
}
|
||||
|
||||
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
||||
func ReserveLabel(label string) {
|
||||
return
|
||||
func reserveLabel(label string) {
|
||||
}
|
||||
|
||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||
func EnforceMode() int {
|
||||
func enforceMode() int {
|
||||
return Disabled
|
||||
}
|
||||
|
||||
/*
|
||||
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||
Disabled is not valid, since this needs to be set at boot time.
|
||||
*/
|
||||
func SetEnforceMode(mode int) error {
|
||||
func setEnforceMode(mode int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||
Permissive or Disabled. Note this is is just the default at boot time.
|
||||
EnforceMode tells you the systems current mode.
|
||||
*/
|
||||
func DefaultEnforceMode() int {
|
||||
func defaultEnforceMode() int {
|
||||
return Disabled
|
||||
}
|
||||
|
||||
/*
|
||||
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
|
||||
Allowing it to be used by another process.
|
||||
*/
|
||||
func ReleaseLabel(label string) {
|
||||
return
|
||||
func releaseLabel(label string) {
|
||||
}
|
||||
|
||||
// ROFileLabel returns the specified SELinux readonly file label
|
||||
func ROFileLabel() string {
|
||||
func roFileLabel() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||
// for kvm containers by the calling process.
|
||||
func KVMContainerLabels() (string, string) {
|
||||
func kvmContainerLabels() (string, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// InitContainerLabels returns the default processLabel and file labels to be
|
||||
// used for containers running an init system like systemd by the calling
|
||||
func InitContainerLabels() (string, string) {
|
||||
func initContainerLabels() (string, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
/*
|
||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||
container labeling by the calling process.
|
||||
*/
|
||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
||||
func containerLabels() (processLabel string, fileLabel string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
||||
func SecurityCheckContext(val string) error {
|
||||
func securityCheckContext(val string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||
the dest label.
|
||||
*/
|
||||
func CopyLevel(src, dest string) (string, error) {
|
||||
func copyLevel(src, dest string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Chcon changes the `fpath` file object to the SELinux label `label`.
|
||||
// If `fpath` is a directory and `recurse`` is true, Chcon will walk the
|
||||
// directory tree setting the label.
|
||||
func Chcon(fpath string, label string, recurse bool) error {
|
||||
func chcon(fpath string, label string, recurse bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DupSecOpt takes an SELinux process label and returns security options that
|
||||
// can be used to set the SELinux Type and Level for future container processes.
|
||||
func DupSecOpt(src string) ([]string, error) {
|
||||
func dupSecOpt(src string) ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
||||
// labeling support for future container processes.
|
||||
func DisableSecOpt() []string {
|
||||
func disableSecOpt() []string {
|
||||
return []string{"disable"}
|
||||
}
|
||||
|
8
vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
generated
vendored
8
vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
generated
vendored
@@ -48,7 +48,11 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
|
||||
errCh := make(chan error, 1) // get the first error, ignore others
|
||||
|
||||
// Start walking a tree asap
|
||||
var err error
|
||||
var (
|
||||
err error
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
@@ -68,9 +72,9 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
|
||||
if err == nil {
|
||||
close(files)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(num)
|
||||
for i := 0; i < num; i++ {
|
||||
go func() {
|
||||
|
Reference in New Issue
Block a user