Need to setup labeling of kernel keyrings.
Work is ongoing in the kernel to support different kernel keyrings per user namespace. We want to allow SELinux to manage kernel keyrings inside of the container. Currently when runc creates the kernel keyring it gets the label which runc is running with ususally `container_runtime_t`, with this change the kernel keyring will be labeled with the container process label container_t:s0:C1,c2. Container running as container_t:s0:c1,c2 can manage keyrings with the same label. This change required a revendoring or the SELinux go bindings. github.com/opencontainers/selinux. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
2b18fe1d88
commit
cd96170c10
|
@ -34,6 +34,10 @@ func (l *linuxSetnsInit) Init() error {
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
if !l.config.Config.NoNewKeyring {
|
if !l.config.Config.NoNewKeyring {
|
||||||
|
if err := label.SetKeyLabel(l.config.ProcessLabel); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer label.SetKeyLabel("")
|
||||||
// Do not inherit the parent's session keyring.
|
// Do not inherit the parent's session keyring.
|
||||||
if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
|
if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
|
||||||
// Same justification as in standart_init_linux.go as to why we
|
// Same justification as in standart_init_linux.go as to why we
|
||||||
|
|
|
@ -48,6 +48,10 @@ func (l *linuxStandardInit) Init() error {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
if !l.config.Config.NoNewKeyring {
|
if !l.config.Config.NoNewKeyring {
|
||||||
|
if err := label.SetKeyLabel(l.config.ProcessLabel); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer label.SetKeyLabel("")
|
||||||
ringname, keepperms, newperms := l.getSessionRingParams()
|
ringname, keepperms, newperms := l.getSessionRingParams()
|
||||||
|
|
||||||
// Do not inherit the parent's session keyring.
|
// Do not inherit the parent's session keyring.
|
||||||
|
|
|
@ -5,7 +5,7 @@ github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
|
||||||
# Core libcontainer functionality.
|
# Core libcontainer functionality.
|
||||||
github.com/checkpoint-restore/go-criu v3.11
|
github.com/checkpoint-restore/go-criu v3.11
|
||||||
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
||||||
github.com/opencontainers/selinux v1.0.0-rc1
|
github.com/opencontainers/selinux v1.2
|
||||||
github.com/seccomp/libseccomp-golang 84e90a91acea0f4e51e62bc1a75de18b1fc0790f
|
github.com/seccomp/libseccomp-golang 84e90a91acea0f4e51e62bc1a75de18b1fc0790f
|
||||||
github.com/sirupsen/logrus a3f95b5c423586578a4e099b11a46c2479628cac
|
github.com/sirupsen/logrus a3f95b5c423586578a4e099b11a46c2479628cac
|
||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||||
|
|
|
@ -5,3 +5,14 @@
|
||||||
Common SELinux package used across the container ecosystem.
|
Common SELinux package used across the container ecosystem.
|
||||||
|
|
||||||
Please see the [godoc](https://godoc.org/github.com/opencontainers/selinux) for more information.
|
Please see the [godoc](https://godoc.org/github.com/opencontainers/selinux) for more information.
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
Participation in the OpenContainers community is governed by [OpenContainer's Code of Conduct][code-of-conduct].
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
If you find an issue, please follow the [security][security] protocol to report it.
|
||||||
|
|
||||||
|
[security]: https://github.com/opencontainers/org/blob/master/security
|
||||||
|
[code-of-conduct]: https://github.com/opencontainers/org/blob/master/CODE_OF_CONDUCT.md
|
||||||
|
|
|
@ -9,7 +9,7 @@ func InitLabels(options []string) (string, string, error) {
|
||||||
return "", "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetROMountLabel() string {
|
func ROMountLabel() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,27 @@ func SetProcessLabel(processLabel string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFileLabel(path string) (string, error) {
|
func ProcessLabel() (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetSocketLabel(processLabel string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SocketLabel() (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKeyLabel(processLabel string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyLabel() (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileLabel(path string) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +61,18 @@ func Relabel(path string, fileLabel string, shared bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPidLabel(pid int) (string, error) {
|
func PidLabel(pid int) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearLabels clears all reserved labels
|
||||||
|
func ClearLabels() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func ReserveLabel(label string) error {
|
func ReserveLabel(label string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -58,8 +83,8 @@ func ReleaseLabel(label string) error {
|
||||||
|
|
||||||
// DupSecOpt takes a process label and returns security options that
|
// DupSecOpt takes a process label and returns security options that
|
||||||
// can be used to set duplicate labels on future container processes
|
// can be used to set duplicate labels on future container processes
|
||||||
func DupSecOpt(src string) []string {
|
func DupSecOpt(src string) ([]string, error) {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableSecOpt returns a security opt that can disable labeling
|
// DisableSecOpt returns a security opt that can disable labeling
|
||||||
|
|
|
@ -4,6 +4,8 @@ package label
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/opencontainers/selinux/go-selinux"
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
|
@ -24,17 +26,29 @@ var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be use
|
||||||
// the container. A list of options can be passed into this function to alter
|
// the container. A list of options can be passed into this function to alter
|
||||||
// the labels. The labels returned will include a random MCS String, that is
|
// the labels. The labels returned will include a random MCS String, that is
|
||||||
// guaranteed to be unique.
|
// guaranteed to be unique.
|
||||||
func InitLabels(options []string) (string, string, error) {
|
func InitLabels(options []string) (plabel string, mlabel string, Err error) {
|
||||||
if !selinux.GetEnabled() {
|
if !selinux.GetEnabled() {
|
||||||
return "", "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
processLabel, mountLabel := selinux.ContainerLabels()
|
processLabel, mountLabel := selinux.ContainerLabels()
|
||||||
if processLabel != "" {
|
if processLabel != "" {
|
||||||
pcon := selinux.NewContext(processLabel)
|
defer func() {
|
||||||
mcon := selinux.NewContext(mountLabel)
|
if Err != nil {
|
||||||
|
ReleaseLabel(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 {
|
for _, opt := range options {
|
||||||
if opt == "disable" {
|
if opt == "disable" {
|
||||||
return "", "", nil
|
return "", mountLabel, nil
|
||||||
}
|
}
|
||||||
if i := strings.Index(opt, ":"); i == -1 {
|
if i := strings.Index(opt, ":"); i == -1 {
|
||||||
return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type' followed by ':' and a value", opt)
|
return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type' followed by ':' and a value", opt)
|
||||||
|
@ -49,8 +63,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,12 +101,31 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||||
|
// label to the next socket that gets created
|
||||||
|
func SetSocketLabel(processLabel string) error {
|
||||||
|
return selinux.SetSocketLabel(processLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketLabel retrieves the current default socket label setting
|
||||||
|
func SocketLabel() (string, error) {
|
||||||
|
return selinux.SocketLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||||
|
// label to the next kernel keyring that gets created
|
||||||
|
func SetKeyLabel(processLabel string) error {
|
||||||
|
return selinux.SetKeyLabel(processLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyLabel retrieves the current default kernel keyring label setting
|
||||||
|
func KeyLabel() (string, error) {
|
||||||
|
return selinux.KeyLabel()
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessLabel returns the process label that the kernel will assign
|
// ProcessLabel returns the process label that the kernel will assign
|
||||||
// to the next program executed by the current process. If "" is returned
|
// to the next program executed by the current process. If "" is returned
|
||||||
// this indicates that the default labeling will happen for the process.
|
// this indicates that the default labeling will happen for the process.
|
||||||
|
@ -98,7 +133,7 @@ func ProcessLabel() (string, error) {
|
||||||
return selinux.ExecLabel()
|
return selinux.ExecLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFileLabel returns the label for specified path
|
// FileLabel returns the label for specified path
|
||||||
func FileLabel(path string) (string, error) {
|
func FileLabel(path string) (string, error) {
|
||||||
return selinux.FileLabel(path)
|
return selinux.FileLabel(path)
|
||||||
}
|
}
|
||||||
|
@ -131,13 +166,56 @@ 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,
|
||||||
|
"/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] {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
if shared {
|
if shared {
|
||||||
c := selinux.NewContext(fileLabel)
|
c, err := selinux.NewContext(fileLabel)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
c["level"] = "s0"
|
c["level"] = "s0"
|
||||||
fileLabel = c.Get()
|
fileLabel = c.Get()
|
||||||
}
|
}
|
||||||
|
@ -157,6 +235,11 @@ func Init() {
|
||||||
selinux.GetEnabled()
|
selinux.GetEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearLabels will clear all reserved labels
|
||||||
|
func ClearLabels() {
|
||||||
|
selinux.ClearLabels()
|
||||||
|
}
|
||||||
|
|
||||||
// ReserveLabel will record the fact that the MCS label has already been used.
|
// ReserveLabel will record the fact that the MCS label has already been used.
|
||||||
// This will prevent InitLabels from using the MCS label in a newly created
|
// This will prevent InitLabels from using the MCS label in a newly created
|
||||||
// container
|
// container
|
||||||
|
@ -175,7 +258,7 @@ func ReleaseLabel(label string) error {
|
||||||
|
|
||||||
// DupSecOpt takes a process label and returns security options that
|
// DupSecOpt takes a process label and returns security options that
|
||||||
// can be used to set duplicate labels on future container processes
|
// 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)
|
return selinux.DupSecOpt(src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,15 @@ 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")
|
||||||
|
// InvalidLabel is returned when an invalid label is specified.
|
||||||
|
InvalidLabel = errors.New("Invalid Label")
|
||||||
|
|
||||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||||
|
roFileLabel string
|
||||||
state = selinuxState{
|
state = selinuxState{
|
||||||
mcsList: make(map[string]bool),
|
mcsList: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
@ -91,6 +104,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 +190,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 +207,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 +249,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filecon 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 +329,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 +348,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.
|
||||||
|
@ -283,35 +387,74 @@ func SetExecLabel(label string) error {
|
||||||
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), label)
|
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), 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 writeCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()), label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketLabel retrieves the current socket label setting
|
||||||
|
func SocketLabel() (string, error) {
|
||||||
|
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 writeCon("/proc/self/attr/keycreate", label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// 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
|
||||||
func NewContext(label string) Context {
|
func NewContext(label string) (Context, error) {
|
||||||
c := make(Context)
|
c := make(Context)
|
||||||
|
|
||||||
if len(label) != 0 {
|
if len(label) != 0 {
|
||||||
con := strings.SplitN(label, ":", 4)
|
con := strings.SplitN(label, ":", 4)
|
||||||
|
if len(con) < 3 {
|
||||||
|
return c, InvalidLabel
|
||||||
|
}
|
||||||
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, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
||||||
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
|
||||||
|
@ -331,7 +474,7 @@ func EnforceMode() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SetEnforce sets the current SELinux mode Enforcing, Permissive.
|
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||||
Disabled is not valid, since this needs to be set at boot time.
|
Disabled is not valid, since this needs to be set at boot time.
|
||||||
*/
|
*/
|
||||||
func SetEnforceMode(mode int) error {
|
func SetEnforceMode(mode int) error {
|
||||||
|
@ -354,16 +497,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 +573,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 +646,25 @@ func ContainerLabels() (processLabel string, fileLabel string) {
|
||||||
roFileLabel = fileLabel
|
roFileLabel = fileLabel
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
mcs := uniqMcs(1024)
|
scon, _ := NewContext(processLabel)
|
||||||
scon := NewContext(processLabel)
|
if scon["level"] != "" {
|
||||||
scon["level"] = mcs
|
mcs := uniqMcs(1024)
|
||||||
processLabel = scon.Get()
|
scon["level"] = mcs
|
||||||
scon = NewContext(fileLabel)
|
processLabel = scon.Get()
|
||||||
scon["level"] = mcs
|
scon, _ = NewContext(fileLabel)
|
||||||
fileLabel = scon.Get()
|
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) {
|
||||||
|
@ -526,8 +677,14 @@ func CopyLevel(src, dest string) (string, error) {
|
||||||
if err := SecurityCheckContext(dest); err != nil {
|
if err := SecurityCheckContext(dest); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
scon := NewContext(src)
|
scon, err := NewContext(src)
|
||||||
tcon := NewContext(dest)
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
tcon, err := NewContext(dest)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
mcsDelete(tcon["level"])
|
mcsDelete(tcon["level"])
|
||||||
mcsAdd(scon["level"])
|
mcsAdd(scon["level"])
|
||||||
tcon["level"] = scon["level"]
|
tcon["level"] = scon["level"]
|
||||||
|
@ -536,20 +693,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
|
||||||
}
|
}
|
||||||
|
@ -557,7 +720,11 @@ func Chcon(fpath string, label string, recurse bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
callback := func(p string, info os.FileInfo, err error) error {
|
callback := func(p string, info os.FileInfo, err error) error {
|
||||||
return SetFileLabel(p, label)
|
e := SetFileLabel(p, label)
|
||||||
|
if os.IsNotExist(e) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
if recurse {
|
if recurse {
|
||||||
|
@ -568,26 +735,34 @@ 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, error) {
|
||||||
if src == "" {
|
if src == "" {
|
||||||
return nil
|
return nil, nil
|
||||||
|
}
|
||||||
|
con, err := NewContext(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
con := NewContext(src)
|
|
||||||
if con["user"] == "" ||
|
if con["user"] == "" ||
|
||||||
con["role"] == "" ||
|
con["role"] == "" ||
|
||||||
con["type"] == "" ||
|
con["type"] == "" {
|
||||||
con["level"] == "" {
|
return nil, 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, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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"}
|
||||||
}
|
}
|
217
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
Normal file
217
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
// +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
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketLabel retrieves the current socket label setting
|
||||||
|
func SocketLabel() (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 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyLabel retrieves the current kernel keyring label setting
|
||||||
|
func KeyLabel() (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, error) {
|
||||||
|
c := make(Context)
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearLabels clears all reserved MLS/MCS levels
|
||||||
|
func ClearLabels() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, 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 {
|
||||||
|
return []string{"disable"}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build linux
|
// +build selinux,linux
|
||||||
|
|
||||||
package selinux
|
package selinux
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue