Cleanup setfcontext_compile atomic patch

- Add matchpathcon -P /etc/selinux/mls support by allowing users to set alternate root
- Make sure we set exit codes from selinux_label calls to ENOENT or SUCCESS
This commit is contained in:
Dan Walsh 2013-03-08 12:23:30 -05:00
parent 8047eef070
commit cc9c7ddcf7
2 changed files with 265 additions and 43 deletions

View File

@ -1,5 +1,5 @@
diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
index a4079aa..80ba628 100644
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);
@ -10,8 +10,16 @@ index a4079aa..80ba628 100644
/* Compute an access decision. */
extern int security_compute_av(const security_context_t scon,
@@ -498,6 +499,7 @@ extern const char *selinux_policy_root(void);
@@ -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);
@ -72,6 +80,77 @@ index 0000000..175a611
+++ 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/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/selinux.8 b/libselinux/man/man8/selinux.8
index a328866..50868e4 100644
--- a/libselinux/man/man8/selinux.8
@ -389,6 +468,27 @@ index b9e8002..355730a 100644
}
hidden_def(get_ordered_context_list)
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/matchpathcon.c b/libselinux/src/matchpathcon.c
index 2d7369e..2a00807 100644
--- a/libselinux/src/matchpathcon.c
@ -423,18 +523,71 @@ index 6c5b45a..0a0dd3e 100644
return 0;
}
diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c
index 296f357..4913c55 100644
index 296f357..0040524 100644
--- a/libselinux/src/selinux_config.c
+++ b/libselinux/src/selinux_config.c
@@ -8,6 +8,7 @@
@@ -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"
@@ -303,6 +304,29 @@ const char *selinux_binary_policy_path(void)
@@ -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 = strchr(selinux_policyroot, '/');
+ 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)
@ -444,18 +597,20 @@ index 296f357..4913c55 100644
+ int vers = 0;
+ static char policy_path[PATH_MAX];
+
+ snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt);
+ if (access(policy_path, F_OK) != 0 ) {
+ 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;
+ 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;
+}
+
@ -489,50 +644,112 @@ index a801ee8..b3bdca2 100644
#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..eb88ea8 100644
index 6f79dd6..e019a07 100644
--- a/libselinux/utils/sefcontext_compile.c
+++ b/libselinux/utils/sefcontext_compile.c
@@ -6,6 +6,7 @@
#include <string.h>
@@ -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;
#include <linux/limits.h>
+#include <libgen.h>
#include "../src/label_file.h"
@@ -321,7 +322,8 @@ int main(int argc, char *argv[])
- 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, *tmppath;
+ char *tmp= NULL;
+ int fd;
+
if (argc != 2) {
fprintf(stderr, "usage: %s input_file\n", argv[0]);
exit(EXIT_FAILURE);
@@ -342,10 +344,21 @@ int main(int argc, char *argv[])
@@ -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 (rc < 0)
+
+ 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;
+ tmppath = strdup(stack_path);
+ if (!tmppath)
+ return -1;
+ tmp = tempnam(dirname(tmppath), ".bin");
+ free(tmppath);
+ if (!tmp)
+ return -1;
+ rc = write_binary_file(&data, tmp);
+ if (rc < 0) {
+ free(tmp);
+ return rc;
+ }
+ rename(tmp, stack_path);
+ free(tmp);
rc = free_specs(&data);
if (rc < 0)
return rc;
- return rc;
+ goto err;
- return 0;
+ rc = 0;
+out:
+ free(tmp);
+ return rc;
+err:
+ rc = -1;
+ goto out;
}

View File

@ -10,7 +10,7 @@
Summary: SELinux library and simple utilities
Name: libselinux
Version: 2.1.13
Release: 8%{?dist}
Release: 9%{?dist}
License: Public Domain
Group: System Environment/Libraries
Source: %{name}-%{version}.tgz
@ -241,6 +241,11 @@ rm -rf %{buildroot}
%{ruby_sitearch}/selinux.so
%changelog
* Wed Mar 6 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.13-9
- Cleanup setfcontext_compile atomic patch
- Add matchpathcon -P /etc/selinux/mls support by allowing users to set alternate root
- Make sure we set exit codes from selinux_label calls to ENOENT or SUCCESS
* Wed Mar 6 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.13-8
- Make setfcontext_compile atomic