From 8cf929c0950e985880b268ae4c8ad08d98bc4073 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 18 Jan 2019 15:01:53 -0500 Subject: Vendor in latest opencontainers/selinux This will now verify labels passed in by the user. Will also prevent users from accidently relabeling their homedir. podman run -ti -v ~/home/user:Z fedora sh Is not a good idea. Signed-off-by: Daniel J Walsh --- .../selinux/go-selinux/label/label.go | 4 +- .../selinux/go-selinux/label/label_selinux.go | 62 ++++++++++++++++++++-- .../selinux/go-selinux/selinux_linux.go | 36 +++++++++---- .../selinux/go-selinux/selinux_stub.go | 8 +-- 4 files changed, 88 insertions(+), 22 deletions(-) (limited to 'vendor') diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go index bb27ac936..4e9a8c54f 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go @@ -75,8 +75,8 @@ func ReleaseLabel(label string) error { // DupSecOpt takes a process label and returns security options that // can be used to set duplicate labels on future container processes -func DupSecOpt(src string) []string { - return nil +func DupSecOpt(src string) ([]string, error) { + return nil, nil } // DisableSecOpt returns a security opt that can disable labeling diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go index de214b2d5..d4e26909d 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go @@ -4,6 +4,8 @@ package label import ( "fmt" + "os" + "os/user" "strings" "github.com/opencontainers/selinux/go-selinux" @@ -35,8 +37,15 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) { ReleaseLabel(mountLabel) } }() - pcon := selinux.NewContext(processLabel) - mcon := selinux.NewContext(mountLabel) + pcon, err := selinux.NewContext(processLabel) + if err != nil { + return "", "", err + } + + mcon, err := selinux.NewContext(mountLabel) + if err != nil { + return "", "", err + } for _, opt := range options { if opt == "disable" { return "", mountLabel, nil @@ -146,13 +155,56 @@ func Relabel(path string, fileLabel string, shared bool) error { return nil } - exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true, "/tmp": true, "/home": true, "/run": true, "/var": true, "/root": true} + exclude_paths := map[string]bool{ + "/": true, + "/bin": true, + "/boot": true, + "/dev": true, + "/etc": true, + "/etc/passwd": true, + "/etc/pki": true, + "/etc/shadow": true, + "/home": true, + "/lib": true, + "/lib64": true, + "/media": true, + "/opt": true, + "/proc": true, + "/root": true, + "/run": true, + "/sbin": true, + "/srv": true, + "/sys": true, + "/tmp": true, + "/usr": true, + "/var": true, + "/var/lib": true, + "/var/log": true, + } + + if home := os.Getenv("HOME"); home != "" { + exclude_paths[home] = true + } + + if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" { + if usr, err := user.Lookup(sudoUser); err == nil { + exclude_paths[usr.HomeDir] = true + } + } + + if path != "/" { + path = strings.TrimSuffix(path, "/") + } if exclude_paths[path] { return fmt.Errorf("SELinux relabeling of %s is not allowed", path) } if shared { - c := selinux.NewContext(fileLabel) + c, err := selinux.NewContext(fileLabel) + if err != nil { + return err + } + c["level"] = "s0" fileLabel = c.Get() } @@ -195,7 +247,7 @@ func ReleaseLabel(label string) error { // DupSecOpt takes a process label and returns security options that // can be used to set duplicate labels on future container processes -func DupSecOpt(src string) []string { +func DupSecOpt(src string) ([]string, error) { return selinux.DupSecOpt(src) } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 7832f7497..5adafd317 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -52,6 +52,8 @@ var ( 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") assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`) roFileLabel string @@ -405,11 +407,14 @@ func (c Context) Get() string { } // NewContext creates a new Context struct from the specified label -func NewContext(label string) Context { +func NewContext(label string) (Context, error) { c := make(Context) if len(label) != 0 { con := strings.SplitN(label, ":", 4) + if len(con) < 3 { + return c, InvalidLabel + } c["user"] = con[0] c["role"] = con[1] c["type"] = con[2] @@ -417,7 +422,7 @@ func NewContext(label string) Context { c["level"] = con[3] } } - return c + return c, nil } // ClearLabels clears all reserved labels @@ -630,12 +635,12 @@ func ContainerLabels() (processLabel string, fileLabel string) { roFileLabel = fileLabel } exit: - scon := NewContext(processLabel) + scon, _ := NewContext(processLabel) if scon["level"] != "" { mcs := uniqMcs(1024) scon["level"] = mcs processLabel = scon.Get() - scon = NewContext(fileLabel) + scon, _ = NewContext(fileLabel) scon["level"] = mcs fileLabel = scon.Get() } @@ -661,8 +666,14 @@ func CopyLevel(src, dest string) (string, error) { if err := SecurityCheckContext(dest); err != nil { return "", err } - scon := NewContext(src) - tcon := NewContext(dest) + scon, err := NewContext(src) + if err != nil { + return "", err + } + tcon, err := NewContext(dest) + if err != nil { + return "", err + } mcsDelete(tcon["level"]) mcsAdd(scon["level"]) tcon["level"] = scon["level"] @@ -714,15 +725,18 @@ func Chcon(fpath string, label string, recurse bool) error { // 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 { +func DupSecOpt(src string) ([]string, error) { if src == "" { - return nil + return nil, nil + } + con, err := NewContext(src) + if err != nil { + return nil, err } - con := NewContext(src) if con["user"] == "" || con["role"] == "" || con["type"] == "" { - return nil + return nil, nil } dup := []string{"user:" + con["user"], "role:" + con["role"], @@ -733,7 +747,7 @@ func DupSecOpt(src string) []string { dup = append(dup, "level:"+con["level"]) } - return dup + return dup, nil } // DisableSecOpt returns a security opt that can be used to disable SELinux diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 99efa155a..9497acbd0 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -115,9 +115,9 @@ func (c Context) Get() string { } // NewContext creates a new Context struct from the specified label -func NewContext(label string) Context { +func NewContext(label string) (Context, error) { c := make(Context) - return c + return c, nil } // ClearLabels clears all reserved MLS/MCS levels @@ -195,8 +195,8 @@ func Chcon(fpath string, label string, recurse bool) error { // 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 { - return nil +func DupSecOpt(src string) ([]string, error) { + return nil, nil } // DisableSecOpt returns a security opt that can be used to disable SELinux -- cgit v1.2.3-54-g00ecf