libsepol,libselinux,audit2allow: teach audit2why about type bounds failures
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>
This commit is contained in:
parent
fff90bd22b
commit
7e09f584e1
4 changed files with 86 additions and 8 deletions
|
@ -28,6 +28,7 @@
|
|||
#define BOOLEAN 3
|
||||
#define CONSTRAINT 4
|
||||
#define RBAC 5
|
||||
#define BOUNDS 6
|
||||
|
||||
struct boolean_t {
|
||||
char *name;
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -824,6 +824,67 @@ out:
|
|||
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.
|
||||
|
@ -860,6 +921,7 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
|||
avd->auditallow = 0;
|
||||
avd->auditdeny = 0xffffffff;
|
||||
avd->seqno = latest_granting;
|
||||
if (reason)
|
||||
*reason = 0;
|
||||
|
||||
/*
|
||||
|
@ -899,6 +961,7 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
|||
}
|
||||
|
||||
if (requested & ~avd->allowed) {
|
||||
if (reason)
|
||||
*reason |= SEPOL_COMPUTEAV_TE;
|
||||
requested &= avd->allowed;
|
||||
}
|
||||
|
@ -919,6 +982,7 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
|||
}
|
||||
|
||||
if (requested & ~avd->allowed) {
|
||||
if (reason)
|
||||
*reason |= SEPOL_COMPUTEAV_CONS;
|
||||
requested &= avd->allowed;
|
||||
}
|
||||
|
@ -942,10 +1006,13 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
|||
}
|
||||
|
||||
if (requested & ~avd->allowed) {
|
||||
if (reason)
|
||||
*reason |= SEPOL_COMPUTEAV_RBAC;
|
||||
requested &= avd->allowed;
|
||||
}
|
||||
|
||||
type_attribute_bounds_av(scontext, tcontext, tclass, requested, avd,
|
||||
reason);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue