2442 lines
80 KiB
Diff
2442 lines
80 KiB
Diff
diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c
|
||
index ffe381b..2d68482 100644
|
||
--- a/libselinux/src/audit2why.c
|
||
+++ b/libselinux/src/audit2why.c
|
||
@@ -310,10 +310,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 +330,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 +340,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 +374,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 +400,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/get_context_list.c b/libselinux/src/get_context_list.c
|
||
index b9e8002..355730a 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) {
|
||
@@ -465,31 +465,28 @@ int get_ordered_context_list(const char *user,
|
||
}
|
||
}
|
||
|
||
+ 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 +520,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/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/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
|
||
index c27275e..0165eed 100644
|
||
--- a/libsepol/include/sepol/policydb/policydb.h
|
||
+++ b/libsepol/include/sepol/policydb/policydb.h
|
||
@@ -683,10 +683,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
|
||
#define POLICYDB_VERSION_ROLETRANS 26
|
||
#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
|
||
#define POLICYDB_VERSION_DEFAULT_TYPE 28
|
||
+#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
|
||
|
||
/* Range of policy versions we understand*/
|
||
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
|
||
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE
|
||
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES
|
||
|
||
/* Module versions and specific changes*/
|
||
#define MOD_POLICYDB_VERSION_BASE 4
|
||
@@ -704,9 +705,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
|
||
#define MOD_POLICYDB_VERSION_TUNABLE_SEP 14
|
||
#define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 15
|
||
#define MOD_POLICYDB_VERSION_DEFAULT_TYPE 16
|
||
+#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES 17
|
||
|
||
#define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
|
||
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_DEFAULT_TYPE
|
||
+#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_CONSTRAINT_NAMES
|
||
|
||
#define POLICYDB_CONFIG_MLS 1
|
||
|
||
diff --git a/libsepol/include/sepol/policydb/services.h b/libsepol/include/sepol/policydb/services.h
|
||
index aef0c7b..1969a10 100644
|
||
--- a/libsepol/include/sepol/policydb/services.h
|
||
+++ b/libsepol/include/sepol/policydb/services.h
|
||
@@ -58,6 +58,38 @@ extern int sepol_compute_av_reason(sepol_security_id_t ssid,
|
||
struct sepol_av_decision *avd,
|
||
unsigned int *reason);
|
||
|
||
+/*
|
||
+ * Same as above, but also returns the constraint expression calculations
|
||
+ * whether allowed or denied in a buffer. This buffer is allocated by
|
||
+ * this call and must be free'd by the caller using free(3). The contraint
|
||
+ * buffer will contain any constraints in infix notation.
|
||
+ * If the SHOW_GRANTED flag is set it will show granted and denied
|
||
+ * constraints. The default is to show only denied constraints.
|
||
+ */
|
||
+#define SHOW_GRANTED 1
|
||
+extern int sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
|
||
+ sepol_security_id_t tsid,
|
||
+ sepol_security_class_t tclass,
|
||
+ sepol_access_vector_t requested,
|
||
+ struct sepol_av_decision *avd,
|
||
+ unsigned int *reason,
|
||
+ char **reason_buf,
|
||
+ unsigned int flags);
|
||
+/*
|
||
+ * Return a class ID associated with the class string representation
|
||
+ * specified by `class_name'.
|
||
+ */
|
||
+extern int sepol_class_name_to_id(const char *class_name,
|
||
+ sepol_security_class_t *tclass);
|
||
+
|
||
+/*
|
||
+ * Return a permission av bit associated with tclass and the string
|
||
+ * representation of the `perm_name'.
|
||
+ */
|
||
+extern int sepol_perm_name_to_av(sepol_security_class_t tclass,
|
||
+ const char *perm_name,
|
||
+ sepol_access_vector_t *av);
|
||
+
|
||
/*
|
||
* Compute a SID to use for labeling a new object in the
|
||
* class `tclass' based on a SID pair.
|
||
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||
index f0555bb..6fd992f 100644
|
||
--- a/libsepol/src/expand.c
|
||
+++ b/libsepol/src/expand.c
|
||
@@ -384,6 +384,17 @@ static int constraint_node_clone(constraint_node_t ** dst,
|
||
new_expr->op = expr->op;
|
||
if (new_expr->expr_type == CEXPR_NAMES) {
|
||
if (new_expr->attr & CEXPR_TYPE) {
|
||
+ /*
|
||
+ * Copy over constraint policy source types and/or
|
||
+ * attributes for sepol_compute_av_reason_buffer(3) so that
|
||
+ * utilities can analyse constraint errors.
|
||
+ */
|
||
+ if (map_ebitmap(&expr->type_names->types,
|
||
+ &new_expr->type_names->types,
|
||
+ state->typemap)) {
|
||
+ ERR(NULL, "Failed to map type_names->types");
|
||
+ goto out_of_mem;
|
||
+ }
|
||
/* Type sets require expansion and conversion. */
|
||
if (expand_convert_type_set(state->out,
|
||
state->
|
||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||
index 1f49261..8c7efbc 100644
|
||
--- a/libsepol/src/policydb.c
|
||
+++ b/libsepol/src/policydb.c
|
||
@@ -165,6 +165,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||
.target_platform = SEPOL_TARGET_SELINUX,
|
||
},
|
||
{
|
||
+ .type = POLICY_KERN,
|
||
+ .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
|
||
+ .sym_num = SYM_NUM,
|
||
+ .ocon_num = OCON_NODE6 + 1,
|
||
+ .target_platform = SEPOL_TARGET_SELINUX,
|
||
+ },
|
||
+ {
|
||
.type = POLICY_BASE,
|
||
.version = MOD_POLICYDB_VERSION_BASE,
|
||
.sym_num = SYM_NUM,
|
||
@@ -256,6 +263,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||
.target_platform = SEPOL_TARGET_SELINUX,
|
||
},
|
||
{
|
||
+ .type = POLICY_BASE,
|
||
+ .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
|
||
+ .sym_num = SYM_NUM,
|
||
+ .ocon_num = OCON_NODE6 + 1,
|
||
+ .target_platform = SEPOL_TARGET_SELINUX,
|
||
+ },
|
||
+ {
|
||
.type = POLICY_MOD,
|
||
.version = MOD_POLICYDB_VERSION_BASE,
|
||
.sym_num = SYM_NUM,
|
||
@@ -346,6 +360,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||
.ocon_num = 0,
|
||
.target_platform = SEPOL_TARGET_SELINUX,
|
||
},
|
||
+ {
|
||
+ .type = POLICY_MOD,
|
||
+ .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
|
||
+ .sym_num = SYM_NUM,
|
||
+ .ocon_num = 0,
|
||
+ .target_platform = SEPOL_TARGET_SELINUX,
|
||
+ },
|
||
};
|
||
|
||
#if 0
|
||
@@ -2019,6 +2040,10 @@ static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
|
||
if (p->policy_type != POLICY_KERN &&
|
||
type_set_read(e->type_names, fp))
|
||
return -1;
|
||
+ else if (p->policy_type == POLICY_KERN &&
|
||
+ p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
|
||
+ type_set_read(e->type_names, fp))
|
||
+ return -1;
|
||
break;
|
||
default:
|
||
return -1;
|
||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||
index 7fac4a0..43ec07e 100644
|
||
--- a/libsepol/src/services.c
|
||
+++ b/libsepol/src/services.c
|
||
@@ -43,6 +43,11 @@
|
||
* Implementation of the security services.
|
||
*/
|
||
|
||
+/* The initial sizes malloc'd for sepol_compute_av_reason_buffer() support */
|
||
+#define REASON_BUF_SIZE 2048
|
||
+#define EXPR_BUF_SIZE 1024
|
||
+#define STACK_LEN 32
|
||
+
|
||
#include <stdlib.h>
|
||
#include <sys/types.h>
|
||
#include <sys/socket.h>
|
||
@@ -54,6 +59,7 @@
|
||
#include <sepol/policydb/services.h>
|
||
#include <sepol/policydb/conditional.h>
|
||
#include <sepol/policydb/flask.h>
|
||
+#include <sepol/policydb/util.h>
|
||
|
||
#include "debug.h"
|
||
#include "private.h"
|
||
@@ -70,6 +76,50 @@ static int selinux_enforcing = 1;
|
||
static sidtab_t mysidtab, *sidtab = &mysidtab;
|
||
static policydb_t mypolicydb, *policydb = &mypolicydb;
|
||
|
||
+/* Used by sepol_compute_av_reason_buffer() to keep track of entries */
|
||
+static int reason_buf_used;
|
||
+static int reason_buf_len;
|
||
+
|
||
+/* Stack services for RPN to infix conversion. */
|
||
+static char **stack;
|
||
+static int stack_len;
|
||
+static int next_stack_entry;
|
||
+
|
||
+static void push(char * expr_ptr)
|
||
+{
|
||
+ if (next_stack_entry >= stack_len) {
|
||
+ char **new_stack = stack;
|
||
+ int new_stack_len;
|
||
+
|
||
+ if (stack_len == 0)
|
||
+ new_stack_len = STACK_LEN;
|
||
+ else
|
||
+ new_stack_len = stack_len * 2;
|
||
+
|
||
+ new_stack = realloc(stack, new_stack_len * sizeof(*stack));
|
||
+ if (!new_stack) {
|
||
+ ERR(NULL, "unable to allocate stack space");
|
||
+ return;
|
||
+ }
|
||
+ stack_len = new_stack_len;
|
||
+ stack = new_stack;
|
||
+ }
|
||
+ stack[next_stack_entry] = expr_ptr;
|
||
+ next_stack_entry++;
|
||
+}
|
||
+
|
||
+static char *pop(void)
|
||
+{
|
||
+ next_stack_entry--;
|
||
+ if (next_stack_entry < 0) {
|
||
+ next_stack_entry = 0;
|
||
+ ERR(NULL, "pop called with no stack entries");
|
||
+ return NULL;
|
||
+ }
|
||
+ return stack[next_stack_entry];
|
||
+}
|
||
+/* End Stack services */
|
||
+
|
||
int hidden sepol_set_sidtab(sidtab_t * s)
|
||
{
|
||
sidtab = s;
|
||
@@ -113,20 +163,195 @@ int sepol_set_policydb_from_file(FILE * fp)
|
||
static uint32_t latest_granting = 0;
|
||
|
||
/*
|
||
- * Return the boolean value of a constraint expression
|
||
- * when it is applied to the specified source and target
|
||
+ * cat_expr_buf adds a string to an expression buffer and handles realloc's if
|
||
+ * buffer is too small. The array of expression text buffer pointers and its
|
||
+ * counter are globally defined here as constraint_expr_eval_reason() sets
|
||
+ * them up and cat_expr_buf updates the e_buf pointer if the buffer is realloc'ed.
|
||
+ */
|
||
+static int expr_counter;
|
||
+static char **expr_list;
|
||
+static int expr_buf_used;
|
||
+static int expr_buf_len;
|
||
+
|
||
+static void cat_expr_buf(char *e_buf, char *string)
|
||
+{
|
||
+ int len, new_buf_len;
|
||
+ char *p, *new_buf = e_buf;
|
||
+
|
||
+ while (1) {
|
||
+ p = e_buf + expr_buf_used;
|
||
+ len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string);
|
||
+ if (len < 0 || len >= expr_buf_len - expr_buf_used) {
|
||
+ new_buf_len = expr_buf_len + EXPR_BUF_SIZE;
|
||
+ new_buf = realloc(e_buf, new_buf_len);
|
||
+ if (!new_buf) {
|
||
+ ERR(NULL, "failed to realloc expr buffer");
|
||
+ return;
|
||
+ }
|
||
+ /* Update the new ptr in the expr list and locally + new len */
|
||
+ expr_list[expr_counter] = new_buf;
|
||
+ e_buf = new_buf;
|
||
+ expr_buf_len = new_buf_len;
|
||
+ } else {
|
||
+ expr_buf_used += len;
|
||
+ return;
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+/*
|
||
+ * If the POLICY_KERN version is < POLICYDB_VERSION_CONSTRAINT_NAMES,
|
||
+ * then just return.
|
||
+ *
|
||
+ * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES,
|
||
+ * then for 'types' only, read the types_names->types list as it will
|
||
+ * contain a list of types and attributes that were defined in the
|
||
+ * policy source.
|
||
+ */
|
||
+static void get_names_list(constraint_expr_t *e, int type)
|
||
+{
|
||
+ ebitmap_t *types;
|
||
+ types = &e->type_names->types;
|
||
+ int rc = 0;
|
||
+ unsigned int i;
|
||
+ char tmp_buf[128];
|
||
+ /* if -type_names->types is 0, then output string <empty_set> */
|
||
+ int empty_set = 0;
|
||
+
|
||
+ if (policydb->policy_type == POLICY_KERN &&
|
||
+ policydb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
|
||
+ type == CEXPR_TYPE) {
|
||
+ /*
|
||
+ * Process >= POLICYDB_VERSION_CONSTRAINT_NAMES with CEXPR_TYPE, then
|
||
+ * obtain the list of names defined in the policy source.
|
||
+ */
|
||
+ cat_expr_buf(expr_list[expr_counter], "{ POLICY_SOURCE: ");
|
||
+ for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
|
||
+ if ((rc = ebitmap_get_bit(types, i)) == 0)
|
||
+ continue;
|
||
+ /* Collect entries */
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "%s ", policydb->p_type_val_to_name[i]);
|
||
+ cat_expr_buf(expr_list[expr_counter], tmp_buf);
|
||
+ empty_set++;
|
||
+ }
|
||
+ if (empty_set == 0)
|
||
+ cat_expr_buf(expr_list[expr_counter], "<empty_set> ");
|
||
+ cat_expr_buf(expr_list[expr_counter], "} ");
|
||
+ }
|
||
+ return;
|
||
+}
|
||
+
|
||
+static void msgcat(char *src, char *tgt, char *rel, int failed)
|
||
+{
|
||
+ char tmp_buf[1024];
|
||
+ if (failed)
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ",
|
||
+ src, rel, tgt);
|
||
+ else
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Pass-) ",
|
||
+ src, rel, tgt);
|
||
+ cat_expr_buf(expr_list[expr_counter], tmp_buf);
|
||
+}
|
||
+
|
||
+/* Returns a buffer with class, statement type and permissions */
|
||
+static char *get_class_info(sepol_security_class_t tclass,
|
||
+ constraint_node_t *constraint,
|
||
+ context_struct_t * xcontext)
|
||
+{
|
||
+ constraint_expr_t *e;
|
||
+ int mls, state_num;
|
||
+
|
||
+ /* Find if MLS statement or not */
|
||
+ mls = 0;
|
||
+ for (e = constraint->expr; e; e = e->next) {
|
||
+ if (e->attr >= CEXPR_L1L2) {
|
||
+ mls = 1;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /* Determine statement type */
|
||
+ char *statements[] = {
|
||
+ "constrain ", /* 0 */
|
||
+ "mlsconstrain ", /* 1 */
|
||
+ "validatetrans ", /* 2 */
|
||
+ "mlsvalidatetrans ", /* 3 */
|
||
+ 0 };
|
||
+
|
||
+ if (xcontext == NULL)
|
||
+ state_num = mls + 0;
|
||
+ else
|
||
+ state_num = mls + 2;
|
||
+
|
||
+ int class_buf_len = 0;
|
||
+ int new_class_buf_len;
|
||
+ int len, buf_used;
|
||
+ char *class_buf = NULL, *p;
|
||
+ char *new_class_buf = NULL;
|
||
+
|
||
+ while (1) {
|
||
+ new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
|
||
+ new_class_buf = realloc(class_buf, new_class_buf_len);
|
||
+ if (!new_class_buf)
|
||
+ return NULL;
|
||
+ class_buf_len = new_class_buf_len;
|
||
+ class_buf = new_class_buf;
|
||
+ buf_used = 0;
|
||
+ p = class_buf;
|
||
+
|
||
+ /* Add statement type */
|
||
+ len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]);
|
||
+ if (len < 0 || len >= class_buf_len - buf_used)
|
||
+ continue;
|
||
+
|
||
+ /* Add class entry */
|
||
+ p += len;
|
||
+ buf_used += len;
|
||
+ len = snprintf(p, class_buf_len - buf_used, "%s ",
|
||
+ policydb->p_class_val_to_name[tclass - 1]);
|
||
+ if (len < 0 || len >= class_buf_len - buf_used)
|
||
+ continue;
|
||
+
|
||
+ /* Add permission entries */
|
||
+ p += len;
|
||
+ buf_used += len;
|
||
+ len = snprintf(p, class_buf_len - buf_used, "{%s } (",
|
||
+ sepol_av_to_string(policydb, tclass, constraint->permissions));
|
||
+ if (len < 0 || len >= class_buf_len - buf_used)
|
||
+ continue;
|
||
+ break;
|
||
+ }
|
||
+ return class_buf;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Modified version of constraint_expr_eval that will process each
|
||
+ * constraint as before but adds the information to text buffers that
|
||
+ * will hold various components. The expression will be in RPN format,
|
||
+ * therefore there is a stack based RPN to infix converter to produce
|
||
+ * the final readable constraint.
|
||
+ *
|
||
+ * Return the boolean value of a constraint expression
|
||
+ * when it is applied to the specified source and target
|
||
* security contexts.
|
||
*
|
||
* xcontext is a special beast... It is used by the validatetrans rules
|
||
* only. For these rules, scontext is the context before the transition,
|
||
* tcontext is the context after the transition, and xcontext is the context
|
||
* of the process performing the transition. All other callers of
|
||
- * constraint_expr_eval should pass in NULL for xcontext.
|
||
+ * constraint_expr_eval_reason should pass in NULL for xcontext.
|
||
+ *
|
||
+ * This function will also build a buffer as the constraint is processed
|
||
+ * for analysis. If this option is not required, then:
|
||
+ * 'tclass' should be '0' and r_buf MUST be NULL.
|
||
*/
|
||
-static int constraint_expr_eval(context_struct_t * scontext,
|
||
+static int constraint_expr_eval_reason(context_struct_t * scontext,
|
||
context_struct_t * tcontext,
|
||
context_struct_t * xcontext,
|
||
- constraint_expr_t * cexpr)
|
||
+ sepol_security_class_t tclass,
|
||
+ constraint_node_t *constraint,
|
||
+ char **r_buf,
|
||
+ unsigned int flags)
|
||
{
|
||
uint32_t val1, val2;
|
||
context_struct_t *c;
|
||
@@ -136,56 +361,137 @@ static int constraint_expr_eval(context_struct_t * scontext,
|
||
int s[CEXPR_MAXDEPTH];
|
||
int sp = -1;
|
||
|
||
- for (e = cexpr; e; e = e->next) {
|
||
+ char tmp_buf[128];
|
||
+
|
||
+/*
|
||
+ * Define the s_t_x_num values that make up r1, t2 etc. in text strings
|
||
+ * Set 1 = source, 2 = target, 3 = xcontext for validatetrans
|
||
+ */
|
||
+#define SOURCE 1
|
||
+#define TARGET 2
|
||
+#define XTARGET 3
|
||
+
|
||
+ int s_t_x_num = SOURCE;
|
||
+
|
||
+ /* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */
|
||
+ int u_r_t = 0;
|
||
+
|
||
+ char *name1, *name2;
|
||
+ char *src = NULL;
|
||
+ char *tgt = NULL;
|
||
+
|
||
+ int rc = 0, x;
|
||
+
|
||
+ char *class_buf = NULL;
|
||
+
|
||
+ class_buf = get_class_info(tclass, constraint, xcontext);
|
||
+ if (!class_buf) {
|
||
+ ERR(NULL, "failed to allocate class buffer");
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+
|
||
+ /* Original function but with buffer support */
|
||
+ int expr_list_len = 0;
|
||
+ expr_counter = 0;
|
||
+ expr_list = NULL;
|
||
+ for (e = constraint->expr; e; e = e->next) {
|
||
+ /* Allocate a stack to hold expression buffer entries */
|
||
+ if (expr_counter >= expr_list_len) {
|
||
+ char **new_expr_list = expr_list;
|
||
+ int new_expr_list_len;
|
||
+
|
||
+ if (expr_list_len == 0)
|
||
+ new_expr_list_len = STACK_LEN;
|
||
+ else
|
||
+ new_expr_list_len = expr_list_len * 2;
|
||
+
|
||
+ new_expr_list = realloc(expr_list, new_expr_list_len * sizeof(*expr_list));
|
||
+ if (!new_expr_list) {
|
||
+ ERR(NULL, "failed to allocate expr buffer stack");
|
||
+ rc = -ENOMEM;
|
||
+ goto out;
|
||
+ }
|
||
+ expr_list_len = new_expr_list_len;
|
||
+ expr_list = new_expr_list;
|
||
+ }
|
||
+
|
||
+ /*
|
||
+ * malloc a buffer to store each expression text component. If the
|
||
+ * buffer is too small cat_expr_buf() will realloc extra space.
|
||
+ */
|
||
+ expr_buf_len = EXPR_BUF_SIZE;
|
||
+ expr_list[expr_counter] = malloc(expr_buf_len);
|
||
+ if (!expr_list[expr_counter]) {
|
||
+ ERR(NULL, "failed to allocate expr buffer");
|
||
+ rc = -ENOMEM;
|
||
+ goto out;
|
||
+ }
|
||
+ expr_buf_used = 0;
|
||
+
|
||
+ /* Now process each expression of the constraint */
|
||
switch (e->expr_type) {
|
||
case CEXPR_NOT:
|
||
BUG_ON(sp < 0);
|
||
s[sp] = !s[sp];
|
||
+ cat_expr_buf(expr_list[expr_counter], "not");
|
||
break;
|
||
case CEXPR_AND:
|
||
BUG_ON(sp < 1);
|
||
sp--;
|
||
s[sp] &= s[sp + 1];
|
||
+ cat_expr_buf(expr_list[expr_counter], "and");
|
||
break;
|
||
case CEXPR_OR:
|
||
BUG_ON(sp < 1);
|
||
sp--;
|
||
s[sp] |= s[sp + 1];
|
||
+ cat_expr_buf(expr_list[expr_counter], "or");
|
||
break;
|
||
case CEXPR_ATTR:
|
||
if (sp == (CEXPR_MAXDEPTH - 1))
|
||
- return 0;
|
||
+ goto out;
|
||
+
|
||
switch (e->attr) {
|
||
case CEXPR_USER:
|
||
val1 = scontext->user;
|
||
val2 = tcontext->user;
|
||
+ free(src); src = strdup("u1");
|
||
+ free(tgt); tgt = strdup("u2");
|
||
break;
|
||
case CEXPR_TYPE:
|
||
val1 = scontext->type;
|
||
val2 = tcontext->type;
|
||
+ free(src); src = strdup("t1");
|
||
+ free(tgt); tgt = strdup("t2");
|
||
break;
|
||
case CEXPR_ROLE:
|
||
val1 = scontext->role;
|
||
val2 = tcontext->role;
|
||
r1 = policydb->role_val_to_struct[val1 - 1];
|
||
r2 = policydb->role_val_to_struct[val2 - 1];
|
||
+ name1 = policydb->p_role_val_to_name[r1->s.value - 1];
|
||
+ name2 = policydb->p_role_val_to_name[r2->s.value - 1];
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "r1=%s", name1);
|
||
+ free(src); src = strdup(tmp_buf);
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "r2=%s ", name2);
|
||
+ free(tgt); tgt = strdup(tmp_buf);
|
||
+
|
||
switch (e->op) {
|
||
case CEXPR_DOM:
|
||
- s[++sp] =
|
||
- ebitmap_get_bit(&r1->dominates,
|
||
- val2 - 1);
|
||
+ s[++sp] = ebitmap_get_bit(&r1->dominates, val2 - 1);
|
||
+ msgcat(src, tgt, "dom", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_DOMBY:
|
||
- s[++sp] =
|
||
- ebitmap_get_bit(&r2->dominates,
|
||
- val1 - 1);
|
||
+ s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1);
|
||
+ msgcat(src, tgt, "domby", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_INCOMP:
|
||
- s[++sp] =
|
||
- (!ebitmap_get_bit
|
||
- (&r1->dominates, val2 - 1)
|
||
- && !ebitmap_get_bit(&r2->dominates,
|
||
- val1 - 1));
|
||
+ s[++sp] = (!ebitmap_get_bit(&r1->dominates, val2 - 1)
|
||
+ && !ebitmap_get_bit(&r2->dominates, val1 - 1));
|
||
+ msgcat(src, tgt, "incomp", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
default:
|
||
break;
|
||
@@ -194,110 +500,327 @@ static int constraint_expr_eval(context_struct_t * scontext,
|
||
case CEXPR_L1L2:
|
||
l1 = &(scontext->range.level[0]);
|
||
l2 = &(tcontext->range.level[0]);
|
||
+ free(src); src = strdup("l1");
|
||
+ free(tgt); tgt = strdup("l2");
|
||
goto mls_ops;
|
||
case CEXPR_L1H2:
|
||
l1 = &(scontext->range.level[0]);
|
||
l2 = &(tcontext->range.level[1]);
|
||
+ free(src); src = strdup("l1");
|
||
+ free(tgt); tgt = strdup("h2");
|
||
goto mls_ops;
|
||
case CEXPR_H1L2:
|
||
l1 = &(scontext->range.level[1]);
|
||
l2 = &(tcontext->range.level[0]);
|
||
+ free(src); src = strdup("h1");
|
||
+ free(tgt); tgt = strdup("L2");
|
||
goto mls_ops;
|
||
case CEXPR_H1H2:
|
||
l1 = &(scontext->range.level[1]);
|
||
l2 = &(tcontext->range.level[1]);
|
||
+ free(src); src = strdup("h1");
|
||
+ free(tgt); tgt = strdup("h2");
|
||
goto mls_ops;
|
||
case CEXPR_L1H1:
|
||
l1 = &(scontext->range.level[0]);
|
||
l2 = &(scontext->range.level[1]);
|
||
+ free(src); src = strdup("l1");
|
||
+ free(tgt); tgt = strdup("h1");
|
||
goto mls_ops;
|
||
case CEXPR_L2H2:
|
||
l1 = &(tcontext->range.level[0]);
|
||
l2 = &(tcontext->range.level[1]);
|
||
- goto mls_ops;
|
||
- mls_ops:
|
||
+ free(src); src = strdup("l2");
|
||
+ free(tgt); tgt = strdup("h2");
|
||
+ mls_ops:
|
||
switch (e->op) {
|
||
case CEXPR_EQ:
|
||
s[++sp] = mls_level_eq(l1, l2);
|
||
+ msgcat(src, tgt, "eq", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_NEQ:
|
||
s[++sp] = !mls_level_eq(l1, l2);
|
||
+ msgcat(src, tgt, "neq", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_DOM:
|
||
s[++sp] = mls_level_dom(l1, l2);
|
||
+ msgcat(src, tgt, "dom", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_DOMBY:
|
||
s[++sp] = mls_level_dom(l2, l1);
|
||
+ msgcat(src, tgt, "domby", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
case CEXPR_INCOMP:
|
||
s[++sp] = mls_level_incomp(l2, l1);
|
||
+ msgcat(src, tgt, "incomp", s[sp] == 0);
|
||
+ expr_counter++;
|
||
continue;
|
||
default:
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
break;
|
||
default:
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
|
||
switch (e->op) {
|
||
case CEXPR_EQ:
|
||
s[++sp] = (val1 == val2);
|
||
+ msgcat(src, tgt, "eq", s[sp] == 0);
|
||
break;
|
||
case CEXPR_NEQ:
|
||
s[++sp] = (val1 != val2);
|
||
+ msgcat(src, tgt, "neq", s[sp] == 0);
|
||
break;
|
||
default:
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
break;
|
||
case CEXPR_NAMES:
|
||
if (sp == (CEXPR_MAXDEPTH - 1))
|
||
- return 0;
|
||
+ goto out;
|
||
+ s_t_x_num = SOURCE;
|
||
c = scontext;
|
||
- if (e->attr & CEXPR_TARGET)
|
||
+ if (e->attr & CEXPR_TARGET) {
|
||
+ s_t_x_num = TARGET;
|
||
c = tcontext;
|
||
- else if (e->attr & CEXPR_XTARGET) {
|
||
+ } else if (e->attr & CEXPR_XTARGET) {
|
||
+ s_t_x_num = XTARGET;
|
||
c = xcontext;
|
||
- if (!c) {
|
||
- BUG();
|
||
- return 0;
|
||
- }
|
||
}
|
||
- if (e->attr & CEXPR_USER)
|
||
+ if (!c) {
|
||
+ BUG();
|
||
+ goto out;
|
||
+ }
|
||
+ if (e->attr & CEXPR_USER) {
|
||
+ u_r_t = CEXPR_USER;
|
||
val1 = c->user;
|
||
- else if (e->attr & CEXPR_ROLE)
|
||
+ name1 = policydb->p_user_val_to_name[val1 - 1];
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "u%d=%s ",
|
||
+ s_t_x_num, name1);
|
||
+ free(src); src = strdup(tmp_buf);
|
||
+ }
|
||
+ else if (e->attr & CEXPR_ROLE) {
|
||
+ u_r_t = CEXPR_ROLE;
|
||
val1 = c->role;
|
||
- else if (e->attr & CEXPR_TYPE)
|
||
+ name1 = policydb->p_role_val_to_name[val1 - 1];
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf), "r%d=%s ", s_t_x_num, name1);
|
||
+ free(src); src = strdup(tmp_buf);
|
||
+ }
|
||
+ else if (e->attr & CEXPR_TYPE) {
|
||
+ u_r_t = CEXPR_TYPE;
|
||
val1 = c->type;
|
||
+ name1 = policydb->p_type_val_to_name[val1 - 1];
|
||
+ snprintf(tmp_buf, sizeof(tmp_buf),
|
||
+ "t%d=%s ", s_t_x_num, name1);
|
||
+ free(src); src = strdup(tmp_buf);
|
||
+ }
|
||
else {
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
|
||
switch (e->op) {
|
||
case CEXPR_EQ:
|
||
+ switch (u_r_t) {
|
||
+ case CEXPR_USER:
|
||
+ free(tgt); tgt=strdup("USER_ENTRY");
|
||
+ break;
|
||
+ case CEXPR_ROLE:
|
||
+ free(tgt); tgt=strdup("ROLE_ENTRY");
|
||
+ break;
|
||
+ case CEXPR_TYPE:
|
||
+ free(tgt); tgt=strdup("TYPE_ENTRY");
|
||
+ break;
|
||
+ default:
|
||
+ ERR(NULL, "unrecognized u_r_t Value: %d", u_r_t);
|
||
+ break;
|
||
+ }
|
||
+
|
||
s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
|
||
+ msgcat(src, tgt, "eq", s[sp] == 0);
|
||
+ if (s[sp] == 0) {
|
||
+ get_names_list(e, u_r_t);
|
||
+ }
|
||
break;
|
||
+
|
||
case CEXPR_NEQ:
|
||
+ switch (u_r_t) {
|
||
+ case CEXPR_USER:
|
||
+ free(tgt); tgt=strdup("USER_ENTRY");
|
||
+ break;
|
||
+ case CEXPR_ROLE:
|
||
+ free(tgt); tgt=strdup("ROLE_ENTRY");
|
||
+ break;
|
||
+ case CEXPR_TYPE:
|
||
+ free(tgt); tgt=strdup("TYPE_ENTRY");
|
||
+ break;
|
||
+ default:
|
||
+ ERR(NULL, "unrecognized u_r_t Value: %d", u_r_t);
|
||
+ break;
|
||
+ }
|
||
+
|
||
s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
|
||
+ msgcat(src, tgt, "neq", s[sp] == 0);
|
||
+ if (s[sp] == 0) {
|
||
+ get_names_list(e, u_r_t);
|
||
+ }
|
||
break;
|
||
default:
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
break;
|
||
default:
|
||
BUG();
|
||
- return 0;
|
||
+ goto out;
|
||
}
|
||
+ expr_counter++;
|
||
+ }
|
||
+
|
||
+ /*
|
||
+ * At this point each expression of the constraint is in
|
||
+ * expr_list[n+1] and in RPN format. Now convert to 'infix'
|
||
+ */
|
||
+
|
||
+ /*
|
||
+ * Save expr count but zero expr_counter to detect if 'BUG(); goto out;'
|
||
+ * was called as we need to release any used expr_list malloc's. Normally
|
||
+ * they are released by the RPN to infix code.
|
||
+ */
|
||
+ int expr_count = expr_counter;
|
||
+ expr_counter = 0;
|
||
+
|
||
+ /*
|
||
+ * The array of expression answer buffer pointers and counter. Generate
|
||
+ * the same number of answer buffer entries as expression buffers (as
|
||
+ * there will never be more required).
|
||
+ */
|
||
+ char **answer_list;
|
||
+ int answer_counter = 0;
|
||
+
|
||
+ answer_list = malloc(expr_count * sizeof(*answer_list));
|
||
+ if (!answer_list) {
|
||
+ ERR(NULL, "failed to allocate answer stack");
|
||
+ rc = -ENOMEM;
|
||
+ goto out;
|
||
}
|
||
|
||
- BUG_ON(sp != 0);
|
||
- return s[0];
|
||
+ /* The pop operands */
|
||
+ char *a;
|
||
+ char *b;
|
||
+ int a_len, b_len;
|
||
+
|
||
+ /* Convert constraint from RPN to infix notation. */
|
||
+ for (x = 0; x != expr_count; x++) {
|
||
+ if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x],
|
||
+ "or", 2) == 0) {
|
||
+ b = pop();
|
||
+ b_len = strlen(b);
|
||
+ a = pop();
|
||
+ a_len = strlen(a);
|
||
+
|
||
+ /* get a buffer to hold the answer */
|
||
+ answer_list[answer_counter] = malloc(a_len + b_len + 8);
|
||
+ if (!answer_list[answer_counter]) {
|
||
+ ERR(NULL, "failed to allocate answer buffer");
|
||
+ rc = -ENOMEM;
|
||
+ goto out;
|
||
+ }
|
||
+ memset(answer_list[answer_counter], '\0', a_len + b_len + 8);
|
||
+
|
||
+ sprintf(answer_list[answer_counter], "%s %s %s", a, expr_list[x], b);
|
||
+ push(answer_list[answer_counter++]);
|
||
+ free(a);
|
||
+ free(b);
|
||
+ } else if (strncmp(expr_list[x], "not", 3) == 0) {
|
||
+ b = pop();
|
||
+ b_len = strlen(b);
|
||
+
|
||
+ answer_list[answer_counter] = malloc(b_len + 8);
|
||
+ if (!answer_list[answer_counter]) {
|
||
+ ERR(NULL, "failed to allocate answer buffer");
|
||
+ rc = -ENOMEM;
|
||
+ goto out;
|
||
+ }
|
||
+ memset(answer_list[answer_counter], '\0', b_len + 8);
|
||
+
|
||
+ if (strncmp(b, "not", 3) == 0)
|
||
+ sprintf(answer_list[answer_counter], "%s (%s)", expr_list[x], b);
|
||
+ else
|
||
+ sprintf(answer_list[answer_counter], "%s%s", expr_list[x], b);
|
||
+ push(answer_list[answer_counter++]);
|
||
+ free(b);
|
||
+ } else {
|
||
+ push(expr_list[x]);
|
||
+ }
|
||
+ }
|
||
+ /* Get the final answer from tos and build constraint text */
|
||
+ a = pop();
|
||
+
|
||
+ /* Constraint calculation: rc = 0 is denied, rc = 1 is granted */
|
||
+ sprintf(tmp_buf,"Constraint %s\n", s[0] ? "GRANTED" : "DENIED");
|
||
+
|
||
+ int len, new_buf_len;
|
||
+ char *p, **new_buf = r_buf;
|
||
+ /*
|
||
+ * These contain the constraint components that are added to the
|
||
+ * callers reason buffer.
|
||
+ */
|
||
+ char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };
|
||
+
|
||
+ /*
|
||
+ * This will add the constraints to the callers reason buffer (who is
|
||
+ * responsible for freeing the memory). It will handle any realloc's
|
||
+ * should the buffer be too short.
|
||
+ * The reason_buf_used and reason_buf_len counters are defined globally
|
||
+ * as multiple constraints can be in the buffer.
|
||
+ */
|
||
+ if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
|
||
+ (flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
|
||
+ for (x = 0; buffers[x] != NULL; x++) {
|
||
+ while (1) {
|
||
+ p = *r_buf + reason_buf_used;
|
||
+ len = snprintf(p, reason_buf_len - reason_buf_used, "%s", buffers[x]);
|
||
+ if (len < 0 || len >= reason_buf_len - reason_buf_used) {
|
||
+ new_buf_len = reason_buf_len + REASON_BUF_SIZE;
|
||
+ *new_buf = realloc(*r_buf, new_buf_len);
|
||
+ if (!new_buf) {
|
||
+ ERR(NULL, "failed to realloc reason buffer");
|
||
+ goto out1;
|
||
+ }
|
||
+ **r_buf = **new_buf;
|
||
+ reason_buf_len = new_buf_len;
|
||
+ continue;
|
||
+ } else {
|
||
+ reason_buf_used += len;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+out1:
|
||
+ rc = s[0];
|
||
+ free(a);
|
||
+
|
||
+out:
|
||
+ free(class_buf);
|
||
+ free(src);
|
||
+ free(tgt);
|
||
+
|
||
+ if (expr_counter) {
|
||
+ for (x = 0; expr_list[x] != NULL; x++)
|
||
+ free(expr_list[x]);
|
||
+ }
|
||
+ return rc;
|
||
}
|
||
|
||
/*
|
||
@@ -309,7 +832,9 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
||
sepol_security_class_t tclass,
|
||
sepol_access_vector_t requested,
|
||
struct sepol_av_decision *avd,
|
||
- unsigned int *reason)
|
||
+ unsigned int *reason,
|
||
+ char **r_buf,
|
||
+ unsigned int flags)
|
||
{
|
||
constraint_node_t *constraint;
|
||
struct role_allow *ra;
|
||
@@ -384,8 +909,8 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
||
constraint = tclass_datum->constraints;
|
||
while (constraint) {
|
||
if ((constraint->permissions & (avd->allowed)) &&
|
||
- !constraint_expr_eval(scontext, tcontext, NULL,
|
||
- constraint->expr)) {
|
||
+ !constraint_expr_eval_reason(scontext, tcontext, NULL,
|
||
+ tclass, constraint, r_buf, flags)) {
|
||
avd->allowed =
|
||
(avd->allowed) & ~(constraint->permissions);
|
||
}
|
||
@@ -460,8 +985,8 @@ int hidden sepol_validate_transition(sepol_security_id_t oldsid,
|
||
|
||
constraint = tclass_datum->validatetrans;
|
||
while (constraint) {
|
||
- if (!constraint_expr_eval(ocontext, ncontext, tcontext,
|
||
- constraint->expr)) {
|
||
+ if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
|
||
+ 0, constraint, NULL, 0)) {
|
||
return -EPERM;
|
||
}
|
||
constraint = constraint->next;
|
||
@@ -494,11 +1019,59 @@ int hidden sepol_compute_av_reason(sepol_security_id_t ssid,
|
||
}
|
||
|
||
rc = context_struct_compute_av(scontext, tcontext, tclass,
|
||
- requested, avd, reason);
|
||
+ requested, avd, reason, NULL, 0);
|
||
out:
|
||
return rc;
|
||
}
|
||
|
||
+/*
|
||
+ * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to
|
||
+ * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd
|
||
+ * in the constraint_expr_eval_reason() function.
|
||
+ */
|
||
+int hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
|
||
+ sepol_security_id_t tsid,
|
||
+ sepol_security_class_t tclass,
|
||
+ sepol_access_vector_t requested,
|
||
+ struct sepol_av_decision *avd,
|
||
+ unsigned int *reason,
|
||
+ char **reason_buf,
|
||
+ unsigned int flags)
|
||
+{
|
||
+ *reason_buf = malloc(REASON_BUF_SIZE);
|
||
+ if (!*reason_buf) {
|
||
+ ERR(NULL, "failed to allocate reason buffer");
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+ /*
|
||
+ * These are defined globally as the buffer can contain multiple
|
||
+ * constraint statements so need to keep track
|
||
+ */
|
||
+ reason_buf_used = 0;
|
||
+ reason_buf_len = REASON_BUF_SIZE;
|
||
+
|
||
+ context_struct_t *scontext = 0, *tcontext = 0;
|
||
+ int rc = 0;
|
||
+
|
||
+ scontext = sepol_sidtab_search(sidtab, ssid);
|
||
+ if (!scontext) {
|
||
+ ERR(NULL, "unrecognized SID %d", ssid);
|
||
+ rc = -EINVAL;
|
||
+ goto out;
|
||
+ }
|
||
+ tcontext = sepol_sidtab_search(sidtab, tsid);
|
||
+ if (!tcontext) {
|
||
+ ERR(NULL, "unrecognized SID %d", tsid);
|
||
+ rc = -EINVAL;
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
+ rc = context_struct_compute_av(scontext, tcontext, tclass,
|
||
+ requested, avd, reason, reason_buf, flags);
|
||
+out:
|
||
+ return rc;
|
||
+}
|
||
+
|
||
int hidden sepol_compute_av(sepol_security_id_t ssid,
|
||
sepol_security_id_t tsid,
|
||
sepol_security_class_t tclass,
|
||
@@ -511,6 +1084,70 @@ int hidden sepol_compute_av(sepol_security_id_t ssid,
|
||
}
|
||
|
||
/*
|
||
+ * Return a class ID associated with the class string specified by
|
||
+ * class_name.
|
||
+ */
|
||
+int hidden sepol_class_name_to_id(const char *class_name,
|
||
+ sepol_security_class_t *tclass)
|
||
+{
|
||
+ char *class = NULL;
|
||
+ sepol_security_class_t id;
|
||
+
|
||
+ for (id = 1; ; id++) {
|
||
+ if ((class = policydb->p_class_val_to_name[id - 1]) == NULL) {
|
||
+ ERR(NULL, "could not convert %s to class id", class_name);
|
||
+ return STATUS_ERR;
|
||
+ }
|
||
+ if ((strcmp(class, class_name)) == 0) {
|
||
+ *tclass = id;
|
||
+ return STATUS_SUCCESS;
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Return access vector bit associated with the class ID and permission
|
||
+ * string.
|
||
+ */
|
||
+int hidden sepol_perm_name_to_av(sepol_security_class_t tclass,
|
||
+ const char *perm_name,
|
||
+ sepol_access_vector_t *av)
|
||
+{
|
||
+ class_datum_t *tclass_datum;
|
||
+ perm_datum_t *perm_datum;
|
||
+
|
||
+ if (!tclass || tclass > policydb->p_classes.nprim) {
|
||
+ ERR(NULL, "unrecognized class %d", tclass);
|
||
+ return -EINVAL;
|
||
+ }
|
||
+ tclass_datum = policydb->class_val_to_struct[tclass - 1];
|
||
+
|
||
+ /* Check for unique perms then the common ones (if any) */
|
||
+ perm_datum = (perm_datum_t *)
|
||
+ hashtab_search(tclass_datum->permissions.table,
|
||
+ (hashtab_key_t)perm_name);
|
||
+ if (perm_datum != NULL) {
|
||
+ *av = 0x1 << (perm_datum->s.value - 1);
|
||
+ return STATUS_SUCCESS;
|
||
+ }
|
||
+
|
||
+ if (tclass_datum->comdatum == NULL)
|
||
+ goto out;
|
||
+
|
||
+ perm_datum = (perm_datum_t *)
|
||
+ hashtab_search(tclass_datum->comdatum->permissions.table,
|
||
+ (hashtab_key_t)perm_name);
|
||
+
|
||
+ if (perm_datum != NULL) {
|
||
+ *av = 0x1 << (perm_datum->s.value - 1);
|
||
+ return STATUS_SUCCESS;
|
||
+ }
|
||
+out:
|
||
+ ERR(NULL, "could not convert %s to av bit", perm_name);
|
||
+ return STATUS_ERR;
|
||
+}
|
||
+
|
||
+/*
|
||
* Write the security context string representation of
|
||
* the context associated with `sid' into a dynamically
|
||
* allocated string of the correct size. Set `*scontext'
|
||
@@ -1339,7 +1976,7 @@ int hidden sepol_get_user_sids(sepol_security_id_t fromsid,
|
||
rc = context_struct_compute_av(fromcon, &usercon,
|
||
SECCLASS_PROCESS,
|
||
PROCESS__TRANSITION,
|
||
- &avd, &reason);
|
||
+ &avd, &reason, NULL, 0);
|
||
if (rc || !(avd.allowed & PROCESS__TRANSITION))
|
||
continue;
|
||
rc = sepol_sidtab_context_to_sid(sidtab, &usercon,
|
||
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
|
||
index 55992f8..6fe73e6 100644
|
||
--- a/libsepol/src/write.c
|
||
+++ b/libsepol/src/write.c
|
||
@@ -893,8 +893,11 @@ static int write_cons_helper(policydb_t * p,
|
||
if (ebitmap_write(&e->names, fp)) {
|
||
return POLICYDB_ERROR;
|
||
}
|
||
- if (p->policy_type != POLICY_KERN &&
|
||
- type_set_write(e->type_names, fp)) {
|
||
+ if ((p->policy_type != POLICY_KERN &&
|
||
+ type_set_write(e->type_names, fp)) ||
|
||
+ (p->policy_type == POLICY_KERN &&
|
||
+ (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) &&
|
||
+ type_set_write(e->type_names, fp))) {
|
||
return POLICYDB_ERROR;
|
||
}
|
||
break;
|
||
diff --git a/policycoreutils/Makefile b/policycoreutils/Makefile
|
||
index 3980799..6624804 100644
|
||
--- a/policycoreutils/Makefile
|
||
+++ b/policycoreutils/Makefile
|
||
@@ -1,4 +1,4 @@
|
||
-SUBDIRS = sepolicy setfiles semanage load_policy newrole run_init sandbox secon audit2allow audit2why sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui
|
||
+SUBDIRS = sepolicy setfiles semanage semanage/default_encoding load_policy newrole run_init sandbox secon audit2allow sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui
|
||
|
||
INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null)
|
||
|
||
diff --git a/policycoreutils/audit2allow/Makefile b/policycoreutils/audit2allow/Makefile
|
||
index 88635d4..fc290ea 100644
|
||
--- a/policycoreutils/audit2allow/Makefile
|
||
+++ b/policycoreutils/audit2allow/Makefile
|
||
@@ -5,14 +5,19 @@ LIBDIR ?= $(PREFIX)/lib
|
||
MANDIR ?= $(PREFIX)/share/man
|
||
LOCALEDIR ?= /usr/share/locale
|
||
|
||
-all: ;
|
||
+all: audit2why
|
||
+
|
||
+audit2why:
|
||
+ ln -sf audit2allow audit2why
|
||
|
||
install: all
|
||
-mkdir -p $(BINDIR)
|
||
install -m 755 audit2allow $(BINDIR)
|
||
+ (cd $(BINDIR); ln -sf audit2allow audit2why)
|
||
install -m 755 sepolgen-ifgen $(BINDIR)
|
||
-mkdir -p $(MANDIR)/man1
|
||
install -m 644 audit2allow.1 $(MANDIR)/man1/
|
||
+ install -m 644 audit2why.1 $(MANDIR)/man1/
|
||
|
||
clean:
|
||
rm -f *~
|
||
diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow
|
||
index 8e0c396..9bd66f5 100644
|
||
--- a/policycoreutils/audit2allow/audit2allow
|
||
+++ b/policycoreutils/audit2allow/audit2allow
|
||
@@ -18,7 +18,7 @@
|
||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
#
|
||
|
||
-import sys
|
||
+import sys, os
|
||
|
||
import sepolgen.audit as audit
|
||
import sepolgen.policygen as policygen
|
||
@@ -29,6 +29,8 @@ import sepolgen.defaults as defaults
|
||
import sepolgen.module as module
|
||
from sepolgen.sepolgeni18n import _
|
||
import selinux.audit2why as audit2why
|
||
+import locale
|
||
+locale.setlocale(locale.LC_ALL, '')
|
||
|
||
class AuditToPolicy:
|
||
VERSION = "%prog .1"
|
||
@@ -80,8 +82,7 @@ class AuditToPolicy:
|
||
parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
|
||
parser.add_option("--debug", dest="debug", action="store_true", default=False,
|
||
help="leave generated modules for -M")
|
||
-
|
||
- parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=False,
|
||
+ parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
|
||
help="Translates SELinux audit messages into a description of why the access was denied")
|
||
|
||
options, args = parser.parse_args()
|
||
diff --git a/policycoreutils/audit2allow/audit2why.1 b/policycoreutils/audit2allow/audit2why.1
|
||
new file mode 100644
|
||
index 0000000..a9e8893
|
||
--- /dev/null
|
||
+++ b/policycoreutils/audit2allow/audit2why.1
|
||
@@ -0,0 +1 @@
|
||
+.so man1/audit2allow.1
|
||
diff --git a/policycoreutils/audit2why/Makefile b/policycoreutils/audit2why/Makefile
|
||
deleted file mode 100644
|
||
index 63eb8b3..0000000
|
||
--- a/policycoreutils/audit2why/Makefile
|
||
+++ /dev/null
|
||
@@ -1,18 +0,0 @@
|
||
-# Installation directories.
|
||
-PREFIX ?= $(DESTDIR)/usr
|
||
-BINDIR ?= $(PREFIX)/bin
|
||
-MANDIR ?= $(PREFIX)/share/man
|
||
-
|
||
-TARGETS=audit2why
|
||
-
|
||
-all: $(TARGETS)
|
||
-
|
||
-install: all
|
||
- -mkdir -p $(BINDIR)
|
||
- install -m 755 $(TARGETS) $(BINDIR)
|
||
- -mkdir -p $(MANDIR)/man1
|
||
- install -m 644 audit2why.1 $(MANDIR)/man1/
|
||
-
|
||
-clean:
|
||
-
|
||
-relabel:
|
||
diff --git a/policycoreutils/audit2why/audit2why b/policycoreutils/audit2why/audit2why
|
||
deleted file mode 100644
|
||
index 21a72aa..0000000
|
||
--- a/policycoreutils/audit2why/audit2why
|
||
+++ /dev/null
|
||
@@ -1,2 +0,0 @@
|
||
-#!/bin/sh
|
||
-/usr/bin/audit2allow -w $*
|
||
diff --git a/policycoreutils/audit2why/audit2why.1 b/policycoreutils/audit2why/audit2why.1
|
||
deleted file mode 100644
|
||
index a9e8893..0000000
|
||
--- a/policycoreutils/audit2why/audit2why.1
|
||
+++ /dev/null
|
||
@@ -1 +0,0 @@
|
||
-.so man1/audit2allow.1
|
||
diff --git a/policycoreutils/gui/Makefile b/policycoreutils/gui/Makefile
|
||
index b5abbb9..1148b36 100644
|
||
--- a/policycoreutils/gui/Makefile
|
||
+++ b/policycoreutils/gui/Makefile
|
||
@@ -1,7 +1,10 @@
|
||
# Installation directories.
|
||
PREFIX ?= ${DESTDIR}/usr
|
||
+SYSCONFDIR ?= ${DESTDIR}/etc
|
||
BINDIR ?= $(PREFIX)/bin
|
||
SHAREDIR ?= $(PREFIX)/share/system-config-selinux
|
||
+DATADIR ?= $(PREFIX)/share
|
||
+PAMDIR ?= $(SYSCONFDIR)/pam.d
|
||
|
||
TARGETS= \
|
||
booleansPage.py \
|
||
@@ -16,6 +19,7 @@ portsPage.py \
|
||
semanagePage.py \
|
||
statusPage.py \
|
||
system-config-selinux.glade \
|
||
+system-config-selinux.png \
|
||
usersPage.py
|
||
|
||
all: $(TARGETS) system-config-selinux.py polgengui.py
|
||
@@ -23,10 +27,21 @@ all: $(TARGETS) system-config-selinux.py polgengui.py
|
||
install: all
|
||
-mkdir -p $(SHAREDIR)
|
||
-mkdir -p $(BINDIR)
|
||
+ -mkdir -p $(DATADIR)/pixmaps
|
||
+ -mkdir -p $(DATADIR)/icons/hicolor/24x24/apps
|
||
+ -mkdir -p $(SYSCONFDIR)
|
||
+ -mkdir -p $(PAMDIR)
|
||
+ -mkdir -p $(SYSCONFDIR)/security/console.apps/system-config-selinux
|
||
install -m 755 system-config-selinux.py $(SHAREDIR)
|
||
install -m 755 polgengui.py $(SHAREDIR)
|
||
install -m 755 sepolgen $(BINDIR)
|
||
install -m 644 $(TARGETS) $(SHAREDIR)
|
||
+ install -m 644 system-config-selinux.png $(DATADIR)/pixmaps
|
||
+ install -m 644 system-config-selinux.png $(DATADIR)/icons/hicolor/24x24/apps
|
||
+ install -m 644 system-config-selinux.png $(DATADIR)/system-config-selinux
|
||
+ install -m 644 *.desktop $(DATADIR)/system-config-selinux
|
||
+ install -m 644 system-config-selinux.pam $(PAMDIR)/system-config-selinux
|
||
+ install -m 644 system-config-selinux.console $(SYSCONFDIR)/security/console.apps/system-config-selinux
|
||
|
||
clean:
|
||
|
||
diff --git a/policycoreutils/gui/selinux-polgengui.desktop b/policycoreutils/gui/selinux-polgengui.desktop
|
||
new file mode 100644
|
||
index 0000000..0c2f399
|
||
--- /dev/null
|
||
+++ b/policycoreutils/gui/selinux-polgengui.desktop
|
||
@@ -0,0 +1,67 @@
|
||
+[Desktop Entry]
|
||
+Name=SELinux Policy Generation Tool
|
||
+Name[bn_IN]=SELinux Policy নির্মাণের সামগ্রী
|
||
+Name[ca]=Eina de generació de polítiques del SELinux
|
||
+Name[da]=Regelsætgenereringsværktøj til SELinux
|
||
+Name[de]=Tool zur Erstellung von SELinux-Richtlinien
|
||
+Name[es]=Generador de Políticas de SELinux
|
||
+Name[fi]=SELinux-käytäntöjen generointityökalu
|
||
+Name[fr]=Outil de génération de stratégies SELinux
|
||
+Name[gu]=SELinux પોલિસી બનાવટ સાધન
|
||
+Name[hi]=SELinux पॉलिसी जनन औजार
|
||
+Name[it]=Tool di generazione della policy di SELinux
|
||
+Name[ja]=SELinux ポリシー生成ツール
|
||
+Name[kn]=SELinux ಪಾಲಿಸಿ ಉತ್ಪಾದನಾ ಉಪಕರಣ
|
||
+Name[ko]=SELinux 정책 생성 도구
|
||
+Name[ml]=SELinux പോളിസി ഉത്പാദന പ്രയോഗം
|
||
+Name[mr]=SELinux करार निर्माण साधन
|
||
+Name[nl]=SELinux tactiek generatie gereedschap
|
||
+Name[or]=SELinux ନୀତି ସୃଷ୍ଟି ଉପକରଣ
|
||
+Name[pa]=SELinux ਪਾਲਿਸੀ ਨਿਰਮਾਣ ਜੰਤਰ
|
||
+Name[pl]=Narzędzie tworzenia polityki SELinuksa
|
||
+Name[pt]=Ferramenta de Geração de Políticas SELinux
|
||
+Name[pt_BR]=Ferramenta de criação de políticas do SELinux
|
||
+Name[ru]=Средство создания политики SELinux
|
||
+Name[sv]=Genereringsverktyg för SELinuxpolicy
|
||
+Name[ta]=SELinux பாலிசி உற்பத்தி கருவி
|
||
+Name[te]=SELinux నిర్వహణ
|
||
+Name[uk]=Утиліта генерації правил SELinux
|
||
+Name[zh_CN]=SELinux 策略生成工具
|
||
+Name[zh_TW]=SELinux 政策產生工具(SELinux Policy Generation Tool)
|
||
+Comment=Generate SELinux policy modules
|
||
+Comment[bn_IN]=SELinux নিয়মনীতির মডিউল নির্মাণ করুন
|
||
+Comment[ca]=Genera els mòduls de les polítiques de SELinux
|
||
+Comment[da]=Generér SELinux-regelsætmodul
|
||
+Comment[de]=Tool zur Erstellung von SELinux-Richtlinien
|
||
+Comment[es]=Generar módulos de política de SELinux
|
||
+Comment[fi]=Generoi SELinuxin käytäntömoduuleja
|
||
+Comment[fr]=Génére des modules de stratégie SELinux
|
||
+Comment[gu]=SELinux પોલિસી મોડ્યુલોને ઉત્પન્ન કરો
|
||
+Comment[hi]=नया पॉलिसी मॉड्यूल उत्पन्न करें
|
||
+Comment[it]=Genera moduli della politica di SELinux
|
||
+Comment[ja]=新しいポリシーモジュールの作成
|
||
+Comment[kn]=SELinux ಪಾಲಿಸಿ ಘಟಕಗಳನ್ನು ಉತ್ಪಾದಿಸು
|
||
+Comment[ko]=SELinux 정책 모듈 생성
|
||
+Comment[ml]=SELinux യ പോളിസി ഘങ്ങള് തയ്യാറാക്കുക
|
||
+Comment[mr]=SELinux करार घटके निर्माण करा
|
||
+Comment[nl]=Maak een SELinux tactiek module aan
|
||
+Comment[or]=SELinux ନୀତି ଏକକାଂଶ ସୃଷ୍ଟିକରନ୍ତୁ
|
||
+Comment[pa]=SELinux ਪਾਲਿਸੀ ਮੈਡਿਊਲ ਬਣਾਓ
|
||
+Comment[pl]=Tworzenie nowych modułów polityki SELinuksa
|
||
+Comment[pt]=Gerar módulos de políticas SELinux
|
||
+Comment[pt_BR]=Gerar módulos de política do SELinux
|
||
+Comment[ru]=Генерация модулей политики SELinux
|
||
+Comment[sv]=Generera SELinux-policymoduler
|
||
+Comment[ta]=SELinux கொள்கை தொகுதியை உருவாக்கவும்
|
||
+Comment[te]=SELinux పాలసీ మాడ్యూళ్ళను వుద్భవింపచేయుము
|
||
+Comment[uk]=Створення модулів контролю доступу SELinux
|
||
+Comment[zh_CN]=生成 SELinux 策略模块
|
||
+Comment[zh_TW]=產生 SELinux 政策模組
|
||
+StartupNotify=true
|
||
+Icon=system-config-selinux
|
||
+Exec=/usr/bin/selinux-polgengui
|
||
+Type=Application
|
||
+Terminal=false
|
||
+Categories=System;Security;
|
||
+X-Desktop-File-Install-Version=0.2
|
||
+Keywords=policy;security;selinux;avc;permission;mac;
|
||
diff --git a/policycoreutils/gui/system-config-selinux.console b/policycoreutils/gui/system-config-selinux.console
|
||
new file mode 100644
|
||
index 0000000..42b48a3
|
||
--- /dev/null
|
||
+++ b/policycoreutils/gui/system-config-selinux.console
|
||
@@ -0,0 +1,3 @@
|
||
+USER=root
|
||
+PROGRAM=/usr/share/system-config-selinux/system-config-selinux.py
|
||
+SESSION=true
|
||
diff --git a/policycoreutils/gui/system-config-selinux.desktop b/policycoreutils/gui/system-config-selinux.desktop
|
||
new file mode 100644
|
||
index 0000000..8822ce2
|
||
--- /dev/null
|
||
+++ b/policycoreutils/gui/system-config-selinux.desktop
|
||
@@ -0,0 +1,67 @@
|
||
+[Desktop Entry]
|
||
+Name=SELinux Management
|
||
+Name[bn_IN]=SELinux পরিচালনা
|
||
+Name[da]=Håndtering af SELinux
|
||
+Name[de]=SELinux-Management
|
||
+Name[ca]=Gestió de SELinux
|
||
+Name[es]=Administración de SELinux
|
||
+Name[fi]=SELinuxin ylläpito
|
||
+Name[fr]=Gestion de SELinux
|
||
+Name[gu]=SELinux સંચાલન
|
||
+Name[hi]=SELinux प्रबंधन
|
||
+Name[jp]=SELinux 管理
|
||
+Name[it]=Gestione di SELinux
|
||
+Name[kn]=SELinux ವ್ಯವಸ್ಥಾಪನೆ
|
||
+Name[ko]=SELinux 관리
|
||
+Name[ml]=SELinux മാനേജ്മെന്റ്
|
||
+Name[mr]=SELinux मॅनेजमेंट
|
||
+Name[nl]=SELinux beheer
|
||
+Name[or]=SELinux ପରିଚାଳନା
|
||
+Name[pa]=SELinux ਮੈਨੇਜਮੈਂਟ
|
||
+Name[pl]=Zarządzanie SELinuksem
|
||
+Name[pt_BR]=Gerenciamento do SELinux
|
||
+Name[pt]=Gestão de SELinux
|
||
+Name[ru]=Управление SELinux
|
||
+Name[sv]=SELinux-hantering
|
||
+Name[ta]=SELinux மேலாண்மை
|
||
+Name[te]=SELinux నిర్వహణ
|
||
+Name[uk]=Керування SELinux
|
||
+Name[zh_CN]=SELinux 管理
|
||
+Name[zh_TW]=SELinux 管理
|
||
+Comment=Configure SELinux in a graphical setting
|
||
+Comment[bn_IN]=গ্রাফিক্যাল পরিবেশে SELinux কনফিগার করুন
|
||
+Comment[ca]=Configura SELinuc an mode de preferències gràfiques
|
||
+Comment[da]=Konfigurér SELinux i et grafisk miljø
|
||
+Comment[de]=SELinux in einer grafischen Einstellung konfigurieren
|
||
+Comment[es]=Defina SELinux en una configuración de interfaz gráfica
|
||
+Comment[fi]=Tee SELinuxin asetukset graafisesti
|
||
+Comment[fr]=Configure SELinux dans un environnement graphique
|
||
+Comment[gu]=ગ્રાફિકલ સુયોજનમાં SELinux ને રૂપરેખાંકિત કરો
|
||
+Comment[hi]=SELinux को आलेखी सेटिंग में विन्यस्त करें
|
||
+Comment[it]=Configura SELinux in una impostazione grafica
|
||
+Comment[jp]=グラフィカルな設定画面で SELinux を設定する
|
||
+Comment[ko]=SELinux를 그래픽 사용자 인터페이스로 설정
|
||
+Comment[kn]=SELinux ಅನ್ನು ಒಂದು ಚಿತ್ರಾತ್ಮಕ ಸಿದ್ದತೆಯಲ್ಲಿ ಸಂರಚಿಸಿ
|
||
+Comment[ml]=ഒരു ഗ്രാഫിക്കല് സജ്ജീകരണത്തില് SELinux ക്രമീകരിയ്ക്കുക
|
||
+Comment[mr]=ग्राफिकल सेटिंगमध्ये SELinux संरचीत करा
|
||
+Comment[nl]=Configureer SELinux in een grafische omgeving
|
||
+Comment[or]=SELinux କୁ ଆଲେଖିକ ସଂରଚନାରେ ବିନ୍ୟାସ କରନ୍ତୁ
|
||
+Comment[pa]=SELinux ਨੂੰ ਗਰਾਫੀਕਲ ਸੈਟਿੰਗ ਵਿੱਚ ਸੰਰਚਿਤ ਕਰੋ
|
||
+Comment[pl]=Konfiguracja SELinuksa w trybie graficznym
|
||
+Comment[pt]=Configurar o SELinux num ambiente gráfico
|
||
+Comment[pt_BR]=Configure o SELinux em uma configuração gráfica
|
||
+Comment[ru]=Настройка SELinux в графическом режиме
|
||
+Comment[sv]=Konfigurera SELinux i en grafisk miljö
|
||
+Comment[ta]=SELinuxஐ ஒரு வரைகலை அமைவில் கட்டமைக்கவும்
|
||
+Comment[te]=SELinuxను గ్రాఫికల్ అమర్పునందు ఆకృతీకరించుము
|
||
+Comment[uk]=Засіб для налаштування SELinux з графічним інтерфейсом
|
||
+Comment[zh_CN]=在图形设置中配置 SELinux
|
||
+Comment[zh_TW]=在圖形話設定中配置 SELinux
|
||
+StartupNotify=true
|
||
+Icon=system-config-selinux
|
||
+Exec=/usr/bin/system-config-selinux
|
||
+Type=Application
|
||
+Terminal=false
|
||
+Categories=System;Security;
|
||
+X-Desktop-File-Install-Version=0.2
|
||
+Keywords=policy;security;selinux;avc;permission;mac;
|
||
diff --git a/policycoreutils/gui/system-config-selinux.pam b/policycoreutils/gui/system-config-selinux.pam
|
||
new file mode 100644
|
||
index 0000000..6a8c230
|
||
--- /dev/null
|
||
+++ b/policycoreutils/gui/system-config-selinux.pam
|
||
@@ -0,0 +1,8 @@
|
||
+#%PAM-1.0
|
||
+auth sufficient pam_rootok.so
|
||
+auth sufficient pam_timestamp.so
|
||
+auth include system-auth
|
||
+session required pam_permit.so
|
||
+session optional pam_xauth.so
|
||
+session optional pam_timestamp.so
|
||
+account required pam_permit.so
|
||
diff --git a/policycoreutils/gui/system-config-selinux.png b/policycoreutils/gui/system-config-selinux.png
|
||
new file mode 100644
|
||
index 0000000..68ffcb7
|
||
Binary files /dev/null and b/policycoreutils/gui/system-config-selinux.png differ
|
||
diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c
|
||
index 8fbf2d0..3753ef4 100644
|
||
--- a/policycoreutils/newrole/newrole.c
|
||
+++ b/policycoreutils/newrole/newrole.c
|
||
@@ -680,7 +680,7 @@ static int relabel_tty(const char *ttyn, security_context_t new_context,
|
||
security_context_t * tty_context,
|
||
security_context_t * new_tty_context)
|
||
{
|
||
- int fd;
|
||
+ int fd, rc;
|
||
int enforcing = security_getenforce();
|
||
security_context_t tty_con = NULL;
|
||
security_context_t new_tty_con = NULL;
|
||
@@ -699,7 +699,13 @@ static int relabel_tty(const char *ttyn, security_context_t new_context,
|
||
fprintf(stderr, _("Error! Could not open %s.\n"), ttyn);
|
||
return fd;
|
||
}
|
||
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ /* this craziness is to make sure we cann't block on open and deadlock */
|
||
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ if (rc) {
|
||
+ fprintf(stderr, _("Error! Could not clear O_NONBLOCK on %s\n"), ttyn);
|
||
+ close(fd);
|
||
+ return rc;
|
||
+ }
|
||
|
||
if (fgetfilecon(fd, &tty_con) < 0) {
|
||
fprintf(stderr, _("%s! Could not get current context "
|
||
@@ -1010,9 +1016,9 @@ int main(int argc, char *argv[])
|
||
int fd;
|
||
pid_t childPid = 0;
|
||
char *shell_argv0 = NULL;
|
||
+ int rc;
|
||
|
||
#ifdef USE_PAM
|
||
- int rc;
|
||
int pam_status; /* pam return code */
|
||
pam_handle_t *pam_handle; /* opaque handle used by all PAM functions */
|
||
|
||
@@ -1226,15 +1232,23 @@ int main(int argc, char *argv[])
|
||
fd = open(ttyn, O_RDONLY | O_NONBLOCK);
|
||
if (fd != 0)
|
||
goto err_close_pam;
|
||
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ if (rc)
|
||
+ goto err_close_pam;
|
||
+
|
||
fd = open(ttyn, O_RDWR | O_NONBLOCK);
|
||
if (fd != 1)
|
||
goto err_close_pam;
|
||
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ if (rc)
|
||
+ goto err_close_pam;
|
||
+
|
||
fd = open(ttyn, O_RDWR | O_NONBLOCK);
|
||
if (fd != 2)
|
||
goto err_close_pam;
|
||
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||
+ if (rc)
|
||
+ goto err_close_pam;
|
||
|
||
}
|
||
/*
|
||
diff --git a/policycoreutils/po/Makefile b/policycoreutils/po/Makefile
|
||
index a377996..9c1486e 100644
|
||
--- a/policycoreutils/po/Makefile
|
||
+++ b/policycoreutils/po/Makefile
|
||
@@ -81,12 +81,16 @@ POTFILES = \
|
||
../sepolicy/sepolicy/templates/var_log.py \
|
||
../sepolicy/sepolicy/templates/var_run.py \
|
||
../sepolicy/sepolicy/templates/var_spool.py \
|
||
+ booleans.py
|
||
|
||
#default:: clean
|
||
|
||
all:: $(MOFILES)
|
||
|
||
-$(POTFILE): $(POTFILES)
|
||
+booleans.py:
|
||
+ sepolicy booleans -a > booleans.py
|
||
+
|
||
+$(POTFILE): $(POTFILES) booleans.py
|
||
$(XGETTEXT) --keyword=_ --keyword=N_ $(POTFILES)
|
||
@if cmp -s $(NLSPACKAGE).po $(POTFILE); then \
|
||
rm -f $(NLSPACKAGE).po; \
|
||
@@ -95,6 +99,7 @@ $(POTFILE): $(POTFILES)
|
||
fi; \
|
||
|
||
update-po: Makefile $(POTFILE) refresh-po
|
||
+ @rm -f booleans.py
|
||
|
||
refresh-po: Makefile
|
||
for cat in $(POFILES); do \
|
||
diff --git a/policycoreutils/restorecond/Makefile b/policycoreutils/restorecond/Makefile
|
||
index 3074542..3b704d8 100644
|
||
--- a/policycoreutils/restorecond/Makefile
|
||
+++ b/policycoreutils/restorecond/Makefile
|
||
@@ -5,6 +5,7 @@ LIBDIR ?= $(PREFIX)/lib
|
||
MANDIR = $(PREFIX)/share/man
|
||
AUTOSTARTDIR = $(DESTDIR)/etc/xdg/autostart
|
||
DBUSSERVICEDIR = $(DESTDIR)/usr/share/dbus-1/services
|
||
+SYSTEMDDIR ?= $(DESTDIR)/usr/lib/systemd
|
||
|
||
autostart_DATA = sealertauto.desktop
|
||
INITDIR = $(DESTDIR)/etc/rc.d/init.d
|
||
@@ -39,7 +40,8 @@ install: all
|
||
install -m 644 restorecond.desktop $(AUTOSTARTDIR)/restorecond.desktop
|
||
-mkdir -p $(DBUSSERVICEDIR)
|
||
install -m 600 org.selinux.Restorecond.service $(DBUSSERVICEDIR)/org.selinux.Restorecond.service
|
||
-
|
||
+ -mkdir -p $(SYSTEMDDIR)/system
|
||
+ install -m 644 restorecond.service $(SYSTEMDDIR)/system/
|
||
relabel: install
|
||
/sbin/restorecon $(SBINDIR)/restorecond
|
||
|
||
diff --git a/policycoreutils/restorecond/restorecond.service b/policycoreutils/restorecond/restorecond.service
|
||
new file mode 100644
|
||
index 0000000..11f4ffd
|
||
--- /dev/null
|
||
+++ b/policycoreutils/restorecond/restorecond.service
|
||
@@ -0,0 +1,12 @@
|
||
+[Unit]
|
||
+Description=Restorecon maintaining path file context
|
||
+After=syslog.target
|
||
+ConditionPathExists=/etc/selinux/restorecond.conf
|
||
+
|
||
+[Service]
|
||
+Type=oneshot
|
||
+ExecStart=/usr/sbin/restorecond
|
||
+RemainAfterExit=yes
|
||
+
|
||
+[Install]
|
||
+WantedBy=multi-user.target
|
||
diff --git a/policycoreutils/restorecond/user.c b/policycoreutils/restorecond/user.c
|
||
index 00a646f..2c28676 100644
|
||
--- a/policycoreutils/restorecond/user.c
|
||
+++ b/policycoreutils/restorecond/user.c
|
||
@@ -54,6 +54,7 @@ static const char *PATH="/org/selinux/Restorecond";
|
||
static const char *INTERFACE="org.selinux.RestorecondIface";
|
||
static const char *RULE="type='signal',interface='org.selinux.RestorecondIface'";
|
||
|
||
+static int local_lock_fd = -1;
|
||
|
||
static DBusHandlerResult
|
||
signal_filter (DBusConnection *connection __attribute__ ((__unused__)), DBusMessage *message, void *user_data)
|
||
@@ -201,17 +202,18 @@ static int local_server() {
|
||
perror("asprintf");
|
||
return -1;
|
||
}
|
||
- int fd = open(ptr, O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR);
|
||
+ local_lock_fd = open(ptr, O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR);
|
||
if (debug_mode)
|
||
g_warning ("Lock file: %s", ptr);
|
||
|
||
free(ptr);
|
||
- if (fd < 0) {
|
||
+ if (local_lock_fd < 0) {
|
||
if (debug_mode)
|
||
perror("open");
|
||
return -1;
|
||
}
|
||
- if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
|
||
+ if (flock(local_lock_fd, LOCK_EX | LOCK_NB) < 0) {
|
||
+ close(local_lock_fd);
|
||
if (debug_mode)
|
||
perror("flock");
|
||
return -1;
|
||
@@ -226,6 +228,12 @@ static int local_server() {
|
||
return 0;
|
||
}
|
||
|
||
+static void end_local_server(void) {
|
||
+ if (local_lock_fd >= 0)
|
||
+ close(local_lock_fd);
|
||
+ local_lock_fd = -1;
|
||
+}
|
||
+
|
||
int server(int master_fd, const char *watch_file) {
|
||
GMainLoop *loop;
|
||
|
||
@@ -253,6 +261,7 @@ int server(int master_fd, const char *watch_file) {
|
||
g_main_loop_run (loop);
|
||
|
||
end:
|
||
+ end_local_server();
|
||
g_main_loop_unref (loop);
|
||
return 0;
|
||
}
|
||
diff --git a/policycoreutils/sandbox/sandbox b/policycoreutils/sandbox/sandbox
|
||
index b629006..6631c2d 100644
|
||
--- a/policycoreutils/sandbox/sandbox
|
||
+++ b/policycoreutils/sandbox/sandbox
|
||
@@ -243,7 +243,7 @@ class Sandbox:
|
||
copyfile(f, "/tmp", self.__tmpdir)
|
||
copyfile(f, "/var/tmp", self.__tmpdir)
|
||
|
||
- def __setup_sandboxrc(self, wm = "/usr/bin/matchbox-window-manager -use_titlebar no"):
|
||
+ def __setup_sandboxrc(self, wm = "/usr/bin/openbox"):
|
||
execfile =self.__homedir + "/.sandboxrc"
|
||
fd = open(execfile, "w+")
|
||
if self.__options.session:
|
||
@@ -333,7 +333,7 @@ sandbox [-h] [-c] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile
|
||
|
||
parser.add_option("-W", "--windowmanager", dest="wm",
|
||
type="string",
|
||
- default="/usr/bin/matchbox-window-manager -use_titlebar no",
|
||
+ default="/usr/bin/openbox",
|
||
help=_("alternate window manager"))
|
||
|
||
parser.add_option("-l", "--level", dest="level",
|
||
diff --git a/policycoreutils/sandbox/sandbox.8 b/policycoreutils/sandbox/sandbox.8
|
||
index 521afcd..a50eef2 100644
|
||
--- a/policycoreutils/sandbox/sandbox.8
|
||
+++ b/policycoreutils/sandbox/sandbox.8
|
||
@@ -70,7 +70,7 @@ Specifies the windowsize when creating an X based Sandbox. The default windowsiz
|
||
\fB\-W windowmanager\fR
|
||
Select alternative window manager to run within
|
||
.B sandbox -X.
|
||
-Default to /usr/bin/matchbox-window-manager.
|
||
+Default to /usr/bin/openbox.
|
||
.TP
|
||
\fB\-X\fR
|
||
Create an X based Sandbox for gui apps, temporary files for
|
||
diff --git a/policycoreutils/sandbox/sandboxX.sh b/policycoreutils/sandbox/sandboxX.sh
|
||
index 23de6f6..171bb05 100644
|
||
--- a/policycoreutils/sandbox/sandboxX.sh
|
||
+++ b/policycoreutils/sandbox/sandboxX.sh
|
||
@@ -6,6 +6,20 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8
|
||
[ -z $2 ] && export DPI="96" || export DPI="$2"
|
||
trap "exit 0" HUP
|
||
|
||
+mkdir -p ~/.config/openbox
|
||
+cat > ~/.config/openbox/rc.xml << EOF
|
||
+<openbox_config xmlns="http://openbox.org/3.4/rc"
|
||
+ xmlns:xi="http://www.w3.org/2001/XInclude">
|
||
+<applications>
|
||
+ <application class="*">
|
||
+ <decor>no</decor>
|
||
+ <desktop>all</desktop>
|
||
+ <maximized>yes</maximized>
|
||
+ </application>
|
||
+</applications>
|
||
+</openbox_config>
|
||
+EOF
|
||
+
|
||
(/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do
|
||
export DISPLAY=:$D
|
||
cat > ~/seremote << __EOF
|
||
diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c
|
||
index dbd5977..f10df39 100644
|
||
--- a/policycoreutils/sandbox/seunshare.c
|
||
+++ b/policycoreutils/sandbox/seunshare.c
|
||
@@ -962,7 +962,7 @@ int main(int argc, char **argv) {
|
||
char *LANG = NULL;
|
||
int rc = -1;
|
||
|
||
- if (unshare(CLONE_NEWNS) < 0) {
|
||
+ if (unshare(CLONE_NEWNS | CLONE_NEWIPC) < 0) {
|
||
perror(_("Failed to unshare"));
|
||
goto childerr;
|
||
}
|
||
diff --git a/policycoreutils/scripts/Makefile b/policycoreutils/scripts/Makefile
|
||
index 201a988..f5d6e9d 100644
|
||
--- a/policycoreutils/scripts/Makefile
|
||
+++ b/policycoreutils/scripts/Makefile
|
||
@@ -9,23 +9,12 @@ LOCALEDIR ?= $(PREFIX)/share/locale
|
||
.PHONY: all genhomedircon
|
||
all: fixfiles genhomedircon chcat
|
||
|
||
-genhomedircon:
|
||
- @echo "#!/bin/sh" > genhomedircon
|
||
- @echo >> genhomedircon
|
||
- @if [ -z "${SEMODULE_PATH}" ]; then \
|
||
- echo "${USRSBINDIR}/semodule -Bn" >> genhomedircon; \
|
||
- else \
|
||
- echo "${SEMODULE_PATH}/semodule -Bn" >> genhomedircon; \
|
||
- fi
|
||
-
|
||
install: all
|
||
-mkdir -p $(BINDIR)
|
||
install -m 755 chcat $(BINDIR)
|
||
install -m 755 fixfiles $(SBINDIR)
|
||
- install -m 755 genhomedircon $(USRSBINDIR)
|
||
-mkdir -p $(MANDIR)/man8
|
||
install -m 644 fixfiles.8 $(MANDIR)/man8/
|
||
- install -m 644 genhomedircon.8 $(MANDIR)/man8/
|
||
install -m 644 chcat.8 $(MANDIR)/man8/
|
||
|
||
clean:
|
||
diff --git a/policycoreutils/scripts/genhomedircon.8 b/policycoreutils/scripts/genhomedircon.8
|
||
deleted file mode 100644
|
||
index 8ec509c..0000000
|
||
--- a/policycoreutils/scripts/genhomedircon.8
|
||
+++ /dev/null
|
||
@@ -1,24 +0,0 @@
|
||
-.TH GENHOMEDIRCON "12" "Sep 2011" "Security Enhanced Linux" "SELinux"
|
||
-.SH NAME
|
||
-genhomedircon \- generate SELinux file context configuration entries for user home directories
|
||
-.SH SYNOPSIS
|
||
-.B genhomedircon
|
||
-is a script that executes
|
||
-.B semodule
|
||
-to rebuild the currently active SELinux policy (without reloading it) and to create the
|
||
-labels for each user home directory based on directory paths returned by calls to getpwent().
|
||
-
|
||
-The latter functionality depends on the "usepasswd" parameter being set to "true" (default)
|
||
-in /etc/selinux/semanage.conf.
|
||
-
|
||
-This script is usually executed by
|
||
-.B semanage
|
||
-although this default behavior can be optionally modified by setting to "true" the
|
||
-"disable-genhomedircon" in /etc/selinux/semanage.conf.
|
||
-
|
||
-.SH AUTHOR
|
||
-This manual page was written by
|
||
-.I Dan Walsh <dwalsh@redhat.com>
|
||
-
|
||
-.SH "SEE ALSO"
|
||
-semanage.conf(5), semodule(8), semanage(8), getpwent(3), getpwent_r(3)
|
||
diff --git a/policycoreutils/semanage/default_encoding/Makefile b/policycoreutils/semanage/default_encoding/Makefile
|
||
new file mode 100644
|
||
index 0000000..e15a877
|
||
--- /dev/null
|
||
+++ b/policycoreutils/semanage/default_encoding/Makefile
|
||
@@ -0,0 +1,8 @@
|
||
+all:
|
||
+ LDFLAGS="" python setup.py build
|
||
+
|
||
+install: all
|
||
+ LDFLAGS="" python setup.py install --root=$(DESTDIR)/
|
||
+
|
||
+clean:
|
||
+ rm -rf build *~
|
||
diff --git a/policycoreutils/semanage/default_encoding/default_encoding.c b/policycoreutils/semanage/default_encoding/default_encoding.c
|
||
new file mode 100644
|
||
index 0000000..023b8f4
|
||
--- /dev/null
|
||
+++ b/policycoreutils/semanage/default_encoding/default_encoding.c
|
||
@@ -0,0 +1,57 @@
|
||
+/*
|
||
+ * Authors:
|
||
+ * John Dennis <jdennis@redhat.com>
|
||
+ *
|
||
+ * Copyright (C) 2009 Red Hat
|
||
+ * see file 'COPYING' for use and warranty information
|
||
+ *
|
||
+ * This program is free software; you can redistribute it and/or
|
||
+ * modify it under the terms of the GNU General Public License as
|
||
+ * published by the Free Software Foundation.
|
||
+ *
|
||
+ * This program is distributed in the hope that it will be useful,
|
||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
+ * GNU General Public License for more details.
|
||
+ *
|
||
+ * You should have received a copy of the GNU General Public License
|
||
+ * along with this program; if not, write to the Free Software
|
||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
+ */
|
||
+
|
||
+#include <Python.h>
|
||
+
|
||
+PyDoc_STRVAR(setdefaultencoding_doc,
|
||
+"setdefaultencoding(encoding='utf-8')\n\
|
||
+\n\
|
||
+Set the current default string encoding used by the Unicode implementation.\n\
|
||
+Defaults to utf-8."
|
||
+);
|
||
+
|
||
+static PyObject *
|
||
+setdefaultencoding(PyObject *self, PyObject *args, PyObject *kwds)
|
||
+{
|
||
+ static char *kwlist[] = {"utf-8", NULL};
|
||
+ char *encoding;
|
||
+
|
||
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:setdefaultencoding", kwlist, &encoding))
|
||
+ return NULL;
|
||
+
|
||
+ if (PyUnicode_SetDefaultEncoding(encoding))
|
||
+ return NULL;
|
||
+
|
||
+ Py_RETURN_NONE;
|
||
+}
|
||
+
|
||
+static PyMethodDef methods[] = {
|
||
+ {"setdefaultencoding", (PyCFunction)setdefaultencoding, METH_VARARGS|METH_KEYWORDS, setdefaultencoding_doc},
|
||
+ {NULL, NULL} /* sentinel */
|
||
+};
|
||
+
|
||
+
|
||
+PyMODINIT_FUNC
|
||
+initdefault_encoding_utf8(void)
|
||
+{
|
||
+ PyUnicode_SetDefaultEncoding("utf-8");
|
||
+ Py_InitModule3("default_encoding_utf8", methods, "Forces the default encoding to utf-8");
|
||
+}
|
||
diff --git a/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py
|
||
new file mode 100644
|
||
index 0000000..ccb6b8b
|
||
--- /dev/null
|
||
+++ b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py
|
||
@@ -0,0 +1,17 @@
|
||
+#
|
||
+# Copyright (C) 2006,2007,2008, 2009 Red Hat, Inc.
|
||
+#
|
||
+# This program is free software; you can redistribute it and/or modify
|
||
+# it under the terms of the GNU General Public License as published by
|
||
+# the Free Software Foundation; either version 2 of the License, or
|
||
+# (at your option) any later version.
|
||
+#
|
||
+# This program is distributed in the hope that it will be useful,
|
||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
+# GNU General Public License for more details.
|
||
+#
|
||
+# You should have received a copy of the GNU General Public License
|
||
+# along with this program; if not, write to the Free Software
|
||
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
+#
|
||
diff --git a/policycoreutils/semanage/default_encoding/setup.py b/policycoreutils/semanage/default_encoding/setup.py
|
||
new file mode 100644
|
||
index 0000000..e2befdb
|
||
--- /dev/null
|
||
+++ b/policycoreutils/semanage/default_encoding/setup.py
|
||
@@ -0,0 +1,38 @@
|
||
+# Authors:
|
||
+# John Dennis <jdennis@redhat.com>
|
||
+#
|
||
+# Copyright (C) 2009 Red Hat
|
||
+# see file 'COPYING' for use and warranty information
|
||
+#
|
||
+# This program is free software; you can redistribute it and/or
|
||
+# modify it under the terms of the GNU General Public License as
|
||
+# published by the Free Software Foundation.
|
||
+#
|
||
+# This program is distributed in the hope that it will be useful,
|
||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
+# GNU General Public License for more details.
|
||
+#
|
||
+# You should have received a copy of the GNU General Public License
|
||
+# along with this program; if not, write to the Free Software
|
||
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
+
|
||
+from distutils.core import setup, Extension
|
||
+
|
||
+default_encoding_utf8 = Extension('policycoreutils.default_encoding_utf8', ['default_encoding.c'])
|
||
+
|
||
+setup(name = 'policycoreutils-default-encoding',
|
||
+ version = '0.1',
|
||
+ description = 'Forces the default encoding in Python to be utf-8',
|
||
+ long_description = 'Forces the default encoding in Python to be utf-8',
|
||
+ author = 'John Dennis',
|
||
+ author_email = 'jdennis@redhat.com',
|
||
+ maintainer = 'John Dennis',
|
||
+ maintainer_email = 'jdennis@redhat.com',
|
||
+ license = 'GPLv3+',
|
||
+ platforms = 'posix',
|
||
+ url = '',
|
||
+ download_url = '',
|
||
+ ext_modules = [default_encoding_utf8],
|
||
+ packages=["policycoreutils"],
|
||
+)
|
||
diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage
|
||
index 6e33c85..49e4709 100644
|
||
--- a/policycoreutils/semanage/semanage
|
||
+++ b/policycoreutils/semanage/semanage
|
||
@@ -20,6 +20,7 @@
|
||
# 02111-1307 USA
|
||
#
|
||
#
|
||
+import policycoreutils.default_encoding_utf8
|
||
import sys, getopt, re
|
||
import seobject
|
||
import selinux
|
||
@@ -32,7 +33,7 @@ gettext.textdomain(PROGNAME)
|
||
try:
|
||
gettext.install(PROGNAME,
|
||
localedir="/usr/share/locale",
|
||
- unicode=False,
|
||
+ unicode=True,
|
||
codeset = 'utf-8')
|
||
except IOError:
|
||
import __builtin__
|
||
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
|
||
index 85bc37f..02b1acd 100644
|
||
--- a/policycoreutils/semanage/seobject.py
|
||
+++ b/policycoreutils/semanage/seobject.py
|
||
@@ -32,11 +32,10 @@ from IPy import IP
|
||
import gettext
|
||
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
|
||
gettext.textdomain(PROGNAME)
|
||
-try:
|
||
- gettext.install(PROGNAME, localedir = "/usr/share/locale", unicode = 1)
|
||
-except IOError:
|
||
- import __builtin__
|
||
- __builtin__.__dict__['_'] = unicode
|
||
+
|
||
+import gettext
|
||
+translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True)
|
||
+_=translation.ugettext
|
||
|
||
import syslog
|
||
|
||
@@ -461,7 +460,9 @@ class loginRecords(semanageRecords):
|
||
if rc < 0:
|
||
raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
||
if exists:
|
||
- raise ValueError(_("Login mapping for %s is already defined") % name)
|
||
+ semanage_seuser_key_free(k)
|
||
+ return self.__modify(name, sename, serange)
|
||
+
|
||
if name[0] == '%':
|
||
try:
|
||
grp.getgrnam(name[1:])
|
||
@@ -731,7 +732,8 @@ class seluserRecords(semanageRecords):
|
||
if rc < 0:
|
||
raise ValueError(_("Could not check if SELinux user %s is defined") % name)
|
||
if exists:
|
||
- raise ValueError(_("SELinux user %s is already defined") % name)
|
||
+ semanage_user_key_free(k)
|
||
+ return self.__modify(name, roles, selevel, serange, prefix)
|
||
|
||
(rc, u) = semanage_user_create(self.sh)
|
||
if rc < 0:
|
||
@@ -1274,7 +1276,8 @@ class nodeRecords(semanageRecords):
|
||
|
||
(rc, exists) = semanage_node_exists(self.sh, k)
|
||
if exists:
|
||
- raise ValueError(_("Addr %s already defined") % addr)
|
||
+ semanage_node_key_free(k)
|
||
+ return self.__modify(addr, mask, self.protocol[proto], serange, ctype)
|
||
|
||
(rc, node) = semanage_node_create(self.sh)
|
||
if rc < 0:
|
||
@@ -1475,7 +1478,8 @@ class interfaceRecords(semanageRecords):
|
||
if rc < 0:
|
||
raise ValueError(_("Could not check if interface %s is defined") % interface)
|
||
if exists:
|
||
- raise ValueError(_("Interface %s already defined") % interface)
|
||
+ semanage_iface_key_free(k)
|
||
+ return self.__modify(interface, serange, ctype)
|
||
|
||
(rc, iface) = semanage_iface_create(self.sh)
|
||
if rc < 0:
|
||
@@ -1777,7 +1781,8 @@ class fcontextRecords(semanageRecords):
|
||
raise ValueError(_("Could not check if file context for %s is defined") % target)
|
||
|
||
if exists:
|
||
- raise ValueError(_("File context for %s already defined") % target)
|
||
+ semanage_fcontext_key_free(k)
|
||
+ return self.__modify(target, type, ftype, serange, seuser)
|
||
|
||
(rc, fcontext) = semanage_fcontext_create(self.sh)
|
||
if rc < 0:
|
||
diff --git a/policycoreutils/semodule/Makefile b/policycoreutils/semodule/Makefile
|
||
index 4c5243a..036c418 100644
|
||
--- a/policycoreutils/semodule/Makefile
|
||
+++ b/policycoreutils/semodule/Makefile
|
||
@@ -11,7 +11,7 @@ LDLIBS = -lsepol -lselinux -lsemanage -L$(LIBDIR)
|
||
SEMODULE_OBJS = semodule.o
|
||
|
||
.PHONY: all semodule_path
|
||
-all: semodule semodule_path
|
||
+all: semodule semodule_path genhomedircon
|
||
|
||
semodule_path:
|
||
@echo -n $(SBINDIR) > ../scripts/semodule_path
|
||
@@ -19,11 +19,16 @@ semodule_path:
|
||
semodule: $(SEMODULE_OBJS)
|
||
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||
|
||
+genhomedircon:
|
||
+ ln -sf semodule genhomedircon
|
||
+
|
||
install: all
|
||
-mkdir -p $(SBINDIR)
|
||
install -m 755 semodule $(SBINDIR)
|
||
+ (cd $(SBINDIR); ln -sf semodule genhomedircon)
|
||
test -d $(MANDIR)/man8 || install -m 755 -d $(MANDIR)/man8
|
||
install -m 644 semodule.8 $(MANDIR)/man8/
|
||
+ install -m 644 genhomedircon.8 $(MANDIR)/man8/
|
||
|
||
relabel:
|
||
|
||
diff --git a/policycoreutils/semodule/genhomedircon.8 b/policycoreutils/semodule/genhomedircon.8
|
||
new file mode 100644
|
||
index 0000000..8ec509c
|
||
--- /dev/null
|
||
+++ b/policycoreutils/semodule/genhomedircon.8
|
||
@@ -0,0 +1,24 @@
|
||
+.TH GENHOMEDIRCON "12" "Sep 2011" "Security Enhanced Linux" "SELinux"
|
||
+.SH NAME
|
||
+genhomedircon \- generate SELinux file context configuration entries for user home directories
|
||
+.SH SYNOPSIS
|
||
+.B genhomedircon
|
||
+is a script that executes
|
||
+.B semodule
|
||
+to rebuild the currently active SELinux policy (without reloading it) and to create the
|
||
+labels for each user home directory based on directory paths returned by calls to getpwent().
|
||
+
|
||
+The latter functionality depends on the "usepasswd" parameter being set to "true" (default)
|
||
+in /etc/selinux/semanage.conf.
|
||
+
|
||
+This script is usually executed by
|
||
+.B semanage
|
||
+although this default behavior can be optionally modified by setting to "true" the
|
||
+"disable-genhomedircon" in /etc/selinux/semanage.conf.
|
||
+
|
||
+.SH AUTHOR
|
||
+This manual page was written by
|
||
+.I Dan Walsh <dwalsh@redhat.com>
|
||
+
|
||
+.SH "SEE ALSO"
|
||
+semanage.conf(5), semodule(8), semanage(8), getpwent(3), getpwent_r(3)
|
||
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
|
||
index 17b4fa5..6947b37 100644
|
||
--- a/policycoreutils/semodule/semodule.c
|
||
+++ b/policycoreutils/semodule/semodule.c
|
||
@@ -19,6 +19,7 @@
|
||
#include <sys/mman.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/types.h>
|
||
+#include <libgen.h>
|
||
|
||
#include <semanage/modules.h>
|
||
|
||
@@ -284,8 +285,12 @@ int main(int argc, char *argv[])
|
||
int i, commit = 0;
|
||
int result;
|
||
int status = EXIT_FAILURE;
|
||
-
|
||
+ char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" };
|
||
create_signal_handlers();
|
||
+ if (strcmp(basename(argv[0]), "genhomedircon") == 0) {
|
||
+ argc = 3;
|
||
+ argv=genhomedirconargv;
|
||
+ }
|
||
parse_command_line(argc, argv);
|
||
|
||
if (build)
|
||
diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
|
||
index 5e7415c..37cd5dd 100644
|
||
--- a/policycoreutils/sepolicy/sepolicy/__init__.py
|
||
+++ b/policycoreutils/sepolicy/sepolicy/__init__.py
|
||
@@ -145,10 +145,7 @@ def policy(policy_file):
|
||
raise ValueError(_("Failed to read %s policy file") % policy_file)
|
||
|
||
|
||
-policy_file = selinux.selinux_current_policy_path()
|
||
-if not policy_file:
|
||
- policy_file = __get_installed_policy()
|
||
-
|
||
+policy_file = __get_installed_policy()
|
||
try:
|
||
policy(policy_file)
|
||
except ValueError, e:
|
||
diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8
|
||
index 80b6d6e..07c5ee2 100644
|
||
--- a/policycoreutils/setfiles/restorecon.8
|
||
+++ b/policycoreutils/setfiles/restorecon.8
|
||
@@ -4,10 +4,10 @@ restorecon \- restore file(s) default SELinux security contexts.
|
||
|
||
.SH "SYNOPSIS"
|
||
.B restorecon
|
||
-.I [\-o outfilename] [\-R] [\-n] [\-p] [\-v] [\-e directory] pathname...
|
||
+.I [\-R] [\-n] [\-p] [\-v] [\-e directory] pathname...
|
||
.P
|
||
.B restorecon
|
||
-.I \-f infilename [\-o outfilename] [\-e directory] [\-R] [\-n] [\-p] [\-v] [\-F]
|
||
+.I \-f infilename [\-e directory] [\-R] [\-n] [\-p] [\-v] [\-F]
|
||
|
||
.SH "DESCRIPTION"
|
||
This manual page describes the
|
||
@@ -49,7 +49,7 @@ ignore files that do not exist.
|
||
don't change any file labels (passive check).
|
||
.TP
|
||
.B \-o outfilename
|
||
-save list of files with incorrect context in outfilename.
|
||
+Deprecated, SELinux policy will probably block this access. Use shell redirection to save list of files with incorrect context in filename.
|
||
.TP
|
||
.B \-p
|
||
show progress by printing * every STAR_COUNT files. (If you relabel the entire OS, this will show you the percentage complete.)
|
||
diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8
|
||
index 89d2a49..12bca43 100644
|
||
--- a/policycoreutils/setfiles/setfiles.8
|
||
+++ b/policycoreutils/setfiles/setfiles.8
|
||
@@ -4,7 +4,7 @@ setfiles \- set SELinux file security contexts.
|
||
|
||
.SH "SYNOPSIS"
|
||
.B setfiles
|
||
-.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-o filename] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname...
|
||
+.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname...
|
||
.SH "DESCRIPTION"
|
||
This manual page describes the
|
||
.BR setfiles
|
||
@@ -57,7 +57,7 @@ log changes in file labels to syslog.
|
||
don't change any file labels (passive check).
|
||
.TP
|
||
.B \-o filename
|
||
-save list of files with incorrect context in filename.
|
||
+Deprecated, SELinux policy will probably block this access. Use shell redirection to save list of files with incorrect context in filename.
|
||
.TP
|
||
.B \-p
|
||
show progress by printing * every STAR_COUNT files. (If you relabel the entire OS, this will show you the percentage complete.)
|
||
diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
|
||
index b11e49f..d3f02ae 100644
|
||
--- a/policycoreutils/setfiles/setfiles.c
|
||
+++ b/policycoreutils/setfiles/setfiles.c
|
||
@@ -45,14 +45,14 @@ void usage(const char *const name)
|
||
{
|
||
if (iamrestorecon) {
|
||
fprintf(stderr,
|
||
- "usage: %s [-iFnprRv0] [-e excludedir] [-o filename] pathname...\n"
|
||
- "usage: %s [-iFnprRv0] [-e excludedir] [-o filename] -f filename\n",
|
||
+ "usage: %s [-iFnprRv0] [-e excludedir] pathname...\n"
|
||
+ "usage: %s [-iFnprRv0] [-e excludedir] -f filename\n",
|
||
name, name);
|
||
} else {
|
||
fprintf(stderr,
|
||
- "usage: %s [-dilnpqvFW] [-e excludedir] [-o filename] [-r alt_root_path] spec_file pathname...\n"
|
||
- "usage: %s [-dilnpqvFW] [-e excludedir] [-o filename] [-r alt_root_path] spec_file -f filename\n"
|
||
- "usage: %s -s [-dilnpqvFW] [-o filename] spec_file\n"
|
||
+ "usage: %s [-dilnpqvFW] [-e excludedir] [-r alt_root_path] spec_file pathname...\n"
|
||
+ "usage: %s [-dilnpqvFW] [-e excludedir] [-r alt_root_path] spec_file -f filename\n"
|
||
+ "usage: %s -s [-dilnpqvFW] spec_file\n"
|
||
"usage: %s -c policyfile spec_file\n",
|
||
name, name, name, name);
|
||
}
|
||
diff --git a/sepolgen/src/sepolgen/audit.py b/sepolgen/src/sepolgen/audit.py
|
||
index d636091..9ca35a7 100644
|
||
--- a/sepolgen/src/sepolgen/audit.py
|
||
+++ b/sepolgen/src/sepolgen/audit.py
|
||
@@ -259,7 +259,7 @@ class AVCMessage(AuditMessage):
|
||
raise ValueError("Error during access vector computation")
|
||
|
||
if self.type == audit2why.CONSTRAINT:
|
||
- self.data = []
|
||
+ self.data = [ self.data ]
|
||
if self.scontext.user != self.tcontext.user:
|
||
self.data.append("user")
|
||
if self.scontext.role != self.tcontext.role and self.tcontext.role != "object_r":
|