Blob Blame Raw
diff --git libselinux-2.5/ChangeLog libselinux-2.5/ChangeLog
index 24673dd..e696b94 100644
--- libselinux-2.5/ChangeLog
+++ libselinux-2.5/ChangeLog
@@ -1,3 +1,10 @@
+	* 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/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..b2df562 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>
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_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/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/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..3530594 100644
--- libselinux-2.5/src/init.c
+++ libselinux-2.5/src/init.c
@@ -12,6 +12,7 @@
 #include <stdint.h>
 #include <limits.h>
 #include <sys/mount.h>
+#include <linux/magic.h>
 
 #include "dso.h"
 #include "policy.h"
@@ -57,13 +58,19 @@ static int verify_selinuxmnt(const char *mnt)
 
 int selinuxfs_exists(void)
 {
-	int exists = 0, mnt_rc = 0;
+	int exists = 0, mnt_rc = -1, rc;
+	struct statfs sb;
 	FILE *fp = NULL;
 	char *buf = NULL;
 	size_t len;
 	ssize_t num;
 
-	mnt_rc = mount("proc", "/proc", "proc", 0, 0);
+	do {
+		rc = statfs("/proc", &sb);
+	} while (rc < 0 && errno == EINTR);
+
+	if (rc == 0 && ((uint32_t)sb.f_type != (uint32_t)PROC_SUPER_MAGIC))
+		mnt_rc = mount("proc", "/proc", "proc", 0, 0);
 
 	fp = fopen("/proc/filesystems", "r");
 	if (!fp) {
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..3868711 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);
 }
 
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/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;