[PATCH] audit: support for object context filters
authorDarrel Goeddel <dgoeddel@trustedcs.com>
Thu, 29 Jun 2006 21:57:08 +0000 (16:57 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 1 Jul 2006 09:44:19 +0000 (05:44 -0400)
This patch introduces object audit filters based on the elements
of the SELinux context.

Signed-off-by: Darrel Goeddel <dgoeddel@trustedcs.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
 kernel/auditfilter.c           |   25 +++++++++++++++++++++++++
 kernel/auditsc.c               |   40 ++++++++++++++++++++++++++++++++++++++++
 security/selinux/ss/services.c |   18 +++++++++++++++++-
 3 files changed, 82 insertions(+), 1 deletion(-)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
kernel/auditfilter.c
kernel/auditsc.c
security/selinux/ss/services.c

index 40a9931a13e2859eaaf256ed2740acacd7ba5048..7f2ea8b84a2723ca92ba90b1bb8abfab7f731960 100644 (file)
@@ -475,6 +475,11 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                case AUDIT_SUBJ_TYPE:
                case AUDIT_SUBJ_SEN:
                case AUDIT_SUBJ_CLR:
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
                        str = audit_unpack_string(&bufp, &remain, f->val);
                        if (IS_ERR(str))
                                goto exit_free;
@@ -616,6 +621,11 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
                case AUDIT_SUBJ_TYPE:
                case AUDIT_SUBJ_SEN:
                case AUDIT_SUBJ_CLR:
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
                        data->buflen += data->values[i] =
                                audit_pack_string(&bufp, f->se_str);
                        break;
@@ -659,6 +669,11 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
                case AUDIT_SUBJ_TYPE:
                case AUDIT_SUBJ_SEN:
                case AUDIT_SUBJ_CLR:
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
                        if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
                                return 1;
                        break;
@@ -779,6 +794,11 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
                case AUDIT_SUBJ_TYPE:
                case AUDIT_SUBJ_SEN:
                case AUDIT_SUBJ_CLR:
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
                        err = audit_dupe_selinux_field(&new->fields[i],
                                                       &old->fields[i]);
                        break;
@@ -1542,6 +1562,11 @@ static inline int audit_rule_has_selinux(struct audit_krule *rule)
                case AUDIT_SUBJ_TYPE:
                case AUDIT_SUBJ_SEN:
                case AUDIT_SUBJ_CLR:
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
                        return 1;
                }
        }
index 1d24fade17e62addb00c8869848040b7dff72db6..ae40ac8c39e7246c5d2b11c96429073f6daffbc0 100644 (file)
@@ -342,6 +342,46 @@ static int audit_filter_rules(struct task_struct *tsk,
                                                                  ctx);
                        }
                        break;
+               case AUDIT_OBJ_USER:
+               case AUDIT_OBJ_ROLE:
+               case AUDIT_OBJ_TYPE:
+               case AUDIT_OBJ_LEV_LOW:
+               case AUDIT_OBJ_LEV_HIGH:
+                       /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
+                          also applies here */
+                       if (f->se_rule) {
+                               /* Find files that match */
+                               if (name) {
+                                       result = selinux_audit_rule_match(
+                                                  name->osid, f->type, f->op,
+                                                  f->se_rule, ctx);
+                               } else if (ctx) {
+                                       for (j = 0; j < ctx->name_count; j++) {
+                                               if (selinux_audit_rule_match(
+                                                     ctx->names[j].osid,
+                                                     f->type, f->op,
+                                                     f->se_rule, ctx)) {
+                                                       ++result;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               /* Find ipc objects that match */
+                               if (ctx) {
+                                       struct audit_aux_data *aux;
+                                       for (aux = ctx->aux; aux;
+                                            aux = aux->next) {
+                                               if (aux->type == AUDIT_IPC) {
+                                                       struct audit_aux_data_ipcctl *axi = (void *)aux;
+                                                       if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
+                                                               ++result;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       break;
                case AUDIT_ARG0:
                case AUDIT_ARG1:
                case AUDIT_ARG2:
index 92e80b99d1839ca5b455266b29c2c08d0fbd8c08..d2e80e62ff0c9595414f38d00e3d5e49487cb77d 100644 (file)
@@ -1848,12 +1848,17 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
        case AUDIT_SUBJ_USER:
        case AUDIT_SUBJ_ROLE:
        case AUDIT_SUBJ_TYPE:
+       case AUDIT_OBJ_USER:
+       case AUDIT_OBJ_ROLE:
+       case AUDIT_OBJ_TYPE:
                /* only 'equals' and 'not equals' fit user, role, and type */
                if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
                        return -EINVAL;
                break;
        case AUDIT_SUBJ_SEN:
        case AUDIT_SUBJ_CLR:
+       case AUDIT_OBJ_LEV_LOW:
+       case AUDIT_OBJ_LEV_HIGH:
                /* we do not allow a range, indicated by the presense of '-' */
                if (strchr(rulestr, '-'))
                        return -EINVAL;
@@ -1875,6 +1880,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
 
        switch (field) {
        case AUDIT_SUBJ_USER:
+       case AUDIT_OBJ_USER:
                userdatum = hashtab_search(policydb.p_users.table, rulestr);
                if (!userdatum)
                        rc = -EINVAL;
@@ -1882,6 +1888,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
                        tmprule->au_ctxt.user = userdatum->value;
                break;
        case AUDIT_SUBJ_ROLE:
+       case AUDIT_OBJ_ROLE:
                roledatum = hashtab_search(policydb.p_roles.table, rulestr);
                if (!roledatum)
                        rc = -EINVAL;
@@ -1889,6 +1896,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
                        tmprule->au_ctxt.role = roledatum->value;
                break;
        case AUDIT_SUBJ_TYPE:
+       case AUDIT_OBJ_TYPE:
                typedatum = hashtab_search(policydb.p_types.table, rulestr);
                if (!typedatum)
                        rc = -EINVAL;
@@ -1897,6 +1905,8 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
                break;
        case AUDIT_SUBJ_SEN:
        case AUDIT_SUBJ_CLR:
+       case AUDIT_OBJ_LEV_LOW:
+       case AUDIT_OBJ_LEV_HIGH:
                rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
                break;
        }
@@ -1949,6 +1959,7 @@ int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
           without a match */
        switch (field) {
        case AUDIT_SUBJ_USER:
+       case AUDIT_OBJ_USER:
                switch (op) {
                case AUDIT_EQUAL:
                        match = (ctxt->user == rule->au_ctxt.user);
@@ -1959,6 +1970,7 @@ int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
                }
                break;
        case AUDIT_SUBJ_ROLE:
+       case AUDIT_OBJ_ROLE:
                switch (op) {
                case AUDIT_EQUAL:
                        match = (ctxt->role == rule->au_ctxt.role);
@@ -1969,6 +1981,7 @@ int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
                }
                break;
        case AUDIT_SUBJ_TYPE:
+       case AUDIT_OBJ_TYPE:
                switch (op) {
                case AUDIT_EQUAL:
                        match = (ctxt->type == rule->au_ctxt.type);
@@ -1980,7 +1993,10 @@ int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
                break;
        case AUDIT_SUBJ_SEN:
        case AUDIT_SUBJ_CLR:
-               level = (field == AUDIT_SUBJ_SEN ?
+       case AUDIT_OBJ_LEV_LOW:
+       case AUDIT_OBJ_LEV_HIGH:
+               level = ((field == AUDIT_SUBJ_SEN ||
+                         field == AUDIT_OBJ_LEV_LOW) ?
                         &ctxt->range.level[0] : &ctxt->range.level[1]);
                switch (op) {
                case AUDIT_EQUAL: