update selinux to b6fa367
Signed-off-by: Yanqiang Miao <miao.yanqiang@zte.com.cn>
This commit is contained in:
		| @@ -371,8 +371,7 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error) | |||||||
| 	// Should ignored selinuxOpts if they are incomplete. | 	// Should ignored selinuxOpts if they are incomplete. | ||||||
| 	if selinuxOpt.GetUser() == "" || | 	if selinuxOpt.GetUser() == "" || | ||||||
| 		selinuxOpt.GetRole() == "" || | 		selinuxOpt.GetRole() == "" || | ||||||
| 		selinuxOpt.GetType() == "" || | 		selinuxOpt.GetType() == "" { | ||||||
| 		selinuxOpt.GetLevel() == "" { |  | ||||||
| 		return "", "", nil | 		return "", "", nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -391,6 +390,10 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error) | |||||||
| } | } | ||||||
|  |  | ||||||
| func checkSelinuxLevel(level string) (bool, error) { | func checkSelinuxLevel(level string) (bool, error) { | ||||||
|  | 	if len(level) == 0 { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level) | 	matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level) | ||||||
| 	if err != nil || !matched { | 	if err != nil || !matched { | ||||||
| 		return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err) | 		return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err) | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ limitations under the License. | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"github.com/opencontainers/selinux/go-selinux" | 	"github.com/opencontainers/selinux/go-selinux" | ||||||
| @@ -62,6 +63,16 @@ func TestInitSelinuxOpts(t *testing.T) { | |||||||
| 			processLabel: "user_u:user_r:user_t:s0:c1,c2", | 			processLabel: "user_u:user_r:user_t:s0:c1,c2", | ||||||
| 			mountLabels:  []string{"user_u:object_r:container_file_t:s0:c1,c2", "user_u:object_r:svirt_sandbox_file_t:s0:c1,c2"}, | 			mountLabels:  []string{"user_u:object_r:container_file_t:s0:c1,c2", "user_u:object_r:svirt_sandbox_file_t:s0:c1,c2"}, | ||||||
| 		}, | 		}, | ||||||
|  | 		"Should be resolved correctly when selinuxOpt has been initialized with level=''": { | ||||||
|  | 			selinuxOpt: &runtime.SELinuxOption{ | ||||||
|  | 				User:  "user_u", | ||||||
|  | 				Role:  "user_r", | ||||||
|  | 				Type:  "user_t", | ||||||
|  | 				Level: "", | ||||||
|  | 			}, | ||||||
|  | 			processLabel: "user_u:user_r:user_t:s0", | ||||||
|  | 			mountLabels:  []string{"user_u:object_r:container_file_t:s0", "user_u:object_r:svirt_sandbox_file_t:s0"}, | ||||||
|  | 		}, | ||||||
| 		"Should return error when the format of 'level' is not correct": { | 		"Should return error when the format of 'level' is not correct": { | ||||||
| 			selinuxOpt: &runtime.SELinuxOption{ | 			selinuxOpt: &runtime.SELinuxOption{ | ||||||
| 				User:  "user_u", | 				User:  "user_u", | ||||||
| @@ -78,8 +89,15 @@ func TestInitSelinuxOpts(t *testing.T) { | |||||||
| 				assert.Error(t, err) | 				assert.Error(t, err) | ||||||
| 			} else { | 			} else { | ||||||
| 				assert.NoError(t, err) | 				assert.NoError(t, err) | ||||||
| 				assert.Equal(t, test.processLabel, processLabel) | 				if test.selinuxOpt == nil || test.selinuxOpt.Level != "" { | ||||||
| 				assert.Contains(t, test.mountLabels, mountLabel) | 					assert.Equal(t, test.processLabel, processLabel) | ||||||
|  | 					assert.Contains(t, test.mountLabels, mountLabel) | ||||||
|  | 				} else { | ||||||
|  | 					assert.Equal(t, 0, strings.LastIndex(processLabel, test.processLabel)) | ||||||
|  | 					contain := strings.LastIndex(mountLabel, test.mountLabels[0]) == 0 || | ||||||
|  | 						strings.LastIndex(mountLabel, test.mountLabels[1]) == 0 | ||||||
|  | 					assert.True(t, contain) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ github.com/opencontainers/image-spec v1.0.1 | |||||||
| github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340 | github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340 | ||||||
| github.com/opencontainers/runtime-spec v1.0.1 | github.com/opencontainers/runtime-spec v1.0.1 | ||||||
| github.com/opencontainers/runtime-tools v0.6.0 | github.com/opencontainers/runtime-tools v0.6.0 | ||||||
| github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206 | github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a | ||||||
| github.com/pkg/errors v0.8.0 | github.com/pkg/errors v0.8.0 | ||||||
| github.com/pmezard/go-difflib v1.0.0 | github.com/pmezard/go-difflib v1.0.0 | ||||||
| github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823 | github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823 | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -49,8 +49,10 @@ func InitLabels(options []string) (string, string, error) { | |||||||
| 				mcon[con[0]] = con[1] | 				mcon[con[0]] = con[1] | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		_ = ReleaseLabel(processLabel) | ||||||
| 		processLabel = pcon.Get() | 		processLabel = pcon.Get() | ||||||
| 		mountLabel = mcon.Get() | 		mountLabel = mcon.Get() | ||||||
|  | 		_ = ReserveLabel(processLabel) | ||||||
| 	} | 	} | ||||||
| 	return processLabel, mountLabel, nil | 	return processLabel, mountLabel, nil | ||||||
| } | } | ||||||
| @@ -85,9 +87,6 @@ func FormatMountLabel(src, mountLabel string) string { | |||||||
| // SetProcessLabel takes a process label and tells the kernel to assign the | // SetProcessLabel takes a process label and tells the kernel to assign the | ||||||
| // label to the next program executed by the current process. | // label to the next program executed by the current process. | ||||||
| func SetProcessLabel(processLabel string) error { | func SetProcessLabel(processLabel string) error { | ||||||
| 	if processLabel == "" { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return selinux.SetExecLabel(processLabel) | 	return selinux.SetExecLabel(processLabel) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -131,7 +130,7 @@ func Relabel(path string, fileLabel string, shared bool) error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true} | 	exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true, "/tmp": true, "/home": true, "/run": true, "/var": true, "/root": true} | ||||||
| 	if exclude_paths[path] { | 	if exclude_paths[path] { | ||||||
| 		return fmt.Errorf("SELinux relabeling of %s is not allowed", path) | 		return fmt.Errorf("SELinux relabeling of %s is not allowed", path) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1,13 +1,16 @@ | |||||||
| // +build linux | // +build selinux,linux | ||||||
| 
 | 
 | ||||||
| package selinux | package selinux | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
|  | 	"bytes" | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| 	"encoding/binary" | 	"encoding/binary" | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| @@ -23,14 +26,16 @@ const ( | |||||||
| 	// Permissive constant to indicate SELinux is in permissive mode | 	// Permissive constant to indicate SELinux is in permissive mode | ||||||
| 	Permissive = 0 | 	Permissive = 0 | ||||||
| 	// Disabled constant to indicate SELinux is disabled | 	// Disabled constant to indicate SELinux is disabled | ||||||
| 	Disabled         = -1 | 	Disabled = -1 | ||||||
|  | 
 | ||||||
| 	selinuxDir       = "/etc/selinux/" | 	selinuxDir       = "/etc/selinux/" | ||||||
| 	selinuxConfig    = selinuxDir + "config" | 	selinuxConfig    = selinuxDir + "config" | ||||||
|  | 	selinuxfsMount   = "/sys/fs/selinux" | ||||||
| 	selinuxTypeTag   = "SELINUXTYPE" | 	selinuxTypeTag   = "SELINUXTYPE" | ||||||
| 	selinuxTag       = "SELINUX" | 	selinuxTag       = "SELINUX" | ||||||
| 	selinuxPath      = "/sys/fs/selinux" |  | ||||||
| 	xattrNameSelinux = "security.selinux" | 	xattrNameSelinux = "security.selinux" | ||||||
| 	stRdOnly         = 0x01 | 	stRdOnly         = 0x01 | ||||||
|  | 	selinuxfsMagic   = 0xf97cff8c | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type selinuxState struct { | type selinuxState struct { | ||||||
| @@ -43,7 +48,13 @@ type selinuxState struct { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | 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") | ||||||
|  | 
 | ||||||
| 	assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`) | 	assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`) | ||||||
|  | 	roFileLabel string | ||||||
| 	state       = selinuxState{ | 	state       = selinuxState{ | ||||||
| 		mcsList: make(map[string]bool), | 		mcsList: make(map[string]bool), | ||||||
| 	} | 	} | ||||||
| @@ -91,6 +102,83 @@ func (s *selinuxState) setSELinuxfs(selinuxfs string) string { | |||||||
| 	return s.selinuxfs | 	return s.selinuxfs | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func verifySELinuxfsMount(mnt string) bool { | ||||||
|  | 	var buf syscall.Statfs_t | ||||||
|  | 	for { | ||||||
|  | 		err := syscall.Statfs(mnt, &buf) | ||||||
|  | 		if err == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		if err == syscall.EAGAIN { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	if uint32(buf.Type) != uint32(selinuxfsMagic) { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	if (buf.Flags & stRdOnly) != 0 { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func findSELinuxfs() string { | ||||||
|  | 	// fast path: check the default mount first | ||||||
|  | 	if verifySELinuxfsMount(selinuxfsMount) { | ||||||
|  | 		return selinuxfsMount | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// check if selinuxfs is available before going the slow path | ||||||
|  | 	fs, err := ioutil.ReadFile("/proc/filesystems") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	if !bytes.Contains(fs, []byte("\tselinuxfs\n")) { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// slow path: try to find among the mounts | ||||||
|  | 	f, err := os.Open("/proc/self/mountinfo") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	defer f.Close() | ||||||
|  | 
 | ||||||
|  | 	scanner := bufio.NewScanner(f) | ||||||
|  | 	for { | ||||||
|  | 		mnt := findSELinuxfsMount(scanner) | ||||||
|  | 		if mnt == "" { // error or not found | ||||||
|  | 			return "" | ||||||
|  | 		} | ||||||
|  | 		if verifySELinuxfsMount(mnt) { | ||||||
|  | 			return mnt | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // findSELinuxfsMount returns a next selinuxfs mount point found, | ||||||
|  | // if there is one, or an empty string in case of EOF or error. | ||||||
|  | func findSELinuxfsMount(s *bufio.Scanner) string { | ||||||
|  | 	for s.Scan() { | ||||||
|  | 		txt := s.Text() | ||||||
|  | 		// The first field after - is fs type. | ||||||
|  | 		// Safe as spaces in mountpoints are encoded as \040 | ||||||
|  | 		if !strings.Contains(txt, " - selinuxfs ") { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		const mPos = 5 // mount point is 5th field | ||||||
|  | 		fields := strings.SplitN(txt, " ", mPos+1) | ||||||
|  | 		if len(fields) < mPos+1 { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		return fields[mPos-1] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (s *selinuxState) getSELinuxfs() string { | func (s *selinuxState) getSELinuxfs() string { | ||||||
| 	s.Lock() | 	s.Lock() | ||||||
| 	selinuxfs := s.selinuxfs | 	selinuxfs := s.selinuxfs | ||||||
| @@ -100,40 +188,7 @@ func (s *selinuxState) getSELinuxfs() string { | |||||||
| 		return selinuxfs | 		return selinuxfs | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	selinuxfs = "" | 	return s.setSELinuxfs(findSELinuxfs()) | ||||||
| 	f, err := os.Open("/proc/self/mountinfo") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return selinuxfs |  | ||||||
| 	} |  | ||||||
| 	defer f.Close() |  | ||||||
| 
 |  | ||||||
| 	scanner := bufio.NewScanner(f) |  | ||||||
| 	for scanner.Scan() { |  | ||||||
| 		txt := scanner.Text() |  | ||||||
| 		// Safe as mountinfo encodes mountpoints with spaces as \040. |  | ||||||
| 		sepIdx := strings.Index(txt, " - ") |  | ||||||
| 		if sepIdx == -1 { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if !strings.Contains(txt[sepIdx:], "selinuxfs") { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		fields := strings.Split(txt, " ") |  | ||||||
| 		if len(fields) < 5 { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		selinuxfs = fields[4] |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if selinuxfs != "" { |  | ||||||
| 		var buf syscall.Statfs_t |  | ||||||
| 		syscall.Statfs(selinuxfs, &buf) |  | ||||||
| 		if (buf.Flags & stRdOnly) == 1 { |  | ||||||
| 			selinuxfs = "" |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return s.setSELinuxfs(selinuxfs) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs | // getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs | ||||||
| @@ -150,7 +205,7 @@ func GetEnabled() bool { | |||||||
| 	return state.getEnabled() | 	return state.getEnabled() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func readConfig(target string) (value string) { | func readConfig(target string) string { | ||||||
| 	var ( | 	var ( | ||||||
| 		val, key string | 		val, key string | ||||||
| 		bufin    *bufio.Reader | 		bufin    *bufio.Reader | ||||||
| @@ -192,30 +247,42 @@ func readConfig(target string) (value string) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getSELinuxPolicyRoot() string { | func getSELinuxPolicyRoot() string { | ||||||
| 	return selinuxDir + readConfig(selinuxTypeTag) | 	return filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func readCon(name string) (string, error) { | func readCon(fpath string) (string, error) { | ||||||
| 	var val string | 	if fpath == "" { | ||||||
|  | 		return "", ErrEmptyPath | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	in, err := os.Open(name) | 	in, err := os.Open(fpath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	defer in.Close() | 	defer in.Close() | ||||||
| 
 | 
 | ||||||
| 	_, err = fmt.Fscanf(in, "%s", &val) | 	var retval string | ||||||
| 	return val, err | 	if _, err := fmt.Fscanf(in, "%s", &retval); err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return strings.Trim(retval, "\x00"), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetFileLabel sets the SELinux label for this path or returns an error. | // SetFileLabel sets the SELinux label for this path or returns an error. | ||||||
| func SetFileLabel(path string, label string) error { | func SetFileLabel(fpath string, label string) error { | ||||||
| 	return lsetxattr(path, xattrNameSelinux, []byte(label), 0) | 	if fpath == "" { | ||||||
|  | 		return ErrEmptyPath | ||||||
|  | 	} | ||||||
|  | 	return lsetxattr(fpath, xattrNameSelinux, []byte(label), 0) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FileLabel returns the SELinux label for this path or returns an error. | // FileLabel returns the SELinux label for this path or returns an error. | ||||||
| func FileLabel(path string) (string, error) { | func FileLabel(fpath string) (string, error) { | ||||||
| 	label, err := lgetxattr(path, xattrNameSelinux) | 	if fpath == "" { | ||||||
|  | 		return "", ErrEmptyPath | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label, err := lgetxattr(fpath, xattrNameSelinux) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -260,8 +327,12 @@ func ExecLabel() (string, error) { | |||||||
| 	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid())) | 	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid())) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func writeCon(name string, val string) error { | func writeCon(fpath string, val string) error { | ||||||
| 	out, err := os.OpenFile(name, os.O_WRONLY, 0) | 	if fpath == "" { | ||||||
|  | 		return ErrEmptyPath | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	out, err := os.OpenFile(fpath, os.O_WRONLY, 0) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -275,6 +346,37 @@ func writeCon(name string, val string) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* | ||||||
|  | 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) { | ||||||
|  | 	return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func readWriteCon(fpath string, val string) (string, error) { | ||||||
|  | 	if fpath == "" { | ||||||
|  | 		return "", ErrEmptyPath | ||||||
|  | 	} | ||||||
|  | 	f, err := os.OpenFile(fpath, os.O_RDWR, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	defer f.Close() | ||||||
|  | 
 | ||||||
|  | 	_, err = f.Write([]byte(val)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var retval string | ||||||
|  | 	if _, err := fmt.Fscanf(f, "%s", &retval); err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return strings.Trim(retval, "\x00"), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* | /* | ||||||
| SetExecLabel sets the SELinux label that the kernel will use for any programs | SetExecLabel sets the SELinux label that the kernel will use for any programs | ||||||
| that are executed by the current process thread, or an error. | that are executed by the current process thread, or an error. | ||||||
| @@ -285,7 +387,10 @@ func SetExecLabel(label string) error { | |||||||
| 
 | 
 | ||||||
| // Get returns the Context as a string | // Get returns the Context as a string | ||||||
| func (c Context) Get() string { | func (c Context) Get() string { | ||||||
| 	return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"]) | 	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 | // NewContext creates a new Context struct from the specified label | ||||||
| @@ -297,7 +402,9 @@ func NewContext(label string) Context { | |||||||
| 		c["user"] = con[0] | 		c["user"] = con[0] | ||||||
| 		c["role"] = con[1] | 		c["role"] = con[1] | ||||||
| 		c["type"] = con[2] | 		c["type"] = con[2] | ||||||
| 		c["level"] = con[3] | 		if len(con) > 3 { | ||||||
|  | 			c["level"] = con[3] | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	return c | 	return c | ||||||
| } | } | ||||||
| @@ -306,12 +413,14 @@ func NewContext(label string) Context { | |||||||
| func ReserveLabel(label string) { | func ReserveLabel(label string) { | ||||||
| 	if len(label) != 0 { | 	if len(label) != 0 { | ||||||
| 		con := strings.SplitN(label, ":", 4) | 		con := strings.SplitN(label, ":", 4) | ||||||
| 		mcsAdd(con[3]) | 		if len(con) > 3 { | ||||||
|  | 			mcsAdd(con[3]) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func selinuxEnforcePath() string { | func selinuxEnforcePath() string { | ||||||
| 	return fmt.Sprintf("%s/enforce", selinuxPath) | 	return fmt.Sprintf("%s/enforce", getSelinuxMountPoint()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled | // EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled | ||||||
| @@ -354,16 +463,22 @@ func DefaultEnforceMode() int { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func mcsAdd(mcs string) error { | func mcsAdd(mcs string) error { | ||||||
|  | 	if mcs == "" { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
| 	state.Lock() | 	state.Lock() | ||||||
| 	defer state.Unlock() | 	defer state.Unlock() | ||||||
| 	if state.mcsList[mcs] { | 	if state.mcsList[mcs] { | ||||||
| 		return fmt.Errorf("MCS Label already exists") | 		return ErrMCSAlreadyExists | ||||||
| 	} | 	} | ||||||
| 	state.mcsList[mcs] = true | 	state.mcsList[mcs] = true | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func mcsDelete(mcs string) { | func mcsDelete(mcs string) { | ||||||
|  | 	if mcs == "" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	state.Lock() | 	state.Lock() | ||||||
| 	defer state.Unlock() | 	defer state.Unlock() | ||||||
| 	state.mcsList[mcs] = false | 	state.mcsList[mcs] = false | ||||||
| @@ -424,14 +539,14 @@ Allowing it to be used by another process. | |||||||
| func ReleaseLabel(label string) { | func ReleaseLabel(label string) { | ||||||
| 	if len(label) != 0 { | 	if len(label) != 0 { | ||||||
| 		con := strings.SplitN(label, ":", 4) | 		con := strings.SplitN(label, ":", 4) | ||||||
| 		mcsDelete(con[3]) | 		if len(con) > 3 { | ||||||
|  | 			mcsDelete(con[3]) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var roFileLabel string |  | ||||||
| 
 |  | ||||||
| // ROFileLabel returns the specified SELinux readonly file label | // ROFileLabel returns the specified SELinux readonly file label | ||||||
| func ROFileLabel() (fileLabel string) { | func ROFileLabel() string { | ||||||
| 	return roFileLabel | 	return roFileLabel | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -497,23 +612,25 @@ func ContainerLabels() (processLabel string, fileLabel string) { | |||||||
| 		roFileLabel = fileLabel | 		roFileLabel = fileLabel | ||||||
| 	} | 	} | ||||||
| exit: | exit: | ||||||
| 	mcs := uniqMcs(1024) |  | ||||||
| 	scon := NewContext(processLabel) | 	scon := NewContext(processLabel) | ||||||
| 	scon["level"] = mcs | 	if scon["level"] != "" { | ||||||
| 	processLabel = scon.Get() | 		mcs := uniqMcs(1024) | ||||||
| 	scon = NewContext(fileLabel) | 		scon["level"] = mcs | ||||||
| 	scon["level"] = mcs | 		processLabel = scon.Get() | ||||||
| 	fileLabel = scon.Get() | 		scon = NewContext(fileLabel) | ||||||
|  | 		scon["level"] = mcs | ||||||
|  | 		fileLabel = scon.Get() | ||||||
|  | 	} | ||||||
| 	return processLabel, fileLabel | 	return processLabel, fileLabel | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SecurityCheckContext validates that the SELinux label is understood by the kernel | // SecurityCheckContext validates that the SELinux label is understood by the kernel | ||||||
| func SecurityCheckContext(val string) error { | func SecurityCheckContext(val string) error { | ||||||
| 	return writeCon(fmt.Sprintf("%s.context", selinuxPath), val) | 	return writeCon(fmt.Sprintf("%s/context", getSelinuxMountPoint()), val) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| CopyLevel returns a label with the MLS/MCS level from src label replaces on | CopyLevel returns a label with the MLS/MCS level from src label replaced on | ||||||
| the dest label. | the dest label. | ||||||
| */ | */ | ||||||
| func CopyLevel(src, dest string) (string, error) { | func CopyLevel(src, dest string) (string, error) { | ||||||
| @@ -536,20 +653,26 @@ func CopyLevel(src, dest string) (string, error) { | |||||||
| 
 | 
 | ||||||
| // Prevent users from relabing system files | // Prevent users from relabing system files | ||||||
| func badPrefix(fpath string) error { | func badPrefix(fpath string) error { | ||||||
| 	var badprefixes = []string{"/usr"} | 	if fpath == "" { | ||||||
|  | 		return ErrEmptyPath | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, prefix := range badprefixes { | 	badPrefixes := []string{"/usr"} | ||||||
| 		if fpath == prefix || strings.HasPrefix(fpath, fmt.Sprintf("%s/", prefix)) { | 	for _, prefix := range badPrefixes { | ||||||
|  | 		if strings.HasPrefix(fpath, prefix) { | ||||||
| 			return fmt.Errorf("relabeling content in %s is not allowed", prefix) | 			return fmt.Errorf("relabeling content in %s is not allowed", prefix) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Chcon changes the fpath file object to the SELinux label label. | // Chcon changes the `fpath` file object to the SELinux label `label`. | ||||||
| // If the fpath is a directory and recurse is true Chcon will walk the | // If `fpath` is a directory and `recurse`` is true, Chcon will walk the | ||||||
| // directory tree setting the label | // 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 | ||||||
|  | 	} | ||||||
| 	if label == "" { | 	if label == "" { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -568,7 +691,7 @@ 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 will set the SELinux Type and Level for future container processes | // can be used to set the SELinux Type and Level for future container processes. | ||||||
| func DupSecOpt(src string) []string { | func DupSecOpt(src string) []string { | ||||||
| 	if src == "" { | 	if src == "" { | ||||||
| 		return nil | 		return nil | ||||||
| @@ -576,18 +699,23 @@ func DupSecOpt(src string) []string { | |||||||
| 	con := NewContext(src) | 	con := NewContext(src) | ||||||
| 	if con["user"] == "" || | 	if con["user"] == "" || | ||||||
| 		con["role"] == "" || | 		con["role"] == "" || | ||||||
| 		con["type"] == "" || | 		con["type"] == "" { | ||||||
| 		con["level"] == "" { |  | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	return []string{"user:" + con["user"], | 	dup := []string{"user:" + con["user"], | ||||||
| 		"role:" + con["role"], | 		"role:" + con["role"], | ||||||
| 		"type:" + con["type"], | 		"type:" + con["type"], | ||||||
| 		"level:" + con["level"]} | 	} | ||||||
|  | 
 | ||||||
|  | 	if con["level"] != "" { | ||||||
|  | 		dup = append(dup, "level:"+con["level"]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return dup | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DisableSecOpt returns a security opt that can be used to disabling SELinux | // DisableSecOpt returns a security opt that can be used to disable SELinux | ||||||
| // labeling support for future container processes | // labeling support for future container processes. | ||||||
| func DisableSecOpt() []string { | func DisableSecOpt() []string { | ||||||
| 	return []string{"disable"} | 	return []string{"disable"} | ||||||
| } | } | ||||||
							
								
								
									
										188
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | // +build !selinux | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetEnabled returns whether selinux is currently enabled. | ||||||
|  | func GetEnabled() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetFileLabel sets the SELinux label for this path or returns an 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) { | ||||||
|  | 	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 { | ||||||
|  | 	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) { | ||||||
|  | 	return "", nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CurrentLabel returns the SELinux label of the current process thread, or an 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) { | ||||||
|  | 	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) { | ||||||
|  | 	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) { | ||||||
|  | 	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 { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the Context as a string | ||||||
|  | func (c Context) Get() string { | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewContext creates a new Context struct from the specified label | ||||||
|  | func NewContext(label string) Context { | ||||||
|  | 	c := make(Context) | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ReserveLabel reserves the MLS/MCS level component of the specified label | ||||||
|  | func ReserveLabel(label string) { | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled | ||||||
|  | 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 { | ||||||
|  | 	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 { | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ROFileLabel returns the specified SELinux readonly file label | ||||||
|  | func ROFileLabel() 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) { | ||||||
|  | 	return "", "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SecurityCheckContext validates that the SELinux label is understood by the kernel | ||||||
|  | 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) { | ||||||
|  | 	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 { | ||||||
|  | 	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 { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DisableSecOpt returns a security opt that can be used to disable SELinux | ||||||
|  | // labeling support for future container processes. | ||||||
|  | func DisableSecOpt() []string { | ||||||
|  | 	return []string{"disable"} | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // +build linux | // +build selinux,linux | ||||||
|  |  | ||||||
| package selinux | package selinux | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Yanqiang Miao
					Yanqiang Miao