func Getpidcon(pid int) (string, error) {
	return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
}
Getpidcon returns the SELinux label of the given pid, or an error.
package selinux
import (
	"bufio"
	"crypto/rand"
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"github.com/opencontainers/runc/libcontainer/system"
)
const (
	Enforcing        = 1
	Permissive       = 0
	Disabled         = -1
	selinuxDir       = "/etc/selinux/"
	selinuxConfig    = selinuxDir + "config"
	selinuxTypeTag   = "SELINUXTYPE"
	selinuxTag       = "SELINUX"
	selinuxPath      = "/sys/fs/selinux"
	xattrNameSelinux = "security.selinux"
	stRdOnly         = 0x01
)
var (
	assignRegex           = regexp.MustCompile(`^([^=]+)=(.*)$`)
	mcsList               = make(map[string]bool)
	mcsLock               sync.Mutex
	selinuxfs             = "unknown"
	selinuxEnabled        = false  
	selinuxEnabledChecked = false  
)
type SELinuxContext map[string]string
func SetDisabled() {
	selinuxEnabled, selinuxEnabledChecked = false, true
}
func getSelinuxMountPoint() string {
	if selinuxfs != "unknown" {
		return selinuxfs
	}
	selinuxfs = ""
	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()
		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 selinuxfs
}
func SelinuxEnabled() bool {
	if selinuxEnabledChecked {
		return selinuxEnabled
	}
	selinuxEnabledChecked = true
	if fs := getSelinuxMountPoint(); fs != "" {
		if con, _ := Getcon(); con != "kernel" {
			selinuxEnabled = true
		}
	}
	return selinuxEnabled
}
func readConfig(target string) (value string) {
	var (
		val, key string
		bufin    *bufio.Reader
	)
	in, err := os.Open(selinuxConfig)
	if err != nil {
		return ""
	}
	defer in.Close()
	bufin = bufio.NewReader(in)
	for done := false; !done; {
		var line string
		if line, err = bufin.ReadString('\n'); err != nil {
			if err != io.EOF {
				return ""
			}
			done = true
		}
		line = strings.TrimSpace(line)
		if len(line) == 0 {
			continue
		}
		if line[0] == ';' || line[0] == '#' {
			continue
		}
		if groups := assignRegex.FindStringSubmatch(line); groups != nil {
			key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
			if key == target {
				return strings.Trim(val, "\"")
			}
		}
	}
	return ""
}
func getSELinuxPolicyRoot() string {
	return selinuxDir + readConfig(selinuxTypeTag)
}
func readCon(name string) (string, error) {
	var val string
	in, err := os.Open(name)
	if err != nil {
		return "", err
	}
	defer in.Close()
	_, err = fmt.Fscanf(in, "%s", &val)
	return val, err
}
func Setfilecon(path string, scon string) error {
	return system.Lsetxattr(path, xattrNameSelinux, []byte(scon), 0)
}
func Getfilecon(path string) (string, error) {
	con, err := system.Lgetxattr(path, xattrNameSelinux)
	if err != nil {
		return "", err
	}
	if len(con) > 0 && con[len(con)-1] == '\x00' {
		con = con[:len(con)-1]
	}
	return string(con), nil
}
func Setfscreatecon(scon string) error {
	return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), scon)
}
func Getfscreatecon() (string, error) {
	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()))
}
func Getcon() (string, error) {
	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()))
}