0695b75fac
Resolves #1013801
1335 lines
40 KiB
Diff
1335 lines
40 KiB
Diff
diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
|
|
index a4079aa..0b122af 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);
|
|
|
|
+/*
|
|
+ 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);
|
|
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 <guido@trentalancia.com>
|
|
.
|
|
.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 <guido@trentalancia.com>
|
|
.
|
|
.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
|
|
new file mode 100644
|
|
index 0000000..175a611
|
|
--- /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 <selinux/selinux.h>
|
|
.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
|
|
+
|
|
+.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.
|
|
+
|
|
+On success, selinux_set_policy_root returns 0 on success -1 on failure.
|
|
+
|
|
.
|
|
.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, <dwalsh@redhat.com>
|
|
+.
|
|
+.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.
|
|
+
|
|
+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 <dwalsh@redhat.com>.
|
|
.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)
|
|
- }
|
|
+
|
|
rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
|
|
- if (rc < 0) {
|
|
+ if (rc < 0)
|
|
RETURN(BADTCON)
|
|
- }
|
|
+
|
|
tclass = string_to_security_class(tclassstr);
|
|
- if (!tclass) {
|
|
+ if (!tclass)
|
|
RETURN(BADTCLASS)
|
|
- }
|
|
+
|
|
/* 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)
|
|
- }
|
|
+
|
|
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)
|
|
- }
|
|
+
|
|
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/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);
|
|
+ }
|
|
+ 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..f5cb52a 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;
|
|
}
|
|
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
|
|
index 5f697f3..9b0d6b0 100644
|
|
--- a/libselinux/src/label_file.c
|
|
+++ b/libselinux/src/label_file.c
|
|
@@ -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/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);
|
|
+ }
|
|
+ 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 <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/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 *);
|
|
+
|
|
+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);
|
|
+}
|
|
+
|
|
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..9aee32f 100644
|
|
--- a/libselinux/src/selinux_config.c
|
|
+++ b/libselinux/src/selinux_config.c
|
|
@@ -8,6 +8,8 @@
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
+#include <errno.h>
|
|
+#include "policy.h"
|
|
#include "selinux_internal.h"
|
|
#include "get_default_type_internal.h"
|
|
|
|
@@ -138,6 +140,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;
|
|
+}
|
|
+
|
|
static char *selinux_policyroot = NULL;
|
|
static const char *selinux_rootpath = SELINUXDIR;
|
|
|
|
@@ -261,6 +270,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;
|
|
+ }
|
|
+ policy_type++;
|
|
+
|
|
+ fini_selinuxmnt();
|
|
+ fini_selinux_policyroot();
|
|
+
|
|
+ selinux_policyroot = strdup(path);
|
|
+ if (! selinux_policyroot)
|
|
+ return -1;
|
|
+
|
|
+ if (setpolicytype(policy_type) != 0)
|
|
+ return -1;
|
|
+
|
|
+ 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;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
const char *selinux_path(void)
|
|
{
|
|
return selinux_rootpath;
|
|
@@ -303,6 +343,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];
|
|
+
|
|
+ if (selinux_mnt) {
|
|
+ snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt);
|
|
+ if (access(policy_path, F_OK) == 0 ) {
|
|
+ return policy_path;
|
|
+ }
|
|
+ }
|
|
+ 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;
|
|
+}
|
|
+
|
|
+hidden_def(selinux_current_policy_path)
|
|
+
|
|
const char *selinux_file_context_path(void)
|
|
{
|
|
return get_path(FILE_CONTEXTS);
|
|
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
|
|
index 2c7c85c..4a4aebc 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)
|
|
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
|
|
+
|
|
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;
|
|
+}
|
|
+
|
|
/* 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);
|
|
+ }
|
|
+ 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:
|
|
|
|
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;
|
|
}
|
|
|
|
void __attribute__((destructor)) setrans_lib_destructor(void);
|
|
@@ -267,6 +267,7 @@ void hidden __attribute__((destructor)) setrans_lib_destructor(void)
|
|
|
|
static inline void init_thread_destructor(void)
|
|
{
|
|
+ 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 <selinux/selinux.h>
|
|
|
|
-#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 <limits.h>
|
|
#include <stdlib.h>
|
|
|
|
-
|
|
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]);
|
|
|
|
- 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;
|
|
|
|
- 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;
|
|
}
|