diff --git a/.gitignore b/.gitignore
index 12b57f3..ae56fa1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/libselinux-2.2.2.tgz
+SOURCES/libselinux-2.5.tar.gz
diff --git a/.libselinux.metadata b/.libselinux.metadata
index 80ee7c4..c799213 100644
--- a/.libselinux.metadata
+++ b/.libselinux.metadata
@@ -1 +1 @@
-722254a10c1156d15588c24752f56461a62d71df SOURCES/libselinux-2.2.2.tgz
+03a561762d7496cc756f1a6985ff63f8b4a7852d SOURCES/libselinux-2.5.tar.gz
diff --git a/SOURCES/libselinux-rhat.patch b/SOURCES/libselinux-rhat.patch
deleted file mode 100644
index 9c2b6e7..0000000
--- a/SOURCES/libselinux-rhat.patch
+++ /dev/null
@@ -1,883 +0,0 @@
-diff --git a/libselinux/Makefile b/libselinux/Makefile
-index fd4f0b1..51469bc 100644
---- a/libselinux/Makefile
-+++ b/libselinux/Makefile
-@@ -1,4 +1,4 @@
--SUBDIRS = src include utils man
-+SUBDIRS = src include utils man golang
- 
- DISABLE_AVC ?= n
- DISABLE_SETRANS ?= n
-diff --git a/libselinux/golang/Makefile b/libselinux/golang/Makefile
-new file mode 100644
-index 0000000..b75677b
---- /dev/null
-+++ b/libselinux/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 a/libselinux/golang/selinux.go b/libselinux/golang/selinux.go
-new file mode 100644
-index 0000000..6cee26a
---- /dev/null
-+++ b/libselinux/golang/selinux.go
-@@ -0,0 +1,378 @@
-+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 (
-+	"encoding/binary"
-+	"crypto/rand"
-+	"unsafe"
-+	"fmt"
-+	"bufio"
-+	"regexp"
-+	"io"
-+	"os"
-+	"strings"
-+)
-+
-+var (
-+	assignRegex  = regexp.MustCompile(`^([^=]+)=(.*)$`)
-+	mcs_list = make(map[string]bool)
-+)
-+
-+func Matchpathcon(path string, mode int) (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) (int, error) {
-+	var val *C.char
-+	if ! Selinux_enabled() {
-+		return 0, nil
-+	}
-+	if scon != "" {
-+		val = C.CString(scon)
-+	} else {
-+		val = nil
-+	}
-+        rc, err := C.setexeccon(val)
-+	return int(rc), err
-+}
-+
-+type Context struct {
-+	con []string
-+}
-+func (c *Context) Set_user(user string) {
-+	c.con[0]=user
-+}
-+func (c *Context) Get_user() string {
-+	return c.con[0]
-+}
-+func (c *Context) Set_role(role string) {
-+	c.con[1]=role
-+}
-+func (c *Context) Get_role() string {
-+	return c.con[1]
-+}
-+func (c *Context) Set_type(setype string) {
-+	c.con[2]=setype
-+}
-+func (c *Context) Get_type() string {
-+	return c.con[2]
-+}
-+func (c *Context) Set_level(mls string) {
-+	c.con[3]=mls
-+}
-+func (c *Context) Get_level() 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 New_context(scon string) Context {
-+	var con Context
-+	con.Set(scon)
-+	return con
-+}
-+
-+func Is_selinux_enabled() bool {
-+	b := C.is_selinux_enabled()
-+	if b > 0 {
-+		return true;
-+	}
-+	return false
-+}
-+
-+func Selinux_enabled() bool {
-+	b := C.is_selinux_enabled()
-+	if b > 0 {
-+		return true;
-+	}
-+	return false
-+}
-+
-+const (
-+	Enforcing = 1
-+	Permissive = 0
-+	Disabled = -1
-+)
-+
-+func Selinux_getenforce() int {
-+	return int(C.security_getenforce())
-+}
-+
-+func Selinux_getenforcemode() (int) {
-+	var enforce C.int
-+	C.selinux_getenforcemode(&enforce)
-+	return int(enforce)
-+}
-+
-+func mcs_add(mcs string) {
-+	mcs_list[mcs] = true
-+}
-+
-+func mcs_delete(mcs string) {
-+	mcs_list[mcs] = false
-+}
-+
-+func mcs_exists(mcs string) bool {
-+	return mcs_list[mcs] 
-+}
-+
-+func Int_to_mcs(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 uniq_mcs(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 mcs_exists(mcs) {
-+			continue
-+		}
-+		mcs_add(mcs)
-+		break
-+	}
-+	return mcs
-+}
-+func free_context(process_label string) {
-+	var scon Context
-+	scon = New_context(process_label)
-+	mcs_delete(scon.Get_level())
-+}
-+
-+func Get_lxc_contexts() (process_label string, file_label string) {
-+	var val, key string
-+	var bufin *bufio.Reader
-+	if ! Selinux_enabled() {
-+		return
-+	}
-+	lxc_path := C.GoString(C.selinux_lxc_contexts_path())
-+	file_label = "system_u:object_r:svirt_sandbox_file_t:s0"
-+	process_label = "system_u:system_r:svirt_lxc_net_t:s0"
-+
-+	in, err := os.Open(lxc_path)
-+	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" {
-+				process_label = strings.Trim(val,"\"")
-+			}
-+			if key == "file" {
-+				file_label = strings.Trim(val,"\"")
-+			}
-+		}
-+	}
-+exit:
-+	var scon Context
-+	mcs := Int_to_mcs(os.Getpid(), 1024)
-+	scon = New_context(process_label)
-+	scon.Set_level(mcs)
-+	process_label = scon.Get()
-+	scon = New_context(file_label)
-+	scon.Set_level(mcs)
-+	file_label = scon.Get()
-+	return process_label, file_label
-+}
-+
-+func CopyLevel (src, dest string) (string, error) {
-+	if ! Selinux_enabled() {
-+		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 := New_context(src)
-+	tcon := New_context(dest)
-+	tcon.Set_level(scon.Get_level())
-+	return tcon.Get(), nil
-+}
-+
-+func Test() {
-+	var plabel,flabel string
-+	if ! Selinux_enabled() {
-+		return
-+	}
-+
-+	plabel, flabel = Get_lxc_contexts()
-+	fmt.Println(plabel)
-+	fmt.Println(flabel)
-+	free_context(plabel)
-+	plabel, flabel = Get_lxc_contexts()
-+	fmt.Println(plabel)
-+	fmt.Println(flabel)
-+	free_context(plabel)
-+	if Selinux_enabled() {
-+		fmt.Println("Enabled")
-+	} else {
-+		fmt.Println("Disabled")
-+	}
-+	fmt.Println("getenforce ", Selinux_getenforce())
-+	fmt.Println("getenforcemode ", Selinux_getenforcemode())
-+	flabel,_ = Matchpathcon("/home/dwalsh/.emacs", 0)
-+	fmt.Println(flabel)
-+	pid := os.Getpid()
-+	fmt.Printf("PID:%d MCS:%s\n", pid, Int_to_mcs(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 a/libselinux/golang/test.go b/libselinux/golang/test.go
-new file mode 100644
-index 0000000..fed6de8
---- /dev/null
-+++ b/libselinux/golang/test.go
-@@ -0,0 +1,9 @@
-+package main
-+
-+import (
-+	"./selinux"
-+)
-+
-+func main() {
-+	selinux.Test()
-+}
-diff --git a/libselinux/man/man3/getfscreatecon.3 b/libselinux/man/man3/getfscreatecon.3
-index c7675be..677ece4 100644
---- a/libselinux/man/man3/getfscreatecon.3
-+++ b/libselinux/man/man3/getfscreatecon.3
-@@ -49,6 +49,11 @@ Signal handlers that perform a
- must take care to
- save, reset, and restore the fscreate context to avoid unexpected behavior.
- .
-+
-+.br
-+.B Note:
-+Contexts are thread specific.
-+
- .SH "RETURN VALUE"
- On error \-1 is returned.
- On success 0 is returned.
-diff --git a/libselinux/man/man3/getkeycreatecon.3 b/libselinux/man/man3/getkeycreatecon.3
-index d6a118c..b503535 100644
---- a/libselinux/man/man3/getkeycreatecon.3
-+++ b/libselinux/man/man3/getkeycreatecon.3
-@@ -48,6 +48,10 @@ Signal handlers that perform a
- .BR setkeycreatecon ()
- must take care to
- save, reset, and restore the keycreate context to avoid unexpected behavior.
-+
-+.br
-+.B Note:
-+Contexts are thread specific.
- .
- .SH "RETURN VALUE"
- On error \-1 is returned.
-diff --git a/libselinux/man/man3/getsockcreatecon.3 b/libselinux/man/man3/getsockcreatecon.3
-index 99e9436..673738c 100644
---- a/libselinux/man/man3/getsockcreatecon.3
-+++ b/libselinux/man/man3/getsockcreatecon.3
-@@ -49,6 +49,11 @@ Signal handlers that perform a
- must take care to
- save, reset, and restore the sockcreate context to avoid unexpected behavior.
- .
-+
-+.br
-+.B Note:
-+Contexts are thread specific.
-+
- .SH "RETURN VALUE"
- On error \-1 is returned.
- On success 0 is returned.
-diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
-index 02dd829..6dfdb46 100644
---- a/libselinux/src/Makefile
-+++ b/libselinux/src/Makefile
-@@ -114,7 +114,7 @@ $(LIBA): $(OBJS)
- 	$(RANLIB) $@
- 
- $(LIBSO): $(LOBJS)
--	$(CC) $(CFLAGS) -shared -o $@ $^ -lpcre -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
-+	$(CC) $(CFLAGS) -shared -o $@ $^ -lpcre -llzma -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
- 	ln -sf $@ $(TARGET) 
- 
- $(LIBPC): $(LIBPC).in ../VERSION
-diff --git a/libselinux/src/avc_sidtab.c b/libselinux/src/avc_sidtab.c
-index 0b696bb..506e236 100644
---- a/libselinux/src/avc_sidtab.c
-+++ b/libselinux/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 a/libselinux/src/canonicalize_context.c b/libselinux/src/canonicalize_context.c
-index 176c45a..6075025 100644
---- a/libselinux/src/canonicalize_context.c
-+++ b/libselinux/src/canonicalize_context.c
-@@ -17,6 +17,11 @@ int security_canonicalize_context_raw(const security_context_t con,
- 	size_t size;
- 	int fd, ret;
- 
-+	if (! con) {
-+		errno=EINVAL;
-+		return -1;
-+	}
-+
- 	if (!selinux_mnt) {
- 		errno = ENOENT;
- 		return -1;
-diff --git a/libselinux/src/check_context.c b/libselinux/src/check_context.c
-index 33ab5e3..1277bdd 100644
---- a/libselinux/src/check_context.c
-+++ b/libselinux/src/check_context.c
-@@ -14,6 +14,11 @@ int security_check_context_raw(const security_context_t con)
- 	char path[PATH_MAX];
- 	int fd, ret;
- 
-+	if (! con) {
-+		errno=EINVAL;
-+		return -1;
-+	}
-+
- 	if (!selinux_mnt) {
- 		errno = ENOENT;
- 		return -1;
-diff --git a/libselinux/src/compute_av.c b/libselinux/src/compute_av.c
-index 5962c0b..61ea454 100644
---- a/libselinux/src/compute_av.c
-+++ b/libselinux/src/compute_av.c
-@@ -26,6 +26,11 @@ int security_compute_av_flags_raw(const security_context_t 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 a/libselinux/src/compute_create.c b/libselinux/src/compute_create.c
-index 3c05be3..34a1ccd 100644
---- a/libselinux/src/compute_create.c
-+++ b/libselinux/src/compute_create.c
-@@ -64,6 +64,11 @@ int security_compute_create_name_raw(const security_context_t 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 a/libselinux/src/compute_member.c b/libselinux/src/compute_member.c
-index dad0a77..7850986 100644
---- a/libselinux/src/compute_member.c
-+++ b/libselinux/src/compute_member.c
-@@ -25,6 +25,11 @@ int security_compute_member_raw(const security_context_t 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 a/libselinux/src/compute_relabel.c b/libselinux/src/compute_relabel.c
-index 656f00a..2560e78 100644
---- a/libselinux/src/compute_relabel.c
-+++ b/libselinux/src/compute_relabel.c
-@@ -25,6 +25,11 @@ int security_compute_relabel_raw(const security_context_t 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 a/libselinux/src/compute_user.c b/libselinux/src/compute_user.c
-index 3b39ddd..af20735 100644
---- a/libselinux/src/compute_user.c
-+++ b/libselinux/src/compute_user.c
-@@ -24,6 +24,11 @@ int security_compute_user_raw(const security_context_t 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 a/libselinux/src/fsetfilecon.c b/libselinux/src/fsetfilecon.c
-index 9963f7a..37f9d74 100644
---- a/libselinux/src/fsetfilecon.c
-+++ b/libselinux/src/fsetfilecon.c
-@@ -9,8 +9,12 @@
- 
- int fsetfilecon_raw(int fd, const security_context_t 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) {
- 		security_context_t ccontext = NULL;
- 		int err = errno;
-diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c
-index e419f1a..275672d 100644
---- a/libselinux/src/load_policy.c
-+++ b/libselinux/src/load_policy.c
-@@ -16,6 +16,82 @@
- #include <dlfcn.h>
- #include "policy.h"
- #include <limits.h>
-+#include <lzma.h>
-+
-+static char *lzmaread(int fd, size_t *rsize) {
-+	int capacity = 64*1024;
-+	char *buf = NULL;
-+	int tmpsize = 8 * 1024;
-+	unsigned char tmp[tmpsize];
-+	unsigned char tmp_out[tmpsize];
-+	size_t size = 0;
-+	lzma_stream strm = LZMA_STREAM_INIT;
-+	lzma_action action = LZMA_RUN;
-+	lzma_ret ret;
-+	
-+	FILE *stream = fdopen (fd, "r");
-+	if (!stream) {
-+		return NULL;
-+	}
-+	ret = lzma_stream_decoder(&strm, UINT64_MAX,
-+				  LZMA_CONCATENATED);
-+	
-+	strm.avail_in = 0;
-+	strm.next_out = tmp_out;
-+	strm.avail_out = tmpsize;
-+	
-+	buf = (char *) malloc (capacity);
-+	if (!buf)
-+		goto err;
-+	
-+	while (1) {
-+		if (strm.avail_in == 0) {
-+			strm.next_in = tmp;
-+			strm.avail_in = fread(tmp, 1, tmpsize, stream);
-+			
-+			if (ferror(stream)) {
-+				// POSIX says that fread() sets errno if
-+				// an error occurred. ferror() doesn't
-+				// touch errno.
-+				goto err;
-+			}
-+			if (feof(stream)) action = LZMA_FINISH;
-+		}
-+		
-+		ret = lzma_code(&strm, action);
-+		
-+		// Write and check write error before checking decoder error.
-+		// This way as much data as possible gets written to output
-+		// even if decoder detected an error.
-+		if (strm.avail_out == 0 || ret != LZMA_OK) {
-+			const size_t num =  tmpsize - strm.avail_out;
-+			if (num > capacity) {
-+				buf = (char*) realloc (buf, size*2);
-+				capacity = size;
-+			}
-+			memcpy (buf+size, tmp_out, num);
-+			capacity -= num;
-+			size += num;
-+			strm.next_out = tmp_out;
-+			strm.avail_out = tmpsize;
-+		}
-+		if (ret != LZMA_OK) {
-+			if (ret == LZMA_STREAM_END) {
-+				break;
-+			} else {
-+				goto err;
-+			}
-+		}
-+	}
-+	*rsize = size;
-+	
-+	goto exit;
-+err:
-+	free(buf); buf = NULL;
-+exit:
-+	lzma_end(&strm);
-+	return buf;
-+}
- 
- int security_load_policy(void *data, size_t len)
- {
-@@ -55,7 +131,7 @@ int selinux_mkload_policy(int preservebools)
- 	struct stat sb;
- 	struct utsname uts;
- 	size_t size;
--	void *map, *data;
-+	void *map = NULL, *data=NULL;
- 	int fd, rc = -1, prot;
- 	sepol_policydb_t *policydb;
- 	sepol_policy_file_t *pf;
-@@ -181,24 +257,28 @@ checkbool:
- 		goto dlclose;
- 	}
- 
--	if (fstat(fd, &sb) < 0) {
--		fprintf(stderr,
--			"SELinux:  Could not stat policy file %s:  %s\n",
--			path, strerror(errno));
--		goto close;
--	}
--
--	prot = PROT_READ;
--	if (setlocaldefs || preservebools)
--		prot |= PROT_WRITE;
-+	data = lzmaread(fd,&size);
- 
--	size = sb.st_size;
--	data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
--	if (map == MAP_FAILED) {
--		fprintf(stderr,
--			"SELinux:  Could not map policy file %s:  %s\n",
-+	if (!data) {
-+		if (fstat(fd, &sb) < 0) {
-+			fprintf(stderr,
-+				"SELinux:  Could not stat policy file %s:  %s\n",
- 			path, strerror(errno));
--		goto close;
-+			goto close;
-+		}
-+		
-+		prot = PROT_READ;
-+		if (setlocaldefs || preservebools)
-+			prot |= PROT_WRITE;
-+		
-+		size = sb.st_size;
-+		data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
-+		if (map == MAP_FAILED) {
-+			fprintf(stderr,
-+				"SELinux:  Could not map policy file %s:  %s\n",
-+				path, strerror(errno));
-+			goto close;
-+		}
- 	}
- 
- 	if (vers > kernvers && usesepol) {
-@@ -210,6 +290,8 @@ checkbool:
- 			goto unmap;
- 		}
- 		policy_file_set_mem(pf, data, size);
-+		if (!map)
-+			free(data);
- 		if (policydb_read(policydb, pf)) {
- 			policy_file_free(pf);
- 			policydb_free(policydb);
-@@ -223,7 +305,8 @@ checkbool:
- 				path);
- 			policy_file_free(pf);
- 			policydb_free(policydb);
--			munmap(map, sb.st_size);
-+			if (map)
-+				munmap(map, sb.st_size);
- 			close(fd);
- 			vers--;
- 			goto search;
-@@ -275,7 +358,7 @@ checkbool:
- #endif
- 	}
- 
--
-+	
- 	rc = security_load_policy(data, size);
- 	
- 	if (rc)
-@@ -286,7 +369,8 @@ checkbool:
-       unmap:
- 	if (data != map)
- 		free(data);
--	munmap(map, sb.st_size);
-+	if (map)
-+		munmap(map, sb.st_size);
-       close:
- 	close(fd);
-       dlclose:
-diff --git a/libselinux/src/lsetfilecon.c b/libselinux/src/lsetfilecon.c
-index fd9bb26..af2d88c 100644
---- a/libselinux/src/lsetfilecon.c
-+++ b/libselinux/src/lsetfilecon.c
-@@ -9,8 +9,13 @@
- 
- int lsetfilecon_raw(const char *path, const security_context_t 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) {
- 		security_context_t ccontext = NULL;
- 		int err = errno;
-diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
-index 2d7369e..2a00807 100644
---- a/libselinux/src/matchpathcon.c
-+++ b/libselinux/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 a/libselinux/src/setfilecon.c b/libselinux/src/setfilecon.c
-index 50cb228..e617039 100644
---- a/libselinux/src/setfilecon.c
-+++ b/libselinux/src/setfilecon.c
-@@ -9,8 +9,12 @@
- 
- int setfilecon_raw(const char *path, const security_context_t 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) {
- 		security_context_t ccontext = NULL;
- 		int err = errno;
diff --git a/SOURCES/libselinux-rhel.patch b/SOURCES/libselinux-rhel.patch
new file mode 100644
index 0000000..5a06f64
--- /dev/null
+++ b/SOURCES/libselinux-rhel.patch
@@ -0,0 +1,1315 @@
+diff --git libselinux-2.5/ChangeLog libselinux-2.5/ChangeLog
+index 24673dd..41507e4 100644
+--- libselinux-2.5/ChangeLog
++++ libselinux-2.5/ChangeLog
+@@ -1,3 +1,20 @@
++	* Handle NULL pcre study data, from Stephen Smalley.
++	* Fix in tree compilation of utils that depend on libsepol, from Laurent Bigonville.
++	* 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/label_file.c libselinux-2.5/src/label_file.c
+index 071d902..c89bb35 100644
+--- libselinux-2.5/src/label_file.c
++++ libselinux-2.5/src/label_file.c
+@@ -388,18 +388,21 @@ static int load_mmap(struct selabel_handle *rec, const char *path,
+ 			rc = -1;
+ 			goto err;
+ 		}
+-		spec->lsd.study_data = (void *)mmap_area->next_addr;
+-		spec->lsd.flags |= PCRE_EXTRA_STUDY_DATA;
+-		rc = next_entry(NULL, mmap_area, entry_len);
+-		if (rc < 0)
+-			goto err;
+ 
+-		/* Check that study data lengths match. */
+-		rc = pcre_fullinfo(spec->regex, &spec->lsd,
+-				    PCRE_INFO_STUDYSIZE, &len);
+-		if (rc < 0 || len != entry_len) {
+-			rc = -1;
+-			goto err;
++		if (entry_len) {
++			spec->lsd.study_data = (void *)mmap_area->next_addr;
++			spec->lsd.flags |= PCRE_EXTRA_STUDY_DATA;
++			rc = next_entry(NULL, mmap_area, entry_len);
++			if (rc < 0)
++				goto err;
++
++			/* Check that study data lengths match. */
++			rc = pcre_fullinfo(spec->regex, &spec->lsd,
++					   PCRE_INFO_STUDYSIZE, &len);
++			if (rc < 0 || len != entry_len) {
++				rc = -1;
++				goto err;
++			}
+ 		}
+ 
+ 		data->nspec++;
+diff --git libselinux-2.5/src/label_file.h libselinux-2.5/src/label_file.h
+index 72fed1f..6d1e890 100644
+--- libselinux-2.5/src/label_file.h
++++ libselinux-2.5/src/label_file.h
+@@ -80,9 +80,12 @@ struct saved_data {
+ 
+ static inline pcre_extra *get_pcre_extra(struct spec *spec)
+ {
+-	if (spec->from_mmap)
+-		return &spec->lsd;
+-	else
++	if (spec->from_mmap) {
++		if (spec->lsd.study_data)
++			return &spec->lsd;
++		else
++			return NULL;
++	} else
+ 		return spec->sd;
+ }
+ 
+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/setexecfilecon.c libselinux-2.5/src/setexecfilecon.c
+index e72ba0d..9c821f8 100644
+--- libselinux-2.5/src/setexecfilecon.c
++++ libselinux-2.5/src/setexecfilecon.c
+@@ -45,7 +45,7 @@ int setexecfilecon(const char *filename, const char *fallback_type)
+ 		goto out;
+       out:
+ 
+-	if (rc < 0 && security_getenforce() == 0)
++	if (rc < 0 && security_getenforce() < 1)
+ 		rc = 0;
+ 
+ 	context_free(con);
+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
+diff --git libselinux-2.5/utils/Makefile libselinux-2.5/utils/Makefile
+index cf7af52..8497cb4 100644
+--- libselinux-2.5/utils/Makefile
++++ libselinux-2.5/utils/Makefile
+@@ -3,6 +3,7 @@ PREFIX ?= $(DESTDIR)/usr
+ LIBDIR ?= $(PREFIX)/lib
+ USRBINDIR ?= $(PREFIX)/sbin
+ SBINDIR ?= $(DESTDIR)/sbin
++INCLUDEDIR ?= $(PREFIX)/include
+ 
+ MAX_STACK_SIZE=8192
+ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissing-include-dirs \
+@@ -23,7 +24,7 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi
+           -fasynchronous-unwind-tables -fdiagnostics-show-option -funit-at-a-time \
+           -fipa-pure-const -Wno-suggest-attribute=pure -Wno-suggest-attribute=const \
+           -Werror -Wno-aggregate-return -Wno-redundant-decls
+-override CFLAGS += -I../include -D_GNU_SOURCE $(EMFLAGS)
++override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE $(EMFLAGS)
+ LDLIBS += -L../src -lselinux -L$(LIBDIR)
+ 
+ TARGETS=$(patsubst %.c,%,$(wildcard *.c))
+diff --git libselinux-2.5/utils/sefcontext_compile.c libselinux-2.5/utils/sefcontext_compile.c
+index d2578b6..fd6fb78 100644
+--- libselinux-2.5/utils/sefcontext_compile.c
++++ libselinux-2.5/utils/sefcontext_compile.c
+@@ -228,10 +228,13 @@ static int write_binary_file(struct saved_data *data, int fd)
+ 		if (len != to_write)
+ 			goto err;
+ 
+-		/* determine the size of the pcre study info */
+-		rc = pcre_fullinfo(re, sd, PCRE_INFO_STUDYSIZE, &size);
+-		if (rc < 0)
+-			goto err;
++		if (sd) {
++			/* determine the size of the pcre study info */
++			rc = pcre_fullinfo(re, sd, PCRE_INFO_STUDYSIZE, &size);
++			if (rc < 0)
++				goto err;
++		} else
++			size = 0;
+ 
+ 		/* write the number of bytes in the pcre study data */
+ 		to_write = size;
+@@ -239,10 +242,12 @@ static int write_binary_file(struct saved_data *data, int fd)
+ 		if (len != 1)
+ 			goto err;
+ 
+-		/* write the actual pcre study data as a char array */
+-		len = fwrite(sd->study_data, 1, to_write, bin_file);
+-		if (len != to_write)
+-			goto err;
++		if (sd) {
++			/* write the actual pcre study data as a char array */
++			len = fwrite(sd->study_data, 1, to_write, bin_file);
++			if (len != to_write)
++				goto err;
++		}
+ 	}
+ 
+ 	rc = 0;
diff --git a/SPECS/libselinux.spec b/SPECS/libselinux.spec
index 0e659c1..1821e96 100644
--- a/SPECS/libselinux.spec
+++ b/SPECS/libselinux.spec
@@ -1,27 +1,31 @@
-%global with_python3 0
+%if 0%{?fedora} > 12
+%global with_python3 1
+%endif
 
 %define ruby_inc %(pkg-config --cflags ruby)
 %define ruby_sitearch %(ruby -rrbconfig -e "puts RbConfig::CONFIG['vendorarchdir']")
-%define libsepolver 2.1.9-1
+%define libsepolver 2.5-6
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
 
 Summary: SELinux library and simple utilities
 Name: libselinux
-Version: 2.2.2
+Version: 2.5
 Release: 6%{?dist}
 License: Public Domain
 Group: System Environment/Libraries
-Source: %{name}-%{version}.tgz
+# https://github.com/SELinuxProject/selinux/wiki/Releases
+Source: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libselinux-2.5.tar.gz
 Source1: selinuxconlist.8
 Source2: selinuxdefcon.8
-Url: http://oss.tresys.com/git/selinux.git
-Patch1: libselinux-rhat.patch
-BuildRequires: pkgconfig python-devel ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre-devel xz-devel
+Url: https://github.com/SELinuxProject/selinux/wiki
+# HEAD 95ce251a24e80e884c69771a497589323be2223c
+Patch1: libselinux-rhel.patch
+BuildRequires: pkgconfig python python-devel ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre-devel xz-devel
 %if 0%{?with_python3}
-BuildRequires: python3-devel
+BuildRequires: python3 python3-devel
 %endif # if with_python3
-Requires: libsepol >= %{libsepolver} pcre
-Conflicts: filesystem < 3
+Requires: libsepol%{?_isa} >= %{libsepolver} pcre
+Conflicts: filesystem < 3 systemd < 219-20
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 %description
@@ -42,7 +46,7 @@ decisions.  Required for any applications that use the SELinux API.
 %package utils
 Summary: SELinux libselinux utilies
 Group: Development/Libraries
-Requires: libselinux = %{version}-%{release} 
+Requires: libselinux%{?_isa} = %{version}-%{release}
 
 %description utils
 The libselinux-utils package contains the utilities
@@ -50,7 +54,7 @@ The libselinux-utils package contains the utilities
 %package python
 Summary: SELinux python bindings for libselinux
 Group: Development/Libraries
-Requires: libselinux = %{version}-%{release} 
+Requires: libselinux%{?_isa} = %{version}-%{release}
 
 %description python
 The libselinux-python package contains the python bindings for developing 
@@ -60,7 +64,7 @@ SELinux applications.
 %package python3
 Summary: SELinux python 3 bindings for libselinux
 Group: Development/Libraries
-Requires: libselinux = %{version}-%{release} 
+Requires: libselinux%{?_isa} = %{version}-%{release}
 
 %description python3
 The libselinux-python3 package contains python 3 bindings for developing
@@ -70,7 +74,7 @@ SELinux applications.
 %package ruby
 Summary: SELinux ruby bindings for libselinux
 Group: Development/Libraries
-Requires: libselinux = %{version}-%{release} 
+Requires: libselinux%{?_isa} = %{version}-%{release}
 Provides: ruby(selinux)
 
 %description ruby
@@ -80,8 +84,8 @@ SELinux applications.
 %package devel
 Summary: Header files and libraries used to build SELinux
 Group: Development/Libraries
-Requires: libselinux = %{version}-%{release} 
-Requires: libsepol-devel >= %{libsepolver}
+Requires: libselinux%{?_isa} = %{version}-%{release}
+Requires: libsepol-devel%{?_isa} >= %{libsepolver}
 
 %description devel
 The libselinux-devel package contains the libraries and header files
@@ -90,17 +94,20 @@ needed for developing SELinux applications.
 %package static
 Summary: Static libraries used to build SELinux
 Group: Development/Libraries
-Requires: libselinux-devel = %{version}-%{release}
+Requires: libselinux-devel%{?_isa} = %{version}-%{release}
 
 %description static
 The libselinux-static package contains the static libraries
 needed for developing SELinux applications. 
 
 %prep
-%setup -q
-%patch1 -p2 -b .rhat
+%setup -q -n libselinux-2.5
+%patch1 -p1 -b .rhel
 
 %build
+export LDFLAGS="%{?__global_ldflags}"
+# FIXME: export DISABLE_RPM="y"
+
 # To support building the Python wrapper against multiple Python runtimes
 # Define a function, for how to perform a "build" of the python wrapper against
 # a specific runtime:
@@ -155,7 +162,7 @@ InstallPythonWrapper %{__python}
 InstallPythonWrapper %{__python3}
 %endif # with_python3
 
-make DESTDIR="%{buildroot}" LIBDIR="%{buildroot}%{_libdir}" SHLIBDIR="%{buildroot}%{_libdir}" BINDIR="%{buildroot}%{_bindir}" SBINDIR="%{buildroot}%{_sbindir}" RUBYINSTALL=%{buildroot}%{ruby_sitearch} install install-rubywrap
+make DESTDIR="%{buildroot}" LIBDIR="%{buildroot}%{_libdir}" SHLIBDIR="%{buildroot}%{_libdir}" BINDIR="%{buildroot}%{_bindir}" SBINDIR="%{buildroot}%{_sbindir}" RUBYINSTALL=%{buildroot}%{ruby_vendorarchdir} install install-rubywrap
 
 # Nuke the files we don't want to distribute
 rm -f %{buildroot}%{_sbindir}/compute_*
@@ -204,6 +211,11 @@ rm -rf %{buildroot}
 %{_sbindir}/selinuxexeccon
 %{_sbindir}/selinuxenabled
 %{_sbindir}/setenforce
+%{_sbindir}/selabel_digest
+%{_sbindir}/selabel_lookup
+%{_sbindir}/selabel_lookup_best_match
+%{_sbindir}/selabel_partial_match
+%{_sbindir}/selinux_restorecon
 %{_mandir}/man5/*
 %{_mandir}/man8/*
 
@@ -211,9 +223,9 @@ rm -rf %{buildroot}
 %defattr(-,root,root,-)
 %{_libdir}/libselinux.so
 %{_libdir}/pkgconfig/libselinux.pc
-%dir %{_includedir}/selinux
 %dir %{_libdir}/golang/src/pkg/github.com/selinux
 %{_libdir}/golang/src/pkg/github.com/selinux/selinux.go
+%dir %{_includedir}/selinux
 %{_includedir}/selinux/*
 %{_mandir}/man3/*
 
@@ -238,9 +250,39 @@ rm -rf %{buildroot}
 
 %files ruby
 %defattr(-,root,root,-)
-%{ruby_sitearch}/selinux.so
+%{ruby_vendorarchdir}/selinux.so
 
 %changelog
+* Fri Aug 26 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-6
+- Handle NULL pcre study data
+
+* Wed Aug 10 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-5
+- Fix in tree compilation of utils that depend on libsepol
+
+* Mon Jun 27 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-4
+- Clarify is_selinux_mls_enabled() description
+- Explain how to free policy type from selinux_getpolicytype()
+- Compare absolute pathname in matchpathcon -V
+- Add selinux_snapperd_contexts_path()
+- Modify audit2why analyze function to use loaded policy
+- Sort object files for deterministic linking order
+- Respect CC and PKG_CONFIG environment variable
+- Avoid mounting /proc outside of selinux_init_load_policy()
+- Fix multiple spelling errors
+
+* Wed Apr 27 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-3
+- Fix setexecfilecon() to work better in a chroot (#1329931)
+- Fix typo in sefcontext_compile.8 (#1320062)
+
+* Mon Apr 11 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-2
+- Fix location of selinuxfs mount point (#1321086)
+- Only mount /proc if necessary
+- procattr: return einval for <= 0 pid args
+- procattr: return error on invalid pid_t inpu
+
+* Tue Feb 23 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-1
+- Update to upstream release 2016-02-23
+
 * Fri Feb 14 2014 Dan Walsh <dwalsh@redhat.com>  - 2.2.2-6
 - Add additional go bindings for get*con calls
 - Add go bindings test command