Skip to content

Commit

Permalink
libsepol,libselinux,audit2allow: teach audit2why about type bounds fa…
Browse files Browse the repository at this point in the history
…ilures

Teach audit2why to recognize type bounds failures.  This required
updating libsepol sepol_compute_av_reason() to identify bounds
failures, and updating libsepol context_struct_compute_av() to
include the type bounds logic from the kernel.

This could potentially be further augmented to provide more detailed
reporting via the reason buffer to include information similar to
what security_dump_masked_av() reports in the kernel.  However, it
is unclear if this is needed.  It is already possible to get type
bounds checking at policy build time by enabling expand-check=1
in /etc/selinux/semanage.conf (or by default when compiling
monolithic policy).

Before:
type=AVC msg=audit(1480451925.038:3225): avc:  denied  { getattr } for  pid=7118 comm="chmod" path="/home/sds/selinux-testsuite/tests/bounds/bounds_file_blue" dev="dm-2" ino=23337697 scontext=unconfined_u:unconfined_r:test_bounds_child_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_bounds_file_blue_t:s0 tclass=file permissive=0

	Was caused by:
		Unknown - would be allowed by active policy
		Possible mismatch between this policy and the one under which the audit message was generated.

		Possible mismatch between current in-memory boolean settings vs. permanent ones.

After:
type=AVC msg=audit(1480451925.038:3225): avc:  denied  { getattr } for  pid=7118 comm="chmod" path="/home/sds/selinux-testsuite/tests/bounds/bounds_file_blue" dev="dm-2" ino=23337697 scontext=unconfined_u:unconfined_r:test_bounds_child_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_bounds_file_blue_t:s0 tclass=file permissive=0
        Was caused by:
                Typebounds violation.

                Add an allow rule for the parent type.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
  • Loading branch information
stephensmalley committed Nov 29, 2016
1 parent fff90bd commit 7e09f58
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
5 changes: 5 additions & 0 deletions libselinux/src/audit2why.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define BOOLEAN 3
#define CONSTRAINT 4
#define RBAC 5
#define BOUNDS 6

struct boolean_t {
char *name;
Expand Down Expand Up @@ -425,6 +426,9 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
if (reason & SEPOL_COMPUTEAV_RBAC)
RETURN(RBAC)

if (reason & SEPOL_COMPUTEAV_BOUNDS)
RETURN(BOUNDS)

RETURN(BADCOMPUTE)
}

Expand Down Expand Up @@ -481,6 +485,7 @@ PyMODINIT_FUNC initaudit2why(void)
PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN);
PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT);
PyModule_AddIntConstant(m,"RBAC", RBAC);
PyModule_AddIntConstant(m,"BOUNDS", BOUNDS);

#if PY_MAJOR_VERSION >= 3
return m;
Expand Down
7 changes: 4 additions & 3 deletions libsepol/include/sepol/policydb/services.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ extern int sepol_compute_av(sepol_security_id_t ssid, /* IN */

/* Same as above, but also return the reason(s) for any
denials of the requested permissions. */
#define SEPOL_COMPUTEAV_TE 1
#define SEPOL_COMPUTEAV_CONS 2
#define SEPOL_COMPUTEAV_RBAC 4
#define SEPOL_COMPUTEAV_TE 0x1U
#define SEPOL_COMPUTEAV_CONS 0x2U
#define SEPOL_COMPUTEAV_RBAC 0x4U
#define SEPOL_COMPUTEAV_BOUNDS 0x8U
extern int sepol_compute_av_reason(sepol_security_id_t ssid,
sepol_security_id_t tsid,
sepol_security_class_t tclass,
Expand Down
77 changes: 72 additions & 5 deletions libsepol/src/services.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,67 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
return rc;
}

/* Forward declaration */
static int context_struct_compute_av(context_struct_t * scontext,
context_struct_t * tcontext,
sepol_security_class_t tclass,
sepol_access_vector_t requested,
struct sepol_av_decision *avd,
unsigned int *reason,
char **r_buf,
unsigned int flags);

static void type_attribute_bounds_av(context_struct_t *scontext,
context_struct_t *tcontext,
sepol_security_class_t tclass,
sepol_access_vector_t requested,
struct sepol_av_decision *avd,
unsigned int *reason)
{
context_struct_t lo_scontext;
context_struct_t lo_tcontext, *tcontextp = tcontext;
struct sepol_av_decision lo_avd;
type_datum_t *source;
type_datum_t *target;
sepol_access_vector_t masked = 0;

source = policydb->type_val_to_struct[scontext->type - 1];
if (!source->bounds)
return;

target = policydb->type_val_to_struct[tcontext->type - 1];

memset(&lo_avd, 0, sizeof(lo_avd));

memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
lo_scontext.type = source->bounds;

if (target->bounds) {
memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext));
lo_tcontext.type = target->bounds;
tcontextp = &lo_tcontext;
}

context_struct_compute_av(&lo_scontext,
tcontextp,
tclass,
requested,
&lo_avd,
NULL, /* reason intentionally omitted */
NULL,
0);

masked = ~lo_avd.allowed & avd->allowed;

if (!masked)
return; /* no masked permission */

/* mask violated permissions */
avd->allowed &= ~masked;

*reason |= SEPOL_COMPUTEAV_BOUNDS;
}

/*
* Compute access vectors based on a context structure pair for
* the permissions in a particular class.
Expand All @@ -835,7 +896,7 @@ static int context_struct_compute_av(context_struct_t * scontext,
struct sepol_av_decision *avd,
unsigned int *reason,
char **r_buf,
unsigned int flags)
unsigned int flags)
{
constraint_node_t *constraint;
struct role_allow *ra;
Expand All @@ -860,7 +921,8 @@ static int context_struct_compute_av(context_struct_t * scontext,
avd->auditallow = 0;
avd->auditdeny = 0xffffffff;
avd->seqno = latest_granting;
*reason = 0;
if (reason)
*reason = 0;

/*
* If a specific type enforcement rule was defined for
Expand Down Expand Up @@ -899,7 +961,8 @@ static int context_struct_compute_av(context_struct_t * scontext,
}

if (requested & ~avd->allowed) {
*reason |= SEPOL_COMPUTEAV_TE;
if (reason)
*reason |= SEPOL_COMPUTEAV_TE;
requested &= avd->allowed;
}

Expand All @@ -919,7 +982,8 @@ static int context_struct_compute_av(context_struct_t * scontext,
}

if (requested & ~avd->allowed) {
*reason |= SEPOL_COMPUTEAV_CONS;
if (reason)
*reason |= SEPOL_COMPUTEAV_CONS;
requested &= avd->allowed;
}

Expand All @@ -942,10 +1006,13 @@ static int context_struct_compute_av(context_struct_t * scontext,
}

if (requested & ~avd->allowed) {
*reason |= SEPOL_COMPUTEAV_RBAC;
if (reason)
*reason |= SEPOL_COMPUTEAV_RBAC;
requested &= avd->allowed;
}

type_attribute_bounds_av(scontext, tcontext, tclass, requested, avd,
reason);
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions python/audit2allow/audit2allow
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ class AuditToPolicy:
print("\t\tAdd an allow rule for the role pair.\n")
continue

if rc == audit2why.BOUNDS:
print("\t\tTypebounds violation.\n")
print("\t\tAdd an allow rule for the parent type.\n")
continue

audit2why.finish()
return

Expand Down

0 comments on commit 7e09f58

Please sign in to comment.