Blob Blame History Raw
diff --git libselinux-2.5/ChangeLog libselinux-2.5/ChangeLog
index 24673dd..2b81053 100644
--- libselinux-2.5/ChangeLog
+++ libselinux-2.5/ChangeLog
@@ -1,3 +1,18 @@
+	* Clarify is_selinux_mls_enabled() description, from David King.
+	* Explain how to free policy type from selinux_getpolicytype(), from David King.
+	* Compare absolute pathname in matchpathcon -V, from Petr Lautrbach.
+	* Add selinux_snapperd_contexts_path(), from Petr Lautrbach.
+	* Modify audit2why analyze function to use loaded policy, from Joshua Brindle.
+	* Sort object files for deterministic linking order, from Laurent Bigonville.
+	* Respect CC and PKG_CONFIG environment variable, from Julien Pivotto.
+	* Avoid mounting /proc outside of selinux_init_load_policy(), from Stephen Smalley.
+	* Fix multiple spelling errors, from Laurent Bigonville.
+	* Fix typo in sefcontext_compile.8, from Petr Lautrbach and Milos Malik
+	* Fix location of selinuxfs mount point, from Dan Walsh.
+	* Only mount /proc if necessary, from Stephen Smalley.
+	* procattr: return einval for <= 0 pid args, from Daniel Cashman.
+	* procattr: return error on invalid pid_t input, from Daniel Cashman.
+
 2.5 2016-02-23
 	* selinux_restorecon.3 man page corrections, from Richard Haines.
 	* Add selinux_restorecon function, from Richard Haines.
diff --git libselinux-2.5/Makefile libselinux-2.5/Makefile
index 6142b60..bdf9de8 100644
--- libselinux-2.5/Makefile
+++ libselinux-2.5/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS = src include utils man
+SUBDIRS = src include utils man golang
 
 DISABLE_AVC ?= n
 DISABLE_SETRANS ?= n
diff --git libselinux-2.5/golang/Makefile libselinux-2.5/golang/Makefile
new file mode 100644
index 0000000..b75677b
--- /dev/null
+++ libselinux-2.5/golang/Makefile
@@ -0,0 +1,22 @@
+# Installation directories.
+PREFIX ?= $(DESTDIR)/usr
+LIBDIR ?= $(DESTDIR)/usr/lib
+GODIR ?= $(LIBDIR)/golang/src/pkg/github.com/selinux
+all:
+
+install: 
+	[ -d $(GODIR) ] || mkdir -p $(GODIR)
+	install -m 644 selinux.go $(GODIR)
+
+test:
+	@mkdir selinux
+	@cp selinux.go selinux
+	GOPATH=$(pwd) go run test.go 
+	@rm -rf selinux
+
+clean:
+	@rm -f *~
+	@rm -rf selinux
+indent:
+
+relabel:
diff --git libselinux-2.5/golang/selinux.go libselinux-2.5/golang/selinux.go
new file mode 100644
index 0000000..34bf6bb
--- /dev/null
+++ libselinux-2.5/golang/selinux.go
@@ -0,0 +1,412 @@
+package selinux
+
+/*
+ The selinux package is a go bindings to libselinux required to add selinux
+ support to docker.
+
+ Author Dan Walsh <dwalsh@redhat.com>
+
+ Used some ideas/code from the go-ini packages https://github.com/vaughan0
+ By Vaughan Newton
+*/
+
+// #cgo pkg-config: libselinux
+// #include <selinux/selinux.h>
+// #include <stdlib.h>
+import "C"
+import (
+	"bufio"
+	"crypto/rand"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"unsafe"
+)
+
+var (
+	assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
+	mcsList     = make(map[string]bool)
+)
+
+func Matchpathcon(path string, mode os.FileMode) (string, error) {
+	var con C.security_context_t
+	var scon string
+	rc, err := C.matchpathcon(C.CString(path), C.mode_t(mode), &con)
+	if rc == 0 {
+		scon = C.GoString(con)
+		C.free(unsafe.Pointer(con))
+	}
+	return scon, err
+}
+
+func Setfilecon(path, scon string) (int, error) {
+	rc, err := C.lsetfilecon(C.CString(path), C.CString(scon))
+	return int(rc), err
+}
+
+func Getfilecon(path string) (string, error) {
+	var scon C.security_context_t
+	var fcon string
+	rc, err := C.lgetfilecon(C.CString(path), &scon)
+	if rc >= 0 {
+		fcon = C.GoString(scon)
+		err = nil
+	}
+	return fcon, err
+}
+
+func Setfscreatecon(scon string) (int, error) {
+	var (
+		rc  C.int
+		err error
+	)
+	if scon != "" {
+		rc, err = C.setfscreatecon(C.CString(scon))
+	} else {
+		rc, err = C.setfscreatecon(nil)
+	}
+	return int(rc), err
+}
+
+func Getfscreatecon() (string, error) {
+	var scon C.security_context_t
+	var fcon string
+	rc, err := C.getfscreatecon(&scon)
+	if rc >= 0 {
+		fcon = C.GoString(scon)
+		err = nil
+		C.freecon(scon)
+	}
+	return fcon, err
+}
+
+func Getcon() string {
+	var pcon C.security_context_t
+	C.getcon(&pcon)
+	scon := C.GoString(pcon)
+	C.freecon(pcon)
+	return scon
+}
+
+func Getpidcon(pid int) (string, error) {
+	var pcon C.security_context_t
+	var scon string
+	rc, err := C.getpidcon(C.pid_t(pid), &pcon)
+	if rc >= 0 {
+		scon = C.GoString(pcon)
+		C.freecon(pcon)
+		err = nil
+	}
+	return scon, err
+}
+
+func Getpeercon(socket int) (string, error) {
+	var pcon C.security_context_t
+	var scon string
+	rc, err := C.getpeercon(C.int(socket), &pcon)
+	if rc >= 0 {
+		scon = C.GoString(pcon)
+		C.freecon(pcon)
+		err = nil
+	}
+	return scon, err
+}
+
+func Setexeccon(scon string) error {
+	var val *C.char
+	if !SelinuxEnabled() {
+		return nil
+	}
+	if scon != "" {
+		val = C.CString(scon)
+	} else {
+		val = nil
+	}
+	_, err := C.setexeccon(val)
+	return err
+}
+
+type Context struct {
+	con []string
+}
+
+func (c *Context) SetUser(user string) {
+	c.con[0] = user
+}
+func (c *Context) GetUser() string {
+	return c.con[0]
+}
+func (c *Context) SetRole(role string) {
+	c.con[1] = role
+}
+func (c *Context) GetRole() string {
+	return c.con[1]
+}
+func (c *Context) SetType(setype string) {
+	c.con[2] = setype
+}
+func (c *Context) GetType() string {
+	return c.con[2]
+}
+func (c *Context) SetLevel(mls string) {
+	c.con[3] = mls
+}
+func (c *Context) GetLevel() string {
+	return c.con[3]
+}
+func (c *Context) Get() string {
+	return strings.Join(c.con, ":")
+}
+func (c *Context) Set(scon string) {
+	c.con = strings.SplitN(scon, ":", 4)
+}
+func NewContext(scon string) Context {
+	var con Context
+	con.Set(scon)
+	return con
+}
+
+func SelinuxEnabled() bool {
+	b := C.is_selinux_enabled()
+	if b > 0 {
+		return true
+	}
+	return false
+}
+
+const (
+	Enforcing  = 1
+	Permissive = 0
+	Disabled   = -1
+)
+
+func SelinuxGetEnforce() int {
+	return int(C.security_getenforce())
+}
+
+func SelinuxGetEnforceMode() int {
+	var enforce C.int
+	C.selinux_getenforcemode(&enforce)
+	return int(enforce)
+}
+
+func mcsAdd(mcs string) {
+	mcsList[mcs] = true
+}
+
+func mcsDelete(mcs string) {
+	mcsList[mcs] = false
+}
+
+func mcsExists(mcs string) bool {
+	return mcsList[mcs]
+}
+
+func IntToMcs(id int, catRange uint32) string {
+	if (id < 1) || (id > 523776) {
+		return ""
+	}
+
+	SETSIZE := int(catRange)
+	TIER := SETSIZE
+
+	ORD := id
+	for ORD > TIER {
+		ORD = ORD - TIER
+		TIER -= 1
+	}
+	TIER = SETSIZE - TIER
+	ORD = ORD + TIER
+	return fmt.Sprintf("s0:c%d,c%d", TIER, ORD)
+}
+
+func uniqMcs(catRange uint32) string {
+	var n uint32
+	var c1, c2 uint32
+	var mcs string
+	for {
+		binary.Read(rand.Reader, binary.LittleEndian, &n)
+		c1 = n % catRange
+		binary.Read(rand.Reader, binary.LittleEndian, &n)
+		c2 = n % catRange
+		if c1 == c2 {
+			continue
+		} else {
+			if c1 > c2 {
+				t := c1
+				c1 = c2
+				c2 = t
+			}
+		}
+		mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2)
+		if mcsExists(mcs) {
+			continue
+		}
+		mcsAdd(mcs)
+		break
+	}
+	return mcs
+}
+func freeContext(processLabel string) {
+	var scon Context
+	scon = NewContext(processLabel)
+	mcsDelete(scon.GetLevel())
+}
+
+func GetLxcContexts() (processLabel string, fileLabel string) {
+	var val, key string
+	var bufin *bufio.Reader
+	if !SelinuxEnabled() {
+		return
+	}
+	lxcPath := C.GoString(C.selinux_lxc_contexts_path())
+	fileLabel = "system_u:object_r:svirt_sandbox_file_t:s0"
+	processLabel = "system_u:system_r:svirt_lxc_net_t:s0"
+
+	in, err := os.Open(lxcPath)
+	if err != nil {
+		goto exit
+	}
+
+	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 {
+				done = true
+			} else {
+				goto exit
+			}
+		}
+		line = strings.TrimSpace(line)
+		if len(line) == 0 {
+			// Skip blank lines
+			continue
+		}
+		if line[0] == ';' || line[0] == '#' {
+			// Skip comments
+			continue
+		}
+		if groups := assignRegex.FindStringSubmatch(line); groups != nil {
+			key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
+			if key == "process" {
+				processLabel = strings.Trim(val, "\"")
+			}
+			if key == "file" {
+				fileLabel = strings.Trim(val, "\"")
+			}
+		}
+	}
+exit:
+	var scon Context
+	mcs := IntToMcs(os.Getpid(), 1024)
+	scon = NewContext(processLabel)
+	scon.SetLevel(mcs)
+	processLabel = scon.Get()
+	scon = NewContext(fileLabel)
+	scon.SetLevel(mcs)
+	fileLabel = scon.Get()
+	return processLabel, fileLabel
+}
+
+func CopyLevel(src, dest string) (string, error) {
+	if !SelinuxEnabled() {
+		return "", nil
+	}
+	if src == "" {
+		return "", nil
+	}
+	rc, err := C.security_check_context(C.CString(src))
+	if rc != 0 {
+		return "", err
+	}
+	rc, err = C.security_check_context(C.CString(dest))
+	if rc != 0 {
+		return "", err
+	}
+	scon := NewContext(src)
+	tcon := NewContext(dest)
+	tcon.SetLevel(scon.GetLevel())
+	return tcon.Get(), nil
+}
+
+func RestoreCon(fpath string, recurse bool) error {
+	var flabel string
+	var err error
+	var fs os.FileInfo
+
+	if !SelinuxEnabled() {
+		return nil
+	}
+
+	if recurse {
+		var paths []string
+		var err error
+
+		if paths, err = filepath.Glob(path.Join(fpath, "**", "*")); err != nil {
+			return fmt.Errorf("Unable to find directory %v: %v", fpath, err)
+		}
+
+		for _, fpath := range paths {
+			if err = RestoreCon(fpath, false); err != nil {
+				return fmt.Errorf("Unable to restore selinux context for %v: %v", fpath, err)
+			}
+		}
+		return nil
+	}
+	if fs, err = os.Stat(fpath); err != nil {
+		return fmt.Errorf("Unable stat %v: %v", fpath, err)
+	}
+
+	if flabel, err = Matchpathcon(fpath, fs.Mode()); flabel == "" {
+		return fmt.Errorf("Unable to get context for %v: %v", fpath, err)
+	}
+
+	if rc, err := Setfilecon(fpath, flabel); rc != 0 {
+		return fmt.Errorf("Unable to set selinux context for %v: %v", fpath, err)
+	}
+
+	return nil
+}
+
+func Test() {
+	var plabel, flabel string
+	if !SelinuxEnabled() {
+		return
+	}
+
+	plabel, flabel = GetLxcContexts()
+	fmt.Println(plabel)
+	fmt.Println(flabel)
+	freeContext(plabel)
+	plabel, flabel = GetLxcContexts()
+	fmt.Println(plabel)
+	fmt.Println(flabel)
+	freeContext(plabel)
+	if SelinuxEnabled() {
+		fmt.Println("Enabled")
+	} else {
+		fmt.Println("Disabled")
+	}
+	fmt.Println("getenforce ", SelinuxGetEnforce())
+	fmt.Println("getenforcemode ", SelinuxGetEnforceMode())
+	flabel, _ = Matchpathcon("/home/dwalsh/.emacs", 0)
+	fmt.Println(flabel)
+	pid := os.Getpid()
+	fmt.Printf("PID:%d MCS:%s\n", pid, IntToMcs(pid, 1023))
+	fmt.Println(Getcon())
+	fmt.Println(Getfilecon("/etc/passwd"))
+	fmt.Println(Getpidcon(1))
+	Setfscreatecon("unconfined_u:unconfined_r:unconfined_t:s0")
+	fmt.Println(Getfscreatecon())
+	Setfscreatecon("")
+	fmt.Println(Getfscreatecon())
+	fmt.Println(Getpidcon(1))
+}
diff --git libselinux-2.5/golang/test.go libselinux-2.5/golang/test.go
new file mode 100644
index 0000000..fed6de8
--- /dev/null
+++ libselinux-2.5/golang/test.go
@@ -0,0 +1,9 @@
+package main
+
+import (
+	"./selinux"
+)
+
+func main() {
+	selinux.Test()
+}
diff --git libselinux-2.5/include/selinux/selinux.h libselinux-2.5/include/selinux/selinux.h
index 2262086..3d8673f 100644
--- libselinux-2.5/include/selinux/selinux.h
+++ libselinux-2.5/include/selinux/selinux.h
@@ -544,6 +544,7 @@ extern const char *selinux_lxc_contexts_path(void);
 extern const char *selinux_x_context_path(void);
 extern const char *selinux_sepgsql_context_path(void);
 extern const char *selinux_openssh_contexts_path(void);
+extern const char *selinux_snapperd_contexts_path(void);
 extern const char *selinux_systemd_contexts_path(void);
 extern const char *selinux_contexts_path(void);
 extern const char *selinux_securetty_types_path(void);
diff --git libselinux-2.5/man/man3/avc_add_callback.3 libselinux-2.5/man/man3/avc_add_callback.3
index dbfe72d..bdbbadf 100644
--- libselinux-2.5/man/man3/avc_add_callback.3
+++ libselinux-2.5/man/man3/avc_add_callback.3
@@ -57,7 +57,7 @@ and will cause any SID to match.
 .I callback
 is the callback function provided by the userspace object manager.  The
 .I event
-argument indicates the security event which occured; the remaining arguments
+argument indicates the security event which occurred; the remaining arguments
 are interpreted according to the event as described below.  The return value
 of the callback should be zero on success, \-1 on error with
 .I errno
@@ -175,7 +175,7 @@ If the userspace AVC is running in threaded mode, callbacks registered via
 may be executed in the context of the netlink handler thread.  This will likely introduce synchronization issues requiring the use of locks.  See
 .BR avc_init (3).
 
-Support for dynamic revocation and retained permissions is mostly unimplemented in the SELinux kernel module.  The only security event that currently gets excercised is
+Support for dynamic revocation and retained permissions is mostly unimplemented in the SELinux kernel module.  The only security event that currently gets exercised is
 .BR AVC_CALLBACK_RESET .
 .
 .SH "AUTHOR"
diff --git libselinux-2.5/man/man3/avc_has_perm.3 libselinux-2.5/man/man3/avc_has_perm.3
index 7353952..3e9fca8 100644
--- libselinux-2.5/man/man3/avc_has_perm.3
+++ libselinux-2.5/man/man3/avc_has_perm.3
@@ -108,7 +108,7 @@ for the first time.
 Using an uninitialized structure will produce undefined behavior.
 .
 .SH "RETURN VALUE"
-If requested permissions are granted, zero is returned.  If requested permissions are denied or an error occured, \-1 is returned and
+If requested permissions are granted, zero is returned.  If requested permissions are denied or an error occurred, \-1 is returned and
 .I errno
 is set appropriately.
 
diff --git libselinux-2.5/man/man3/is_selinux_enabled.3 libselinux-2.5/man/man3/is_selinux_enabled.3
index f02052c..df62c22 100644
--- libselinux-2.5/man/man3/is_selinux_enabled.3
+++ libselinux-2.5/man/man3/is_selinux_enabled.3
@@ -3,7 +3,7 @@
 is_selinux_enabled \- check whether SELinux is enabled
 .
 .SH "NAME"
-is_selinux_mls_enabled \- check whether SELinux is enabled for (Multi Level Securty) MLS 
+is_selinux_mls_enabled \- check whether SELinux is enabled for (Multi Level Security) MLS
 .
 .SH "SYNOPSIS"
 .B #include <selinux/selinux.h>
@@ -18,7 +18,9 @@ returns 1 if SELinux is running or 0 if it is not.
 On error, \-1 is returned.
 
 .BR is_selinux_mls_enabled ()
-returns 1 if SELinux is running in MLS mode or 0 if it is not. 
+returns 1 if SELinux is capable of running in MLS mode or 0 if it is not. To
+determine the policy in use on the system, use
+.BR selinux_getpolicytype (3).
 .
 .SH "SEE ALSO"
 .BR selinux "(8)"
diff --git libselinux-2.5/man/man3/security_disable.3 libselinux-2.5/man/man3/security_disable.3
index c75ce0d..072923c 100644
--- libselinux-2.5/man/man3/security_disable.3
+++ libselinux-2.5/man/man3/security_disable.3
@@ -12,7 +12,7 @@ security_disable \- disable the SELinux kernel code at runtime
 disables the SELinux kernel code, unregisters selinuxfs from
 .IR /proc/filesystems ,
 and then unmounts
-.IR /selinux .
+.IR /sys/fs/selinux .
 .sp
 This function can only be called at runtime and prior to the initial policy
 load. After the initial policy load, the SELinux kernel code cannot be disabled,
diff --git libselinux-2.5/man/man3/selinux_getpolicytype.3 libselinux-2.5/man/man3/selinux_getpolicytype.3
index c947e2c..b219d42 100644
--- libselinux-2.5/man/man3/selinux_getpolicytype.3
+++ libselinux-2.5/man/man3/selinux_getpolicytype.3
@@ -13,7 +13,10 @@ Reads the contents of the
 .I /etc/selinux/config
 file to determine the SELinux policy used on the system, and sets
 .I \%policytype
-accordinly.
+accordingly. Free
+.I \%policytype
+with
+.BR free (3).
 .
 .SH "RETURN VALUE"
 On success, zero is returned.
diff --git libselinux-2.5/man/man3/selinux_status_open.3 libselinux-2.5/man/man3/selinux_status_open.3
index f779dd9..2d44be5 100644
--- libselinux-2.5/man/man3/selinux_status_open.3
+++ libselinux-2.5/man/man3/selinux_status_open.3
@@ -23,7 +23,7 @@ without invocation of system calls
 .SH "DESCRIPTION"
 Linux 2.6.37 or later provides a SELinux kernel status page; being mostly
 placed on
-.I /selinux/status
+.I /sys/fs/selinux/status
 entry. It enables userspace applications to mmap this page with read-only
 mode, then it informs some status without system call invocations.
 .sp
@@ -38,7 +38,7 @@ without system-call invocation or worker thread for monitoring.
 .BR selinux_status_open ()
 tries to
 .BR open (2)
-.I /selinux/status
+.I /sys/fs/selinux/status
 and
 .BR mmap (2)
 it in read-only mode. The file-descriptor and pointer to the page shall
diff --git libselinux-2.5/man/man8/avcstat.8 libselinux-2.5/man/man8/avcstat.8
index 204687d..2c4bce1 100644
--- libselinux-2.5/man/man8/avcstat.8
+++ libselinux-2.5/man/man8/avcstat.8
@@ -25,7 +25,7 @@ Display the cumulative values.
 .TP
 .B \-f
 Specifies the location of the AVC statistics file, defaulting to
-.IR /selinux/avc/cache_stats .
+.IR /sys/fs/selinux/avc/cache_stats .
 .
 .SH AUTHOR
 This manual page was written by Dan Walsh <dwalsh@redhat.com>.
diff --git libselinux-2.5/man/man8/sefcontext_compile.8 libselinux-2.5/man/man8/sefcontext_compile.8
index b77ff3a..4eae173 100644
--- libselinux-2.5/man/man8/sefcontext_compile.8
+++ libselinux-2.5/man/man8/sefcontext_compile.8
@@ -13,14 +13,14 @@ sefcontext_compile \- compile file context regular expression files
 .SH "DESCRIPTION"
 .B sefcontext_compile
 is used to compile file context regular expressions into
-.BR prce (3)
+.BR pcre (3)
 format.
 .sp
 The compiled file is used by libselinux file labeling functions.
 .sp
 By default
 .B sefcontext_compile
-writes the compiled prce file with the
+writes the compiled pcre file with the
 .B .bin
 suffix appended (e.g. \fIinputfile\fB.bin\fR).
 .SH OPTIONS
diff --git libselinux-2.5/man/man8/selinux.8 libselinux-2.5/man/man8/selinux.8
index 6f1034b..c9f188c 100644
--- libselinux-2.5/man/man8/selinux.8
+++ libselinux-2.5/man/man8/selinux.8
@@ -91,11 +91,13 @@ This manual page was written by Dan Walsh <dwalsh@redhat.com>.
 .BR sepolicy (8),
 .BR system-config-selinux (8),
 .BR togglesebool (8),
-.BR restorecon (8),
 .BR fixfiles (8),
+.BR restorecon (8),
 .BR setfiles (8),
 .BR semanage (8),
-.BR sepolicy(8)
+.BR sepolicy(8),
+.BR seinfo(8),
+.BR sesearch(8)
 
 Every confined service on the system has a man page in the following format:
 .br
diff --git libselinux-2.5/src/Makefile libselinux-2.5/src/Makefile
index d0021ae..d94163e 100644
--- libselinux-2.5/src/Makefile
+++ libselinux-2.5/src/Makefile
@@ -5,6 +5,7 @@ PYTHON ?= python
 PYPREFIX ?= $(notdir $(PYTHON))
 RUBY ?= ruby
 RUBYPREFIX ?= $(notdir $(RUBY))
+PKG_CONFIG ?= pkg-config
 
 # Installation directories.
 PREFIX ?= $(DESTDIR)/usr
@@ -12,11 +13,11 @@ LIBDIR ?= $(PREFIX)/lib
 SHLIBDIR ?= $(DESTDIR)/lib
 INCLUDEDIR ?= $(PREFIX)/include
 PYLIBVER ?= $(shell $(PYTHON) -c 'import sys;print("python%d.%d" % sys.version_info[0:2])')
-PYINC ?= $(shell pkg-config --cflags $(PYPREFIX))
+PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX))
 PYLIBDIR ?= $(LIBDIR)/$(PYLIBVER)
 RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")')
 RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM')
-RUBYINC ?= $(shell pkg-config --cflags ruby)
+RUBYINC ?= $(shell $(PKG_CONFIG) --cflags ruby)
 RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM)
 LIBBASE ?= $(shell basename $(LIBDIR))
 
@@ -48,7 +49,7 @@ ifeq ($(DISABLE_BOOL),y)
 endif
 
 GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) selinuxswig_python_exception.i
-SRCS= $(filter-out $(UNUSED_SRCS) $(GENERATED) audit2why.c, $(wildcard *.c))
+SRCS= $(filter-out $(UNUSED_SRCS) $(GENERATED) audit2why.c, $(sort $(wildcard *.c)))
 
 MAX_STACK_SIZE=32768
 
diff --git libselinux-2.5/src/audit2why.c libselinux-2.5/src/audit2why.c
index 12745b3..abe1701 100644
--- libselinux-2.5/src/audit2why.c
+++ libselinux-2.5/src/audit2why.c
@@ -343,8 +343,8 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
 	if (rc < 0)
 		RETURN(BADTCON)
 
-	tclass = string_to_security_class(tclassstr);
-	if (!tclass)
+	rc = sepol_string_to_security_class(tclassstr, &tclass);
+	if (rc < 0)
 		RETURN(BADTCLASS)
 
 	/* Convert the permission list to an AV. */
@@ -365,8 +365,8 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
 		permstr = PyString_AsString( strObj );
 #endif
 		
-		perm = string_to_av_perm(tclass, permstr);
-		if (!perm)
+		rc = sepol_string_to_av_perm(tclass, permstr, &perm);
+		if (rc < 0)
 			RETURN(BADPERM)
 
 		av |= perm;
diff --git libselinux-2.5/src/avc_sidtab.c libselinux-2.5/src/avc_sidtab.c
index 9669264..c775430 100644
--- libselinux-2.5/src/avc_sidtab.c
+++ libselinux-2.5/src/avc_sidtab.c
@@ -81,6 +81,11 @@ sidtab_context_to_sid(struct sidtab *s,
 	int hvalue, rc = 0;
 	struct sidtab_node *cur;
 
+	if (! ctx) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	*sid = NULL;
 	hvalue = sidtab_hash(ctx);
 
diff --git libselinux-2.5/src/canonicalize_context.c libselinux-2.5/src/canonicalize_context.c
index 7cf3139..364a746 100644
--- libselinux-2.5/src/canonicalize_context.c
+++ libselinux-2.5/src/canonicalize_context.c
@@ -17,6 +17,11 @@ int security_canonicalize_context_raw(const char * con,
 	size_t size;
 	int fd, ret;
 
+	if (! con) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	if (!selinux_mnt) {
 		errno = ENOENT;
 		return -1;
diff --git libselinux-2.5/src/check_context.c libselinux-2.5/src/check_context.c
index 52063fa..234749c 100644
--- libselinux-2.5/src/check_context.c
+++ libselinux-2.5/src/check_context.c
@@ -14,6 +14,11 @@ int security_check_context_raw(const char * con)
 	char path[PATH_MAX];
 	int fd, ret;
 
+	if (! con) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	if (!selinux_mnt) {
 		errno = ENOENT;
 		return -1;
diff --git libselinux-2.5/src/compute_av.c libselinux-2.5/src/compute_av.c
index 937e5c3..35ace7f 100644
--- libselinux-2.5/src/compute_av.c
+++ libselinux-2.5/src/compute_av.c
@@ -26,6 +26,11 @@ int security_compute_av_flags_raw(const char * scon,
 		return -1;
 	}
 
+	if ((! scon) || (! tcon)) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	snprintf(path, sizeof path, "%s/access", selinux_mnt);
 	fd = open(path, O_RDWR);
 	if (fd < 0)
diff --git libselinux-2.5/src/compute_create.c libselinux-2.5/src/compute_create.c
index 9559d42..14a65d1 100644
--- libselinux-2.5/src/compute_create.c
+++ libselinux-2.5/src/compute_create.c
@@ -64,6 +64,11 @@ int security_compute_create_name_raw(const char * scon,
 		return -1;
 	}
 
+	if ((! scon) || (! tcon)) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	snprintf(path, sizeof path, "%s/create", selinux_mnt);
 	fd = open(path, O_RDWR);
 	if (fd < 0)
diff --git libselinux-2.5/src/compute_member.c libselinux-2.5/src/compute_member.c
index 1fc7e41..065d996 100644
--- libselinux-2.5/src/compute_member.c
+++ libselinux-2.5/src/compute_member.c
@@ -25,6 +25,11 @@ int security_compute_member_raw(const char * scon,
 		return -1;
 	}
 
+	if ((! scon) || (! tcon)) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	snprintf(path, sizeof path, "%s/member", selinux_mnt);
 	fd = open(path, O_RDWR);
 	if (fd < 0)
diff --git libselinux-2.5/src/compute_relabel.c libselinux-2.5/src/compute_relabel.c
index 4615aee..cc77f36 100644
--- libselinux-2.5/src/compute_relabel.c
+++ libselinux-2.5/src/compute_relabel.c
@@ -25,6 +25,11 @@ int security_compute_relabel_raw(const char * scon,
 		return -1;
 	}
 
+	if ((! scon) || (! tcon)) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	snprintf(path, sizeof path, "%s/relabel", selinux_mnt);
 	fd = open(path, O_RDWR);
 	if (fd < 0)
diff --git libselinux-2.5/src/compute_user.c libselinux-2.5/src/compute_user.c
index b37c5d3..7703c26 100644
--- libselinux-2.5/src/compute_user.c
+++ libselinux-2.5/src/compute_user.c
@@ -24,6 +24,11 @@ int security_compute_user_raw(const char * scon,
 		return -1;
 	}
 
+	if (! scon) {
+		errno=EINVAL;
+		return -1;
+	}
+
 	snprintf(path, sizeof path, "%s/user", selinux_mnt);
 	fd = open(path, O_RDWR);
 	if (fd < 0)
diff --git libselinux-2.5/src/exception.sh libselinux-2.5/src/exception.sh
index b7cff7e..a58bf3f 100755
--- libselinux-2.5/src/exception.sh
+++ libselinux-2.5/src/exception.sh
@@ -15,6 +15,6 @@ echo "
 ;;
 esac
 }
-gcc -x c -c -I../include - -aux-info temp.aux < ../include/selinux/selinux.h
+${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/selinux/selinux.h
 for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done 
 rm -f -- temp.aux -.o
diff --git libselinux-2.5/src/file_path_suffixes.h libselinux-2.5/src/file_path_suffixes.h
index d1f9b48..95b228b 100644
--- libselinux-2.5/src/file_path_suffixes.h
+++ libselinux-2.5/src/file_path_suffixes.h
@@ -24,6 +24,7 @@ S_(BINPOLICY, "/policy/policy")
     S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context")
     S_(LXC_CONTEXTS, "/contexts/lxc_contexts")
     S_(OPENSSH_CONTEXTS, "/contexts/openssh_contexts")
+    S_(SNAPPERD_CONTEXTS, "/contexts/snapperd_contexts")
     S_(SYSTEMD_CONTEXTS, "/contexts/systemd_contexts")
     S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs")
     S_(FILE_CONTEXT_SUBS_DIST, "/contexts/files/file_contexts.subs_dist")
diff --git libselinux-2.5/src/fsetfilecon.c libselinux-2.5/src/fsetfilecon.c
index 52707d0..0cbe12d 100644
--- libselinux-2.5/src/fsetfilecon.c
+++ libselinux-2.5/src/fsetfilecon.c
@@ -9,8 +9,12 @@
 
 int fsetfilecon_raw(int fd, const char * context)
 {
-	int rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1,
-			 0);
+	int rc;
+	if (! context) {
+		errno=EINVAL;
+		return -1;
+	}
+	rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0);
 	if (rc < 0 && errno == ENOTSUP) {
 		char * ccontext = NULL;
 		int err = errno;
diff --git libselinux-2.5/src/init.c libselinux-2.5/src/init.c
index 3db4de0..3c687a2 100644
--- libselinux-2.5/src/init.c
+++ libselinux-2.5/src/init.c
@@ -11,7 +11,6 @@
 #include <sys/vfs.h>
 #include <stdint.h>
 #include <limits.h>
-#include <sys/mount.h>
 
 #include "dso.h"
 #include "policy.h"
@@ -57,20 +56,15 @@ static int verify_selinuxmnt(const char *mnt)
 
 int selinuxfs_exists(void)
 {
-	int exists = 0, mnt_rc = 0;
+	int exists = 0;
 	FILE *fp = NULL;
 	char *buf = NULL;
 	size_t len;
 	ssize_t num;
 
-	mnt_rc = mount("proc", "/proc", "proc", 0, 0);
-
 	fp = fopen("/proc/filesystems", "r");
-	if (!fp) {
-		exists = 1; /* Fail as if it exists */
-		goto out;
-	}
-
+	if (!fp)
+		return 1; /* Fail as if it exists */
 	__fsetlocking(fp, FSETLOCKING_BYCALLER);
 
 	num = getline(&buf, &len, fp);
@@ -84,14 +78,6 @@ int selinuxfs_exists(void)
 
 	free(buf);
 	fclose(fp);
-
-out:
-#ifndef MNT_DETACH
-#define MNT_DETACH 2
-#endif
-	if (mnt_rc == 0)
-		umount2("/proc", MNT_DETACH);
-
 	return exists;
 }
 hidden_def(selinuxfs_exists)
diff --git libselinux-2.5/src/load_policy.c libselinux-2.5/src/load_policy.c
index 21ee58b..4f39fc7 100644
--- libselinux-2.5/src/load_policy.c
+++ libselinux-2.5/src/load_policy.c
@@ -17,6 +17,10 @@
 #include "policy.h"
 #include <limits.h>
 
+#ifndef MNT_DETACH
+#define MNT_DETACH 2
+#endif
+
 int security_load_policy(void *data, size_t len)
 {
 	char path[PATH_MAX];
@@ -348,11 +352,6 @@ int selinux_init_load_policy(int *enforce)
 		fclose(cfg);
 		free(buf);
 	}
-#ifndef MNT_DETACH
-#define MNT_DETACH 2
-#endif
-	if (rc == 0)
-		umount2("/proc", MNT_DETACH);
 
 	/* 
 	 * Determine the final desired mode.
@@ -400,11 +399,17 @@ int selinux_init_load_policy(int *enforce)
 			/* Only emit this error if selinux was not disabled */
 			fprintf(stderr, "Mount failed for selinuxfs on %s:  %s\n", SELINUXMNT, strerror(errno));
 		}
+
+		if (rc == 0)
+			umount2("/proc", MNT_DETACH);
                 
 		goto noload;
 	}
 	set_selinuxmnt(mntpoint);
 
+	if (rc == 0)
+		umount2("/proc", MNT_DETACH);
+
 	/*
 	 * Note:  The following code depends on having selinuxfs 
 	 * already mounted and selinuxmnt set above.
diff --git libselinux-2.5/src/lsetfilecon.c libselinux-2.5/src/lsetfilecon.c
index 1d3b28a..ea6d70b 100644
--- libselinux-2.5/src/lsetfilecon.c
+++ libselinux-2.5/src/lsetfilecon.c
@@ -9,8 +9,13 @@
 
 int lsetfilecon_raw(const char *path, const char * context)
 {
-	int rc = lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1,
-			 0);
+	int rc;
+	if (! context) {
+		errno=EINVAL;
+		return -1;
+	}
+
+	rc = lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0);
 	if (rc < 0 && errno == ENOTSUP) {
 		char * ccontext = NULL;
 		int err = errno;
diff --git libselinux-2.5/src/matchpathcon.c libselinux-2.5/src/matchpathcon.c
index 5b495a0..a2f2c3e 100644
--- libselinux-2.5/src/matchpathcon.c
+++ libselinux-2.5/src/matchpathcon.c
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
+#include <syslog.h>
 #include "selinux_internal.h"
 #include "label_internal.h"
 #include "callbacks.h"
@@ -62,7 +63,7 @@ static void
 {
 	va_list ap;
 	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
+	vsyslog(LOG_ERR, fmt, ap);
 	va_end(ap);
 }
 
@@ -470,6 +471,17 @@ int selinux_file_context_verify(const char *path, mode_t mode)
 	char * con = NULL;
 	char * fcontext = NULL;
 	int rc = 0;
+	char stackpath[PATH_MAX + 1];
+	char *p = NULL;
+
+	if (S_ISLNK(mode)) {
+		if (!realpath_not_final(path, stackpath))
+			path = stackpath;
+	} else {
+		p = realpath(path, stackpath);
+		if (p)
+			path = p;
+	}
 
 	rc = lgetfilecon_raw(path, &con);
 	if (rc == -1) {
diff --git libselinux-2.5/src/procattr.c libselinux-2.5/src/procattr.c
index 527a0a5..eee4612 100644
--- libselinux-2.5/src/procattr.c
+++ libselinux-2.5/src/procattr.c
@@ -70,9 +70,9 @@ static int openattr(pid_t pid, const char *attr, int flags)
 	char *path;
 	pid_t tid;
 
-	if (pid > 0)
+	if (pid > 0) {
 		rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
-	else {
+	} else if (pid == 0) {
 		rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
 		if (rc < 0)
 			return -1;
@@ -82,6 +82,9 @@ static int openattr(pid_t pid, const char *attr, int flags)
 		free(path);
 		tid = gettid();
 		rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
+	} else {
+		errno = EINVAL;
+		return -1;
 	}
 	if (rc < 0)
 		return -1;
@@ -303,11 +306,21 @@ static int setprocattrcon(const char * context,
 #define getpidattr_def(fn, attr) \
 	int get##fn##_raw(pid_t pid, char **c)	\
 	{ \
-		return getprocattrcon_raw(c, pid, #attr); \
+		if (pid <= 0) { \
+			errno = EINVAL; \
+			return -1; \
+		} else { \
+			return getprocattrcon_raw(c, pid, #attr); \
+		} \
 	} \
 	int get##fn(pid_t pid, char **c)	\
 	{ \
-		return getprocattrcon(c, pid, #attr); \
+		if (pid <= 0) { \
+			errno = EINVAL; \
+			return -1; \
+		} else { \
+			return getprocattrcon(c, pid, #attr); \
+		} \
 	}
 
 all_selfattr_def(con, current)
diff --git libselinux-2.5/src/selinux_config.c libselinux-2.5/src/selinux_config.c
index bec5f3b..c519a77 100644
--- libselinux-2.5/src/selinux_config.c
+++ libselinux-2.5/src/selinux_config.c
@@ -50,7 +50,8 @@
 #define BOOLEAN_SUBS      27
 #define OPENSSH_CONTEXTS  28
 #define SYSTEMD_CONTEXTS  29
-#define NEL               30
+#define SNAPPERD_CONTEXTS 30
+#define NEL               31
 
 /* Part of one-time lazy init */
 static pthread_once_t once = PTHREAD_ONCE_INIT;
@@ -499,6 +500,13 @@ const char *selinux_openssh_contexts_path(void)
 
 hidden_def(selinux_openssh_contexts_path)
 
+const char *selinux_snapperd_contexts_path(void)
+{
+    return get_path(SNAPPERD_CONTEXTS);
+}
+
+hidden_def(selinux_snapperd_contexts_path)
+
 const char *selinux_systemd_contexts_path(void)
 {
 	return get_path(SYSTEMD_CONTEXTS);
diff --git libselinux-2.5/src/selinux_internal.h libselinux-2.5/src/selinux_internal.h
index 46566f6..9b9145c 100644
--- libselinux-2.5/src/selinux_internal.h
+++ libselinux-2.5/src/selinux_internal.h
@@ -84,6 +84,7 @@ hidden_proto(selinux_mkload_policy)
     hidden_proto(selinux_x_context_path)
     hidden_proto(selinux_sepgsql_context_path)
     hidden_proto(selinux_openssh_contexts_path)
+    hidden_proto(selinux_snapperd_contexts_path)
     hidden_proto(selinux_systemd_contexts_path)
     hidden_proto(selinux_path)
     hidden_proto(selinux_check_passwd_access)
diff --git libselinux-2.5/src/setfilecon.c libselinux-2.5/src/setfilecon.c
index d05969c..3f0200e 100644
--- libselinux-2.5/src/setfilecon.c
+++ libselinux-2.5/src/setfilecon.c
@@ -9,8 +9,12 @@
 
 int setfilecon_raw(const char *path, const char * context)
 {
-	int rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1,
-			0);
+	int rc;
+	if (! context) {
+		errno=EINVAL;
+		return -1;
+	}
+	rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0);
 	if (rc < 0 && errno == ENOTSUP) {
 		char * ccontext = NULL;
 		int err = errno;
diff --git libselinux-2.5/utils/.gitignore libselinux-2.5/utils/.gitignore
index 060eaab..ed3bf0b 100644
--- libselinux-2.5/utils/.gitignore
+++ libselinux-2.5/utils/.gitignore
@@ -14,7 +14,12 @@ getseuser
 matchpathcon
 policyvers
 sefcontext_compile
+selabel_digest
+selabel_lookup
+selabel_lookup_best_match
+selabel_partial_match
 selinux_check_securetty_context
+selinux_restorecon
 selinuxenabled
 selinuxexeccon
 setenforce