From 63fcbfc7d1066edcef7667ca24834fb4a167b682 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Dec 20 2013 14:11:41 +0000 Subject: Mv selinux.go to /usr/share/gocode/src/selinux --- diff --git a/.gitignore b/.gitignore index 76558d8..2e9cec3 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,5 @@ libselinux-2.0.96.tgz /libselinux-2.1.11.tgz /libselinux-2.1.12.tgz /libselinux-2.1.13.tgz +/libselinux-2.2.tgz +/libselinux-2.2.1.tgz diff --git a/libselinux-rhat.patch b/libselinux-rhat.patch index 8ca2b1c..bf75861 100644 --- a/libselinux-rhat.patch +++ b/libselinux-rhat.patch @@ -1,1456 +1,543 @@ -diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h -index a4079aa..52d6700 100644 ---- a/libselinux/include/selinux/selinux.h -+++ b/libselinux/include/selinux/selinux.h -@@ -177,6 +177,7 @@ extern void selinux_set_callback(int type, union selinux_callback cb); - #define SELINUX_WARNING 1 - #define SELINUX_INFO 2 - #define SELINUX_AVC 3 -+#define SELINUX_TRANS_DIR "/var/run/setrans" - - /* Compute an access decision. */ - extern int security_compute_av(const security_context_t scon, -@@ -496,8 +497,15 @@ extern int selinux_getpolicytype(char **policytype); - */ - extern const char *selinux_policy_root(void); +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 -+/* -+ selinux_set_policy_root sets an alternate policy root directory path under -+ which the compiled policy file and context configuration files exist. -+ */ -+extern int selinux_set_policy_root(const char *rootpath); -+ - /* These functions return the paths to specific files under the - policy root directory. */ -+extern const char *selinux_current_policy_path(void); - extern const char *selinux_binary_policy_path(void); - extern const char *selinux_failsafe_context_path(void); - extern const char *selinux_removable_context_path(void); -@@ -515,6 +523,7 @@ extern const char *selinux_virtual_image_context_path(void); - 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_systemd_contexts_path(void); - extern const char *selinux_contexts_path(void); - extern const char *selinux_securetty_types_path(void); - extern const char *selinux_booleans_subs_path(void); -diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3 -index c6837fc..de62d26 100644 ---- a/libselinux/man/man3/security_compute_av.3 -+++ b/libselinux/man/man3/security_compute_av.3 -@@ -37,9 +37,9 @@ the SELinux policy database in the kernel - .sp - .BI "int security_compute_user_raw(security_context_t "scon ", const char *" username ", security_context_t **" con ); - .sp --.BI "int security_get_initial_context(const char *" name ", security_context_t " con ); -+.BI "int security_get_initial_context(const char *" name ", security_context_t *" con ); - .sp --.BI "int security_get_initial_context_raw(const char *" name ", security_context_t " con ); -+.BI "int security_get_initial_context_raw(const char *" name ", security_context_t *" con ); - .sp - .BI "int selinux_check_access(const security_context_t " scon ", const security_context_t " tcon ", const char *" class ", const char *" perm ", void *" auditdata); - .sp -diff --git a/libselinux/man/man3/security_disable.3 b/libselinux/man/man3/security_disable.3 -index aeb78da..c75ce0d 100644 ---- a/libselinux/man/man3/security_disable.3 -+++ b/libselinux/man/man3/security_disable.3 -@@ -17,7 +17,7 @@ and then unmounts - 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, - but only placed in "permissive" mode by using --.BR setenforce (1). -+.BR security_setenforce(3). - . - .SH "RETURN VALUE" - .BR security_disable () -@@ -27,4 +27,4 @@ returns zero on success or \-1 on error. - This manual page has been written by Guido Trentalancia - . - .SH "SEE ALSO" --.BR selinux (8), " setenforce "(3) -+.BR selinux (8), " setenforce "(8) -diff --git a/libselinux/man/man3/security_load_policy.3 b/libselinux/man/man3/security_load_policy.3 -index c4439bf..af56163 100644 ---- a/libselinux/man/man3/security_load_policy.3 -+++ b/libselinux/man/man3/security_load_policy.3 -@@ -43,7 +43,7 @@ unmounted using a call to - .BR security_disable (3). - Therefore, after the initial policy load, the only operational changes - are those permitted by --.BR setenforce (3) -+.BR security_setenforce (3) - (i.e. eventually setting the framework in permissive mode rather than - in enforcing one). - . -@@ -54,4 +54,4 @@ Returns zero on success or \-1 on error. - This manual page has been written by Guido Trentalancia - . - .SH "SEE ALSO" --.BR selinux "(8), " security_disable "(3), " setenforce "(1) -+.BR selinux "(8), " security_disable "(3), " setenforce "(8) -diff --git a/libselinux/man/man3/selinux_binary_policy_path.3 b/libselinux/man/man3/selinux_binary_policy_path.3 -index ec97dcf..503c52c 100644 ---- a/libselinux/man/man3/selinux_binary_policy_path.3 -+++ b/libselinux/man/man3/selinux_binary_policy_path.3 -@@ -1,6 +1,6 @@ - .TH "selinux_binary_policy_path" "3" "15 November 2004" "dwalsh@redhat.com" "SELinux API Documentation" - .SH "NAME" --selinux_path, selinux_policy_root, selinux_binary_policy_path, -+selinux_path, selinux_policy_root, selinux_binary_policy_path, selinux_current_policy_path, - selinux_failsafe_context_path, selinux_removable_context_path, - selinux_default_context_path, selinux_user_contexts_path, - selinux_file_context_path, selinux_media_context_path, -@@ -17,6 +17,8 @@ directories and files - .sp - .B const char *selinux_binary_policy_path(void); - .sp -+.B const char *selinux_current_policy_path(void); -+.sp - .B const char *selinux_failsafe_context_path(void); - .sp - .B const char *selinux_removable_context_path(void); -@@ -55,6 +57,9 @@ returns the top-level policy directory. - .BR selinux_binary_policy_path () - returns the binary policy file loaded into kernel. - .sp -+.BR selinux_current_policy_path () -+returns the currently loaded policy file from the kernel. -+.sp - .BR selinux_default_type_path () - returns the context file mapping roles to default types. - .sp -diff --git a/libselinux/man/man3/selinux_current_policy_path.3 b/libselinux/man/man3/selinux_current_policy_path.3 + DISABLE_AVC ?= n + DISABLE_SETRANS ?= n +diff --git a/libselinux/golang/Makefile b/libselinux/golang/Makefile new file mode 100644 -index 0000000..175a611 +index 0000000..e0be66f --- /dev/null -+++ b/libselinux/man/man3/selinux_current_policy_path.3 -@@ -0,0 +1 @@ -+.so man3/selinux_binary_policy_path.3 -diff --git a/libselinux/man/man3/selinux_policy_root.3 b/libselinux/man/man3/selinux_policy_root.3 -index a6ccf86..63dc901 100644 ---- a/libselinux/man/man3/selinux_policy_root.3 -+++ b/libselinux/man/man3/selinux_policy_root.3 -@@ -1,21 +1,34 @@ - .TH "selinux_policy_root" "3" "25 May 2004" "dwalsh@redhat.com" "SELinux API documentation" - .SH "NAME" - selinux_policy_root \- return the path of the SELinux policy files for this machine -+selinux_set_policy_root \- Set an alternate SELinux root path for the SELinux policy files for this machine. - . - .SH "SYNOPSIS" - .B #include - .sp - .B const char *selinux_policy_root(void); - . -+.sp -+.B int selinux_set_policy_root(const char *policypath); -+. - .SH "DESCRIPTION" - .BR selinux_policy_root () - reads the contents of the - .I /etc/selinux/config - file to determine which policy files should be used for this machine. - . -+.BR selinux_set_policy_root () -+sets up all all policy paths based on the alternate root ++++ b/libselinux/golang/Makefile +@@ -0,0 +1,17 @@ ++# Installation directories. ++PREFIX ?= $(DESTDIR)/usr ++GODIR ?= $(PREFIX)/share/gocode/src/selinux + -+.I /etc/selinux/config -+file to determine which policy files should be used for this machine. -+. - .SH "RETURN VALUE" --On success, returns a directory path containing the SELinux policy files. --On failure, NULL is returned. -+On success, selinux_policy_root returns a directory path containing the SELinux policy files. -+On failure, selinux_policy_root returns NULL. ++all: + -+On success, selinux_set_policy_root returns 0 on success -1 on failure. ++install: ++ [ -d $(GODIR) ] || mkdir -p $(GODIR) ++ install -m 644 selinux.go $(GODIR) + - . - .SH "SEE ALSO" - .BR selinux "(8)" -diff --git a/libselinux/man/man3/selinux_set_policy_root.3 b/libselinux/man/man3/selinux_set_policy_root.3 -new file mode 100644 -index 0000000..8077658 ---- /dev/null -+++ b/libselinux/man/man3/selinux_set_policy_root.3 -@@ -0,0 +1 @@ -+.so man3/selinux_policy_root.3 -diff --git a/libselinux/man/man5/secolor.conf.5 b/libselinux/man/man5/secolor.conf.5 -deleted file mode 100644 -index b834577..0000000 ---- a/libselinux/man/man5/secolor.conf.5 -+++ /dev/null -@@ -1,178 +0,0 @@ --.TH "secolor.conf" "5" "08 April 2011" "SELinux API documentation" --.SH "NAME" --secolor.conf \- The SELinux color configuration file --. --.SH "DESCRIPTION" --This optional file controls the color to be associated to the context components associated to the --.I raw --context passed by --.BR selinux_raw_context_to_color "(3)," --when context related information is to be displayed in color by an SELinux-aware application. --.sp --.BR selinux_raw_context_to_color "(3)" --obtains this color information from the active policy --.B secolor.conf --file as returned by --.BR selinux_colors_path "(3)." --. --.SH "FILE FORMAT" --The file format is as follows: --.RS --.B color --.I color_name --.BI "= #"color_mask --.br --[...] --.sp --.I context_component string --.B = --.I fg_color_name bg_color_name --.br --[...] --.sp --.RE -- --Where: --.br --.B color --.RS --The color keyword. Each color entry is on a new line. --.RE --.I color_name --.RS --A single word name for the color (e.g. red). --.RE --.I color_mask --.RS --A color mask starting with a hash (#) that describes the hexadecimal RGB colors with black being #000000 and white being #ffffff. --.RE --.I context_component --.RS --The context component name that must be one of the following: --.br --.RS --user, role, type or range --.RE --Each --.IR context_component " " string " ..." --entry is on a new line. --.RE --.I string --.RS --This is the --.I context_component --string that will be matched with the --.I raw --context component passed by --.BR selinux_raw_context_to_color "(3)." --.br --A wildcard '*' may be used to match any undefined string for the user, role and type --.I context_component --entries only. --.RE -- --.I fg_color_name --.RS --The color_name string that will be used as the foreground color. --A --.I color_mask --may also be used. --.RE --.I bg_color_name --.RS --The color_name string that will be used as the background color. --A --.I color_mask --may also be used. --.RE --. --.SH "EXAMPLES" --Example 1 entries are: --.RS --color black = #000000 --.br --color green = #008000 --.br --color yellow = #ffff00 --.br --color blue = #0000ff --.br --color white = #ffffff --.br --color red = #ff0000 --.br --color orange = #ffa500 --.br --color tan = #D2B48C --.sp --user * = black white --.br --role * = white black --.br --type * = tan orange --.br --range s0\-s0:c0.c1023 = black green --.br --range s1\-s1:c0.c1023 = white green --.br --range s3\-s3:c0.c1023 = black tan --.br --range s5\-s5:c0.c1023 = white blue --.br --range s7\-s7:c0.c1023 = black red --.br --range s9\-s9:c0.c1023 = black orange --.br --range s15:c0.c1023 = black yellow --.RE -- --.sp --Example 2 entries are: --.RS --color black = #000000 --.br --color green = #008000 --.br --color yellow = #ffff00 --.br --color blue = #0000ff --.br --color white = #ffffff --.br --color red = #ff0000 --.br --color orange = #ffa500 --.br --color tan = #d2b48c --.sp --user unconfined_u = #ff0000 green --.br --role unconfined_r = red #ffffff --.br --type unconfined_t = red orange --.br --user user_u = black green --.br --role user_r = white black --.br --type user_t = tan red --.br --user xguest_u = black yellow --.br --role xguest_r = black red --.br --type xguest_t = black green --.br --user sysadm_u = white black --.br --range s0:c0.c1023 = black white --.br --user * = black white --.br --role * = black white --.br --type * = black white --.RE --. --.SH "SEE ALSO" --.BR selinux "(8), " selinux_raw_context_to_color "(3), " selinux_colors_path "(3)" -diff --git a/libselinux/man/man8/getenforce.8 b/libselinux/man/man8/getenforce.8 -index 906279f..e0924d8 100644 ---- a/libselinux/man/man8/getenforce.8 -+++ b/libselinux/man/man8/getenforce.8 -@@ -1,4 +1,4 @@ --.TH "getenforce" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" -+.TH "getenforce" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" - .SH "NAME" - getenforce \- get the current mode of SELinux - . -diff --git a/libselinux/man/man8/matchpathcon.8 b/libselinux/man/man8/matchpathcon.8 -index 368991f..5d60789 100644 ---- a/libselinux/man/man8/matchpathcon.8 -+++ b/libselinux/man/man8/matchpathcon.8 -@@ -13,6 +13,8 @@ matchpathcon \- get the default SELinux security context for the specified path - .IR file_contexts_file ] - .RB [ \-p - .IR prefix ] -+.RB [ \-P -+.IR policy_root_path ] - .I filepath... - . - .SH "DESCRIPTION" -@@ -46,6 +48,9 @@ Use alternate file_context file - .BI \-p " prefix" - Use prefix to speed translations - .TP -+.BI \-P " policy_root_path" -+Use alternate policy root path -+.TP - .B \-V - Verify file context on disk matches defaults - . -diff --git a/libselinux/man/man8/sefcontext_compile.8 b/libselinux/man/man8/sefcontext_compile.8 -new file mode 100644 -index 0000000..c37ed4a ---- /dev/null -+++ b/libselinux/man/man8/sefcontext_compile.8 -@@ -0,0 +1,19 @@ -+.TH "sefcontext_compile" "8" "27 Jun 2013" "dwalsh@redhat.com" "SELinux Command Line documentation" -+.SH "NAME" -+sefcontext_compile \- compile file context regular expression files -+. -+.SH "SYNOPSIS" -+.B sefcontext_compile inputfile -+. -+.SH "DESCRIPTION" -+sefcontext_compile is used libsemanage to compile file context regular expressions into prce format. sefcontext_compile writes the compiled prce file with the .bin suffix appended "inputfile".bin. This compiled file is used by libselinux file labeling functions. -+ -+.SH "EXAMPLE" -+sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts -+. -+.SH AUTHOR -+Dan Walsh, -+. -+.SH "SEE ALSO" -+.BR selinux (8), -+.BR semanage (8), -diff --git a/libselinux/man/man8/selinux.8 b/libselinux/man/man8/selinux.8 -index a328866..50868e4 100644 ---- a/libselinux/man/man8/selinux.8 -+++ b/libselinux/man/man8/selinux.8 -@@ -37,20 +37,22 @@ The - configuration file also controls what policy - is active on the system. SELinux allows for multiple policies to be - installed on the system, but only one policy may be active at any --given time. At present, two kinds of SELinux policy exist: targeted --and strict. The targeted policy is designed as a policy where most --processes operate without restrictions, and only specific services are -+given time. At present, multiple kinds of SELinux policy exist: targeted, -+mls for example. The targeted policy is designed as a policy where most -+user processes operate without restrictions, and only specific services are - placed into distinct security domains that are confined by the policy. - For example, the user would run in a completely unconfined domain - while the named daemon or apache daemon would run in a specific domain --tailored to its operation. The strict policy is designed as a policy --where all processes are partitioned into fine-grained security domains --and confined by policy. It is anticipated in the future that other --policies will be created (Multi-Level Security for example). You can -+tailored to its operation. The MLS (Multi-Level Security) policy is designed -+as a policy where all processes are partitioned into fine-grained security -+domains and confined by policy. MLS also supports the Bell And LaPadula model, where processes are not only confined by the type but also the level of the data. ++test: + -+You can - define which policy you will run by setting the - .B SELINUXTYPE - environment variable within - .IR /etc/selinux/config . -+You must reboot and possibly relabel if you change the policy type to have it take effect on the system. - The corresponding - policy configuration for each such policy must be installed in the - .I /etc/selinux/{SELINUXTYPE}/ -@@ -58,7 +60,7 @@ directories. - - A given SELinux policy can be customized further based on a set of - compile-time tunable options and a set of runtime policy booleans. --.B \%system\-config\-securitylevel -+.B \%system\-config\-selinux - allows customization of these booleans and tunables. - - Many domains that are protected by SELinux also include SELinux man pages explaining how to customize their policy. -@@ -86,11 +88,13 @@ This manual page was written by Dan Walsh . - .nh - .BR booleans (8), - .BR setsebool (8), --.BR selinuxenabled (8), -+.BR sepolicy (8), -+.BR system-config-selinux (8), - .BR togglesebool (8), - .BR restorecon (8), -+.BR fixfiles (8), - .BR setfiles (8), --.BR semange (8), -+.BR semanage (8), - .BR sepolicy(8) - - Every confined service on the system has a man page in the following format: -diff --git a/libselinux/man/man8/selinuxenabled.8 b/libselinux/man/man8/selinuxenabled.8 -index e0b5201..ac20587 100644 ---- a/libselinux/man/man8/selinuxenabled.8 -+++ b/libselinux/man/man8/selinuxenabled.8 -@@ -1,4 +1,4 @@ --.TH "selinuxenabled" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" -+.TH "selinuxenabled" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" - .SH "NAME" - selinuxenabled \- tool to be used within shell scripts to determine if selinux is enabled - . -diff --git a/libselinux/man/man8/selinuxexeccon.8 b/libselinux/man/man8/selinuxexeccon.8 -index 765cf8c..30c20ed 100644 ---- a/libselinux/man/man8/selinuxexeccon.8 -+++ b/libselinux/man/man8/selinuxexeccon.8 -@@ -1,4 +1,4 @@ --.TH "selinuxexeccon" "1" "14 May 2011" "dwalsh@redhat.com" "SELinux Command Line documentation" -+.TH "selinuxexeccon" "8" "14 May 2011" "dwalsh@redhat.com" "SELinux Command Line documentation" - .SH "NAME" - selinuxexeccon \- report SELinux context used for this executable - . -diff --git a/libselinux/man/man8/setenforce.8 b/libselinux/man/man8/setenforce.8 -index b038da0..8a24f1c 100644 ---- a/libselinux/man/man8/setenforce.8 -+++ b/libselinux/man/man8/setenforce.8 -@@ -1,4 +1,4 @@ --.TH "setenforce" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" -+.TH "setenforce" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation" - .SH "NAME" - setenforce \- modify the mode SELinux is running in - . -diff --git a/libselinux/man/man8/togglesebool.8 b/libselinux/man/man8/togglesebool.8 -index 948aff1..598dc94 100644 ---- a/libselinux/man/man8/togglesebool.8 -+++ b/libselinux/man/man8/togglesebool.8 -@@ -1,4 +1,4 @@ --.TH "togglesebool" "1" "26 Oct 2004" "sgrubb@redhat.com" "SELinux Command Line documentation" -+.TH "togglesebool" "8" "26 Oct 2004" "sgrubb@redhat.com" "SELinux Command Line documentation" - .SH "NAME" - togglesebool \- flip the current value of a SELinux boolean - . -diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile -index c4f5d4c..310177b 100644 ---- a/libselinux/src/Makefile -+++ b/libselinux/src/Makefile -@@ -18,9 +18,7 @@ RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")' - RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM') - RUBYINC ?= $(shell pkg-config --cflags ruby) - RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) --LIBBASE=$(shell basename $(LIBDIR)) -- --LDFLAGS ?= -lpcre -lpthread -+LIBBASE ?= $(shell basename $(LIBDIR)) - - VERSION = $(shell cat ../VERSION) - LIBVERSION = 1 -@@ -116,7 +114,7 @@ $(LIBA): $(OBJS) - $(RANLIB) $@ - - $(LIBSO): $(LOBJS) -- $(CC) $(CFLAGS) -shared -o $@ $^ -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro -+ $(CC) $(CFLAGS) -shared -o $@ $^ -lpcre -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro - ln -sf $@ $(TARGET) - - $(LIBPC): $(LIBPC).in ../VERSION -diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c -index ffe381b..560bc25 100644 ---- a/libselinux/src/audit2why.c -+++ b/libselinux/src/audit2why.c -@@ -210,27 +210,12 @@ static int __policy_init(const char *init_path) - return 1; - } - } else { -- vers = sepol_policy_kern_vers_max(); -- if (vers < 0) { -- snprintf(errormsg, sizeof(errormsg), -- "Could not get policy version: %s\n", -- strerror(errno)); -- PyErr_SetString( PyExc_ValueError, errormsg); -- return 1; -- } -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- while (!fp && errno == ENOENT && --vers) { -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- } -+ fp = fopen(selinux_current_policy_path(), "r"); - if (!fp) { - snprintf(errormsg, sizeof(errormsg), -- "unable to open %s.%d: %s\n", -- selinux_binary_policy_path(), -- security_policyvers(), strerror(errno)); -+ "unable to open %s: %s\n", -+ selinux_current_policy_path(), -+ strerror(errno)); - PyErr_SetString( PyExc_ValueError, errormsg); - return 1; - } -@@ -310,10 +295,12 @@ static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) { - } - - #define RETURN(X) \ -- PyTuple_SetItem(result, 0, Py_BuildValue("i", X)); \ -- return result; -+ { \ -+ return Py_BuildValue("iO", (X), Py_None); \ -+ } - - static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) { -+ char *reason_buf = NULL; - security_context_t scon; - security_context_t tcon; - char *tclassstr; -@@ -328,10 +315,6 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args - struct sepol_av_decision avd; - int rc; - int i=0; -- PyObject *result = PyTuple_New(2); -- if (!result) return NULL; -- Py_INCREF(Py_None); -- PyTuple_SetItem(result, 1, Py_None); - - if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj)) - return NULL; -@@ -342,22 +325,21 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args - /* should raise an error here. */ - if (numlines < 0) return NULL; /* Not a list */ - -- if (!avc) { -+ if (!avc) - RETURN(NOPOLICY) -- } - - rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid); -- if (rc < 0) { -+ if (rc < 0) - RETURN(BADSCON) -- } ++clean: + - rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid); -- if (rc < 0) { -+ if (rc < 0) - RETURN(BADTCON) -- } ++indent: + - tclass = string_to_security_class(tclassstr); -- if (!tclass) { -+ if (!tclass) - RETURN(BADTCLASS) -- } ++relabel: +diff --git a/libselinux/golang/selinux.go b/libselinux/golang/selinux.go +new file mode 100644 +index 0000000..018c955 +--- /dev/null ++++ b/libselinux/golang/selinux.go +@@ -0,0 +1,282 @@ ++package selinux + - /* Convert the permission list to an AV. */ - av = 0; - -@@ -377,21 +359,20 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args - #endif - - perm = string_to_av_perm(tclass, permstr); -- if (!perm) { -+ if (!perm) - RETURN(BADPERM) -- } ++/* ++ The selinux package is a go bindings to libselinux required to add selinux ++ support to docker. ++ ++ Author Dan Walsh ++ ++ Used some ideas/code from the go-ini packages https://github.com/vaughan0 ++ By Vaughan Newton ++*/ ++ ++// #cgo pkg-config: libselinux ++// #include ++// #include ++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 ++} + - av |= perm; - } - - /* Reproduce the computation. */ -- rc = sepol_compute_av_reason(ssid, tsid, tclass, av, &avd, &reason); -- if (rc < 0) { -+ rc = sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0); -+ if (rc < 0) - RETURN(BADCOMPUTE) -- } - -- if (!reason) { -+ if (!reason) - RETURN(ALLOW) -- } ++func Setfilecon(path,scon string) (int, error) { ++ rc, err := C.lsetfilecon(C.CString(path),C.CString(scon)) ++ return int(rc), err ++} + - if (reason & SEPOL_COMPUTEAV_TE) { - avc->ssid = ssid; - avc->tsid = tsid; -@@ -404,28 +385,34 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args - RETURN(TERULE) - } - } else { -- PyTuple_SetItem(result, 0, Py_BuildValue("i", BOOLEAN)); -+ PyObject *outboollist; - struct boolean_t *b = bools; - int len=0; - while (b->name) { - len++; b++; - } - b = bools; -- PyObject *outboollist = PyTuple_New(len); -+ outboollist = PyList_New(len); - len=0; - while(b->name) { -- PyObject *bool = Py_BuildValue("(si)", b->name, b->active); -- PyTuple_SetItem(outboollist, len++, bool); -+ PyObject *bool_ = Py_BuildValue("(si)", b->name, b->active); -+ PyList_SetItem(outboollist, len++, bool_); - b++; - } - free(bools); -- PyTuple_SetItem(result, 1, outboollist); -- return result; -+ /* 'N' steals the reference to outboollist */ -+ return Py_BuildValue("iN", BOOLEAN, outboollist); - } - } - - if (reason & SEPOL_COMPUTEAV_CONS) { -- RETURN(CONSTRAINT); -+ if (reason_buf) { -+ PyObject *result = NULL; -+ result = Py_BuildValue("is", CONSTRAINT, reason_buf); -+ free(reason_buf); -+ return result; -+ } -+ RETURN(CONSTRAINT) - } - - if (reason & SEPOL_COMPUTEAV_RBAC) -diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c -index 802a07f..6ff83a7 100644 ---- a/libselinux/src/avc.c -+++ b/libselinux/src/avc.c -@@ -827,6 +827,7 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid, - errsave = errno; - avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); - errno = errsave; -+ if (!avc_enforcing) return 0; - return rc; - } - -diff --git a/libselinux/src/file_path_suffixes.h b/libselinux/src/file_path_suffixes.h -index d11c8dc..3c92424 100644 ---- a/libselinux/src/file_path_suffixes.h -+++ b/libselinux/src/file_path_suffixes.h -@@ -23,6 +23,7 @@ S_(BINPOLICY, "/policy/policy") - S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context") - S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context") - S_(LXC_CONTEXTS, "/contexts/lxc_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") - S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts") -diff --git a/libselinux/src/fsetfilecon.c b/libselinux/src/fsetfilecon.c -index 309105c..0e9278e 100644 ---- a/libselinux/src/fsetfilecon.c -+++ b/libselinux/src/fsetfilecon.c -@@ -9,8 +9,20 @@ - - int fsetfilecon_raw(int fd, const security_context_t context) - { -- return fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, -+ int rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, - 0); -+ if (rc < 0 && errno == ENOTSUP) { -+ security_context_t ccontext = NULL; -+ int err = errno; -+ if ((fgetfilecon_raw(fd, &ccontext) >= 0) && -+ (strcmp(context,ccontext) == 0)) { -+ rc = 0; -+ } else { -+ errno = err; -+ } -+ freecon(ccontext); ++func Setexeccon(scon string) (int, error) { ++ var val *C.char ++ if ! Selinux_enabled() { ++ return 0, nil + } -+ return rc; - } - - hidden_def(fsetfilecon_raw) -diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c -index b9e8002..1d91123 100644 ---- a/libselinux/src/get_context_list.c -+++ b/libselinux/src/get_context_list.c -@@ -426,7 +426,7 @@ int get_ordered_context_list(const char *user, - /* Initialize ordering array. */ - ordering = malloc(nreach * sizeof(unsigned int)); - if (!ordering) -- goto oom_order; -+ goto failsafe; - for (i = 0; i < nreach; i++) - ordering[i] = nreach; - -@@ -435,7 +435,7 @@ int get_ordered_context_list(const char *user, - fname_len = strlen(user_contexts_path) + strlen(user) + 2; - fname = malloc(fname_len); - if (!fname) -- goto oom_order; -+ goto failsafe; - snprintf(fname, fname_len, "%s%s", user_contexts_path, user); - fp = fopen(fname, "r"); - if (fp) { -@@ -463,33 +463,31 @@ int get_ordered_context_list(const char *user, - __FUNCTION__, selinux_default_context_path()); - /* Fall through */ - } -+ rc = 0; - } - -+ if (!nordered) -+ goto failsafe; -+ - /* Apply the ordering. */ -- if (nordered) { -- co = malloc(nreach * sizeof(struct context_order)); -- if (!co) -- goto oom_order; -- for (i = 0; i < nreach; i++) { -- co[i].con = reachable[i]; -- co[i].order = ordering[i]; -- } -- qsort(co, nreach, sizeof(struct context_order), order_compare); -- for (i = 0; i < nreach; i++) -- reachable[i] = co[i].con; -- free(co); -+ co = malloc(nreach * sizeof(struct context_order)); -+ if (!co) -+ goto failsafe; -+ for (i = 0; i < nreach; i++) { -+ co[i].con = reachable[i]; -+ co[i].order = ordering[i]; - } -+ qsort(co, nreach, sizeof(struct context_order), order_compare); -+ for (i = 0; i < nreach; i++) -+ reachable[i] = co[i].con; -+ free(co); - -- /* Return the ordered list. -- If we successfully ordered it, then only report the ordered entries -- to the caller. Otherwise, fall back to the entire reachable list. */ -- if (nordered && nordered < nreach) { -+ /* Only report the ordered entries to the caller. */ -+ if (nordered <= nreach) { - for (i = nordered; i < nreach; i++) - free(reachable[i]); - reachable[nordered] = NULL; - rc = nordered; -- } else { -- rc = nreach; - } - - out: -@@ -523,14 +521,6 @@ int get_ordered_context_list(const char *user, - } - rc = 1; /* one context in the list */ - goto out; -- -- oom_order: -- /* Unable to order context list due to OOM condition. -- Fall back to unordered reachable context list. */ -- fprintf(stderr, "%s: out of memory, unable to order list\n", -- __FUNCTION__); -- rc = nreach; -- goto out; - } - - hidden_def(get_ordered_context_list) -diff --git a/libselinux/src/label.c b/libselinux/src/label.c -index 11f6e96..b6b3639 100644 ---- a/libselinux/src/label.c -+++ b/libselinux/src/label.c -@@ -43,12 +43,18 @@ static void selabel_subs_fini(struct selabel_sub *ptr) - static char *selabel_sub(struct selabel_sub *ptr, const char *src) - { - char *dst = NULL; -+ int len; - - while (ptr) { - if (strncmp(src, ptr->src, ptr->slen) == 0 ) { - if (src[ptr->slen] == '/' || - src[ptr->slen] == 0) { -- if (asprintf(&dst, "%s%s", ptr->dst, &src[ptr->slen]) < 0) -+ if ((src[ptr->slen] == '/') && -+ (strcmp(ptr->dst, "/") == 0)) -+ len = ptr->slen + 1; -+ else -+ len = ptr->slen; -+ if (asprintf(&dst, "%s%s", ptr->dst, &src[len]) < 0) - return NULL; - return dst; - } -@@ -58,7 +64,7 @@ static char *selabel_sub(struct selabel_sub *ptr, const char *src) - return NULL; - } - --struct selabel_sub *selabel_subs_init(const char *path,struct selabel_sub *list) -+struct selabel_sub *selabel_subs_init(const char *path, struct selabel_sub *list) - { - char buf[1024]; - FILE *cfg = fopen(path, "r"); -@@ -171,6 +177,7 @@ struct selabel_handle *selabel_open(unsigned int backend, - rec->validating = selabel_is_validate_set(opts, nopts); - - rec->subs = NULL; -+ rec->dist_subs = NULL; - - if ((*initfuncs[backend])(rec, opts, nopts)) { - free(rec); -@@ -186,13 +193,24 @@ selabel_lookup_common(struct selabel_handle *rec, int translating, - const char *key, int type) - { - struct selabel_lookup_rec *lr; -+ char *ptr = NULL; -+ char *dptr = NULL; - - if (key == NULL) { - errno = EINVAL; - return NULL; - } - -- char *ptr = selabel_sub(rec->subs, key); -+ ptr = selabel_sub(rec->subs, key); -+ if (ptr) { -+ dptr = selabel_sub(rec->dist_subs, ptr); -+ if (dptr) { -+ free(ptr); -+ ptr = dptr; -+ } ++ if scon != "" { ++ val = C.CString(scon) + } else { -+ ptr = selabel_sub(rec->dist_subs, key); -+ } - if (ptr) { - lr = rec->func_lookup(rec, ptr, type); - free(ptr); -diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c -index 5f697f3..c424a21 100644 ---- a/libselinux/src/label_file.c -+++ b/libselinux/src/label_file.c -@@ -496,12 +496,12 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - - /* Process local and distribution substitution files */ - if (!path) { -- rec->subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->subs); -+ rec->dist_subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->dist_subs); - rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs); - path = selinux_file_context_path(); - } else { - snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path); -- rec->subs = selabel_subs_init(subs_file, rec->subs); -+ rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs); - snprintf(subs_file, sizeof(subs_file), "%s.subs", path); - rec->subs = selabel_subs_init(subs_file, rec->subs); - } -@@ -649,6 +649,8 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec, - break; - } else if (rc == PCRE_ERROR_NOMATCH) - continue; -+ -+ errno = ENOENT; - /* else it's an error */ - goto finish; - } -@@ -660,6 +662,7 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec, - goto finish; - } - -+ errno = 0; - ret = &spec_arr[i].lr; - - finish: -diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h -index 435ecf2..b6ae140 100644 ---- a/libselinux/src/label_internal.h -+++ b/libselinux/src/label_internal.h -@@ -68,6 +68,7 @@ struct selabel_handle { - char *spec_file; - - /* substitution support */ -+ struct selabel_sub *dist_subs; - struct selabel_sub *subs; - }; - -diff --git a/libselinux/src/lsetfilecon.c b/libselinux/src/lsetfilecon.c -index 461e3f7..ab85155 100644 ---- a/libselinux/src/lsetfilecon.c -+++ b/libselinux/src/lsetfilecon.c -@@ -9,8 +9,20 @@ - - int lsetfilecon_raw(const char *path, const security_context_t context) - { -- return lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, -+ int rc = lsetxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, - 0); -+ if (rc < 0 && errno == ENOTSUP) { -+ security_context_t ccontext = NULL; -+ int err = errno; -+ if ((lgetfilecon_raw(path, &ccontext) >= 0) && -+ (strcmp(context,ccontext) == 0)) { -+ rc = 0; -+ } else { -+ errno = err; -+ } -+ freecon(ccontext); ++ val = nil + } -+ return rc; - } - - hidden_def(lsetfilecon_raw) -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 - #include - #include -+#include - #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/procattr.c b/libselinux/src/procattr.c -index 6c5b45a..ecaccc6 100644 ---- a/libselinux/src/procattr.c -+++ b/libselinux/src/procattr.c -@@ -9,19 +9,30 @@ - #include "selinux_internal.h" - #include "policy.h" - -+#define UNSET (const security_context_t) -1 -+ - static __thread pid_t cpid; - static __thread pid_t tid; --static __thread security_context_t prev_current; --static __thread security_context_t prev_exec; --static __thread security_context_t prev_fscreate; --static __thread security_context_t prev_keycreate; --static __thread security_context_t prev_sockcreate; -+static __thread security_context_t prev_current = UNSET; -+static __thread security_context_t prev_exec = UNSET; -+static __thread security_context_t prev_fscreate = UNSET; -+static __thread security_context_t prev_keycreate = UNSET; -+static __thread security_context_t prev_sockcreate = UNSET; - - static pthread_once_t once = PTHREAD_ONCE_INIT; - static pthread_key_t destructor_key; - static int destructor_key_initialized = 0; - static __thread char destructor_initialized; - -+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden"))); -+extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *); ++ rc, err := C.setexeccon(val) ++ return int(rc), err ++} + -+static int __selinux_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void)) -+{ -+ return __register_atfork (prepare, parent, child, -+ &__dso_handle == NULL ? NULL : __dso_handle); ++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 +} + - static pid_t gettid(void) - { - return syscall(__NR_gettid); -@@ -29,11 +40,16 @@ static pid_t gettid(void) - - static void procattr_thread_destructor(void __attribute__((unused)) *unused) - { -- free(prev_current); -- free(prev_exec); -- free(prev_fscreate); -- free(prev_keycreate); -- free(prev_sockcreate); -+ if (prev_current != UNSET) -+ free(prev_current); -+ if (prev_exec != UNSET) -+ free(prev_exec); -+ if (prev_fscreate != UNSET) -+ free(prev_fscreate); -+ if (prev_keycreate != UNSET) -+ free(prev_keycreate); -+ if (prev_sockcreate != UNSET) -+ free(prev_sockcreate); - } - - static void free_procattr(void) -@@ -41,7 +57,7 @@ static void free_procattr(void) - procattr_thread_destructor(NULL); - tid = 0; - cpid = getpid(); -- prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = NULL; -+ prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = UNSET; - } - - void __attribute__((destructor)) procattr_destructor(void); -@@ -63,7 +79,7 @@ static inline void init_thread_destructor(void) - static void init_procattr(void) - { - if (__selinux_key_create(&destructor_key, procattr_thread_destructor) == 0) { -- pthread_atfork(NULL, NULL, free_procattr); -+ __selinux_atfork(NULL, NULL, free_procattr); - destructor_key_initialized = 1; - } - } -@@ -131,7 +147,7 @@ static int getprocattrcon_raw(security_context_t * context, - return -1; - }; - -- if (prev_context) { -+ if (prev_context && prev_context != UNSET) { - *context = strdup(prev_context); - if (!(*context)) { - return -1; -@@ -230,7 +246,8 @@ static int setprocattrcon_raw(security_context_t context, - - if (!context && !*prev_context) - return 0; -- if (context && *prev_context && !strcmp(context, *prev_context)) -+ if (context && *prev_context && *prev_context != UNSET -+ && !strcmp(context, *prev_context)) - return 0; - - fd = openattr(pid, attr, O_RDWR); -@@ -257,6 +274,8 @@ out: - free(context); - return -1; - } else { -+ if (*prev_context != UNSET) -+ free(*prev_context); - *prev_context = context; - return 0; - } -diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c -index 296f357..2cd6d54 100644 ---- a/libselinux/src/selinux_config.c -+++ b/libselinux/src/selinux_config.c -@@ -8,6 +8,8 @@ - #include - #include - #include -+#include -+#include "policy.h" - #include "selinux_internal.h" - #include "get_default_type_internal.h" - -@@ -48,7 +50,8 @@ - #define FILE_CONTEXT_SUBS_DIST 25 - #define LXC_CONTEXTS 26 - #define BOOLEAN_SUBS 27 --#define NEL 28 -+#define SYSTEMD_CONTEXTS 28 -+#define NEL 29 - - /* Part of one-time lazy init */ - static pthread_once_t once = PTHREAD_ONCE_INIT; -@@ -138,6 +141,13 @@ int selinux_getpolicytype(char **type) - - hidden_def(selinux_getpolicytype) - -+static int setpolicytype(const char *type) -+{ -+ free(selinux_policytype); -+ selinux_policytype = strdup(type); -+ return selinux_policytype ? 0 : -1; ++func Is_selinux_enabled() bool { ++ b := C.is_selinux_enabled() ++ if b > 0 { ++ return true; ++ } ++ return false +} + - static char *selinux_policyroot = NULL; - static const char *selinux_rootpath = SELINUXDIR; - -@@ -261,6 +271,37 @@ const char *selinux_policy_root(void) - return selinux_policyroot; - } - -+int selinux_set_policy_root(const char *path) -+{ -+ int i; -+ char *policy_type = strrchr(path, '/'); -+ if (!policy_type) { -+ errno = EINVAL; -+ return -1; ++func Selinux_enabled() bool { ++ b := C.is_selinux_enabled() ++ if b > 0 { ++ return true; + } -+ policy_type++; ++ return false ++} + -+ fini_selinuxmnt(); -+ fini_selinux_policyroot(); ++const ( ++ Enforcing = 1 ++ Permissive = 0 ++ Disabled = -1 ++) + -+ selinux_policyroot = strdup(path); -+ if (! selinux_policyroot) -+ return -1; ++func Selinux_getenforce() int { ++ return int(C.security_getenforce()) ++} + -+ if (setpolicytype(policy_type) != 0) -+ return -1; ++func Selinux_getenforcemode() (int) { ++ var enforce C.int ++ C.selinux_getenforcemode(&enforce) ++ return int(enforce) ++} + -+ for (i = 0; i < NEL; i++) -+ if (asprintf(&file_paths[i], "%s%s", -+ selinux_policyroot, -+ file_path_suffixes_data.str + -+ file_path_suffixes_idx[i]) -+ == -1) -+ return -1; ++func mcs_add(mcs string) { ++ mcs_list[mcs] = true ++} + -+ return 0; ++func mcs_delete(mcs string) { ++ mcs_list[mcs] = false +} + - const char *selinux_path(void) - { - return selinux_rootpath; -@@ -303,6 +344,31 @@ const char *selinux_binary_policy_path(void) - - hidden_def(selinux_binary_policy_path) - -+const char *selinux_current_policy_path(void) -+{ -+ int rc = 0; -+ int vers = 0; -+ static char policy_path[PATH_MAX]; ++func mcs_exists(mcs string) bool { ++ return mcs_list[mcs] ++} + -+ if (selinux_mnt) { -+ snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt); -+ if (access(policy_path, F_OK) == 0 ) { -+ return policy_path; ++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 + } -+ vers = security_policyvers(); -+ do { -+ /* Check prior versions to see if old policy is available */ -+ snprintf(policy_path, sizeof(policy_path), "%s.%d", -+ selinux_binary_policy_path(), vers); -+ } while ((rc = access(policy_path, F_OK)) && --vers > 0); -+ -+ if (rc) return NULL; -+ return policy_path; ++ return mcs ++} ++func free_context(process_label string) { ++ var scon Context ++ scon = New_context(process_label) ++ mcs_delete(scon.Get_level()) +} + -+hidden_def(selinux_current_policy_path) ++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" + - const char *selinux_file_context_path(void) - { - return get_path(FILE_CONTEXTS); -@@ -427,6 +493,13 @@ const char *selinux_lxc_contexts_path(void) - - hidden_def(selinux_lxc_contexts_path) - -+const char *selinux_systemd_contexts_path(void) -+{ -+ return get_path(SYSTEMD_CONTEXTS); -+} ++ in, err := os.Open(lxc_path) ++ if err != nil { ++ goto exit ++ } + -+hidden_def(selinux_systemd_contexts_path) ++ defer in.Close() ++ bufin = bufio.NewReader(in) + - const char * selinux_booleans_subs_path(void) { - return get_path(BOOLEAN_SUBS); - } -diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h -index 2c7c85c..afb2170 100644 ---- a/libselinux/src/selinux_internal.h -+++ b/libselinux/src/selinux_internal.h -@@ -60,6 +60,7 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(security_setenforce) - hidden_proto(security_deny_unknown) - hidden_proto(selinux_boolean_sub) -+ hidden_proto(selinux_current_policy_path) - hidden_proto(selinux_binary_policy_path) - hidden_proto(selinux_booleans_subs_path) - hidden_proto(selinux_default_context_path) -@@ -82,6 +83,7 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(selinux_media_context_path) - hidden_proto(selinux_x_context_path) - hidden_proto(selinux_sepgsql_context_path) -+ hidden_proto(selinux_systemd_contexts_path) - hidden_proto(selinux_path) - hidden_proto(selinux_check_passwd_access) - hidden_proto(selinux_check_securetty_context) -diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i -index 359bd02..9884454 100644 ---- a/libselinux/src/selinuxswig_python.i -+++ b/libselinux/src/selinuxswig_python.i -@@ -10,6 +10,10 @@ - - import shutil, os, stat - -+DISABLED = -1 -+PERMISSIVE = 0 -+ENFORCING = 1 ++ 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 := uniq_mcs(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 ++} + - def restorecon(path, recursive=False): - """ Restore SELinux context on a given path """ - -@@ -74,6 +78,10 @@ def install(src, dest): - $1 = &temp; - } - -+%typemap(in, numinputs=0) void *(char *temp=NULL) { -+ $1 = temp; ++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 +} + - /* Makes security_compute_user() return a Python list of contexts */ - %typemap(argout) (security_context_t **con) { - PyObject* plist; -diff --git a/libselinux/src/setfilecon.c b/libselinux/src/setfilecon.c -index 7465c6a..9aaaa4b 100644 ---- a/libselinux/src/setfilecon.c -+++ b/libselinux/src/setfilecon.c -@@ -9,8 +9,20 @@ - - int setfilecon_raw(const char *path, const security_context_t context) - { -- return setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, -+ int rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1, - 0); -+ if (rc < 0 && errno == ENOTSUP) { -+ security_context_t ccontext = NULL; -+ int err = errno; -+ if ((getfilecon_raw(path, &ccontext) >= 0) && -+ (strcmp(context,ccontext) == 0)) { -+ rc = 0; -+ } else { -+ errno = err; -+ } -+ freecon(ccontext); ++func Test() { ++ var plabel,flabel string ++ if ! Selinux_enabled() { ++ return + } -+ return rc; - } - - hidden_def(setfilecon_raw) -diff --git a/libselinux/src/setrans_client.c b/libselinux/src/setrans_client.c -index f9065bd..4ab7c2a 100644 ---- a/libselinux/src/setrans_client.c -+++ b/libselinux/src/setrans_client.c -@@ -249,12 +249,12 @@ out: ++ ++ 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(Selinux_getenforce()) ++ fmt.Println(Selinux_getenforcemode()) ++ flabel,_ = Matchpathcon("/home/dwalsh/.emacs", 0) ++ fmt.Println(flabel) ++} +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) $@ - static void setrans_thread_destructor(void __attribute__((unused)) *unused) - { -- free(prev_t2r_trans); -- free(prev_t2r_raw); -- free(prev_r2t_trans); -- free(prev_r2t_raw); -- free(prev_r2c_trans); -- free(prev_r2c_raw); -+ free(prev_t2r_trans); prev_t2r_trans = NULL; -+ free(prev_t2r_raw); prev_t2r_raw = NULL; -+ free(prev_r2t_trans); prev_r2t_trans = NULL; -+ free(prev_r2t_raw); prev_r2t_raw = NULL; -+ free(prev_r2c_trans); prev_r2c_trans = NULL; -+ free(prev_r2c_raw); prev_r2c_raw = NULL; - } + $(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) - void __attribute__((destructor)) setrans_lib_destructor(void); -@@ -267,6 +267,7 @@ void hidden __attribute__((destructor)) setrans_lib_destructor(void) + $(LIBPC): $(LIBPC).in ../VERSION +diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c +index e419f1a..fdeca93 100644 +--- a/libselinux/src/load_policy.c ++++ b/libselinux/src/load_policy.c +@@ -16,6 +16,82 @@ + #include + #include "policy.h" + #include ++#include ++ ++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; ++} - static inline void init_thread_destructor(void) + int security_load_policy(void *data, size_t len) { -+ setrans_thread_destructor(NULL); - if (destructor_initialized == 0) { - __selinux_setspecific(destructor_key, (void *)1); - destructor_initialized = 1; -diff --git a/libselinux/src/setrans_internal.h b/libselinux/src/setrans_internal.h -index a801ee8..b3bdca2 100644 ---- a/libselinux/src/setrans_internal.h -+++ b/libselinux/src/setrans_internal.h -@@ -1,6 +1,7 @@ - /* Author: Trusted Computer Solutions, Inc. */ -+#include - --#define SETRANS_UNIX_SOCKET "/var/run/setrans/.setrans-unix" -+#define SETRANS_UNIX_SOCKET SELINUX_TRANS_DIR "/.setrans-unix" - - #define RAW_TO_TRANS_CONTEXT 2 - #define TRANS_TO_RAW_CONTEXT 3 -diff --git a/libselinux/utils/matchpathcon.c b/libselinux/utils/matchpathcon.c -index dd5aaa3..9d3ff3a 100644 ---- a/libselinux/utils/matchpathcon.c -+++ b/libselinux/utils/matchpathcon.c -@@ -12,11 +12,10 @@ - #include - #include +@@ -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; +- } - - static void usage(const char *progname) - { - fprintf(stderr, -- "usage: %s [-N] [-n] [-f file_contexts] [-p prefix] [-Vq] path...\n", -+ "usage: %s [-N] [-n] [-f file_contexts] [ -P policy_root_path ] [-p prefix] [-Vq] path...\n", - progname); - exit(1); - } -@@ -78,7 +77,7 @@ int main(int argc, char **argv) - if (argc < 2) - usage(argv[0]); +- 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; ++ } + } -- while ((opt = getopt(argc, argv, "m:Nnf:p:Vq")) > 0) { -+ while ((opt = getopt(argc, argv, "m:Nnf:P:p:Vq")) > 0) { - switch (opt) { - case 'n': - header = 0; -@@ -113,6 +112,15 @@ int main(int argc, char **argv) - exit(1); - } - break; -+ case 'P': -+ if (selinux_set_policy_root(optarg) < 0 ) { -+ fprintf(stderr, -+ "Error setting policy root %s: %s\n", -+ optarg, -+ errno ? strerror(errno) : "invalid"); -+ exit(1); -+ } -+ break; - case 'p': - if (init) { - fprintf(stderr, -diff --git a/libselinux/utils/sefcontext_compile.c b/libselinux/utils/sefcontext_compile.c -index 6f79dd6..e019a07 100644 ---- a/libselinux/utils/sefcontext_compile.c -+++ b/libselinux/utils/sefcontext_compile.c -@@ -145,7 +145,7 @@ static int process_file(struct saved_data *data, const char *filename) - * u32 - data length of the pcre regex study daya - * char - a buffer holding the raw pcre regex study data - */ --static int write_binary_file(struct saved_data *data, char *filename) -+static int write_binary_file(struct saved_data *data, int fd) - { - struct spec *specs = data->spec_arr; - FILE *bin_file; -@@ -155,7 +155,7 @@ static int write_binary_file(struct saved_data *data, char *filename) - uint32_t i; - int rc; + 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 + } -- bin_file = fopen(filename, "w"); -+ bin_file = fdopen(fd, "w"); - if (!bin_file) { - perror("fopen output_file"); - exit(EXIT_FAILURE); -@@ -321,7 +321,9 @@ int main(int argc, char *argv[]) - const char *path; - char stack_path[PATH_MAX + 1]; - int rc; - -+ char *tmp= NULL; -+ int fd; + - if (argc != 2) { - fprintf(stderr, "usage: %s input_file\n", argv[0]); - exit(EXIT_FAILURE); -@@ -342,13 +344,29 @@ int main(int argc, char *argv[]) - rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path); - if (rc < 0 || rc >= sizeof(stack_path)) - return rc; -- rc = write_binary_file(&data, stack_path); -+ -+ if (asprintf(&tmp, "%sXXXXXX", stack_path) < 0) -+ return -1; -+ -+ fd = mkstemp(tmp); -+ if (fd < 0) -+ goto err; -+ -+ rc = write_binary_file(&data, fd); -+ - if (rc < 0) -- return rc; -+ goto err; - -+ rename(tmp, stack_path); - rc = free_specs(&data); - if (rc < 0) -- return rc; -+ goto err; - -- return 0; -+ rc = 0; -+out: -+ free(tmp); -+ return rc; -+err: -+ rc = -1; -+ goto out; + 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: +@@ -410,7 +494,7 @@ int selinux_init_load_policy(int *enforce) + * already mounted and selinuxmnt set above. + */ + +- if (seconfig == -1) { ++ if (*enforce == -1) { + /* Runtime disable of SELinux. */ + rc = security_disable(); + if (rc == 0) { +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 + #include + #include ++#include + #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); } +