aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h4
-rw-r--r--kernel/auditfilter.c40
-rw-r--r--kernel/auditsc.c12
-rw-r--r--security/selinux/include/audit.h65
4 files changed, 93 insertions, 28 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 04869c96016b..4ccb048cae1d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -377,8 +377,8 @@ struct audit_field {
377 u32 type; 377 u32 type;
378 u32 val; 378 u32 val;
379 u32 op; 379 u32 op;
380 char *se_str; 380 char *lsm_str;
381 void *se_rule; 381 void *lsm_rule;
382}; 382};
383 383
384#define AUDITSC_INVALID 0 384#define AUDITSC_INVALID 0
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 7c69cb5e44fb..28fef6bf8534 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -139,8 +139,8 @@ static inline void audit_free_rule(struct audit_entry *e)
139 if (e->rule.fields) 139 if (e->rule.fields)
140 for (i = 0; i < e->rule.field_count; i++) { 140 for (i = 0; i < e->rule.field_count; i++) {
141 struct audit_field *f = &e->rule.fields[i]; 141 struct audit_field *f = &e->rule.fields[i];
142 kfree(f->se_str); 142 kfree(f->lsm_str);
143 security_audit_rule_free(f->se_rule); 143 security_audit_rule_free(f->lsm_rule);
144 } 144 }
145 kfree(e->rule.fields); 145 kfree(e->rule.fields);
146 kfree(e->rule.filterkey); 146 kfree(e->rule.filterkey);
@@ -554,8 +554,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
554 f->op = data->fieldflags[i] & AUDIT_OPERATORS; 554 f->op = data->fieldflags[i] & AUDIT_OPERATORS;
555 f->type = data->fields[i]; 555 f->type = data->fields[i];
556 f->val = data->values[i]; 556 f->val = data->values[i];
557 f->se_str = NULL; 557 f->lsm_str = NULL;
558 f->se_rule = NULL; 558 f->lsm_rule = NULL;
559 switch(f->type) { 559 switch(f->type) {
560 case AUDIT_PID: 560 case AUDIT_PID:
561 case AUDIT_UID: 561 case AUDIT_UID:
@@ -598,7 +598,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
598 entry->rule.buflen += f->val; 598 entry->rule.buflen += f->val;
599 599
600 err = security_audit_rule_init(f->type, f->op, str, 600 err = security_audit_rule_init(f->type, f->op, str,
601 (void **)&f->se_rule); 601 (void **)&f->lsm_rule);
602 /* Keep currently invalid fields around in case they 602 /* Keep currently invalid fields around in case they
603 * become valid after a policy reload. */ 603 * become valid after a policy reload. */
604 if (err == -EINVAL) { 604 if (err == -EINVAL) {
@@ -610,7 +610,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
610 kfree(str); 610 kfree(str);
611 goto exit_free; 611 goto exit_free;
612 } else 612 } else
613 f->se_str = str; 613 f->lsm_str = str;
614 break; 614 break;
615 case AUDIT_WATCH: 615 case AUDIT_WATCH:
616 str = audit_unpack_string(&bufp, &remain, f->val); 616 str = audit_unpack_string(&bufp, &remain, f->val);
@@ -754,7 +754,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
754 case AUDIT_OBJ_LEV_LOW: 754 case AUDIT_OBJ_LEV_LOW:
755 case AUDIT_OBJ_LEV_HIGH: 755 case AUDIT_OBJ_LEV_HIGH:
756 data->buflen += data->values[i] = 756 data->buflen += data->values[i] =
757 audit_pack_string(&bufp, f->se_str); 757 audit_pack_string(&bufp, f->lsm_str);
758 break; 758 break;
759 case AUDIT_WATCH: 759 case AUDIT_WATCH:
760 data->buflen += data->values[i] = 760 data->buflen += data->values[i] =
@@ -806,7 +806,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
806 case AUDIT_OBJ_TYPE: 806 case AUDIT_OBJ_TYPE:
807 case AUDIT_OBJ_LEV_LOW: 807 case AUDIT_OBJ_LEV_LOW:
808 case AUDIT_OBJ_LEV_HIGH: 808 case AUDIT_OBJ_LEV_HIGH:
809 if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) 809 if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))
810 return 1; 810 return 1;
811 break; 811 break;
812 case AUDIT_WATCH: 812 case AUDIT_WATCH:
@@ -862,28 +862,28 @@ out:
862 return new; 862 return new;
863} 863}
864 864
865/* Duplicate LSM field information. The se_rule is opaque, so must be 865/* Duplicate LSM field information. The lsm_rule is opaque, so must be
866 * re-initialized. */ 866 * re-initialized. */
867static inline int audit_dupe_lsm_field(struct audit_field *df, 867static inline int audit_dupe_lsm_field(struct audit_field *df,
868 struct audit_field *sf) 868 struct audit_field *sf)
869{ 869{
870 int ret = 0; 870 int ret = 0;
871 char *se_str; 871 char *lsm_str;
872 872
873 /* our own copy of se_str */ 873 /* our own copy of lsm_str */
874 se_str = kstrdup(sf->se_str, GFP_KERNEL); 874 lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);
875 if (unlikely(!se_str)) 875 if (unlikely(!lsm_str))
876 return -ENOMEM; 876 return -ENOMEM;
877 df->se_str = se_str; 877 df->lsm_str = lsm_str;
878 878
879 /* our own (refreshed) copy of se_rule */ 879 /* our own (refreshed) copy of lsm_rule */
880 ret = security_audit_rule_init(df->type, df->op, df->se_str, 880 ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
881 (void **)&df->se_rule); 881 (void **)&df->lsm_rule);
882 /* Keep currently invalid fields around in case they 882 /* Keep currently invalid fields around in case they
883 * become valid after a policy reload. */ 883 * become valid after a policy reload. */
884 if (ret == -EINVAL) { 884 if (ret == -EINVAL) {
885 printk(KERN_WARNING "audit rule for LSM \'%s\' is " 885 printk(KERN_WARNING "audit rule for LSM \'%s\' is "
886 "invalid\n", df->se_str); 886 "invalid\n", df->lsm_str);
887 ret = 0; 887 ret = 0;
888 } 888 }
889 889
@@ -930,7 +930,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
930 new->tree = old->tree; 930 new->tree = old->tree;
931 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); 931 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
932 932
933 /* deep copy this information, updating the se_rule fields, because 933 /* deep copy this information, updating the lsm_rule fields, because
934 * the originals will all be freed when the old rule is freed. */ 934 * the originals will all be freed when the old rule is freed. */
935 for (i = 0; i < fcount; i++) { 935 for (i = 0; i < fcount; i++) {
936 switch (new->fields[i].type) { 936 switch (new->fields[i].type) {
@@ -1762,7 +1762,7 @@ unlock_and_return:
1762 return result; 1762 return result;
1763} 1763}
1764 1764
1765/* This function will re-initialize the se_rule field of all applicable rules. 1765/* This function will re-initialize the lsm_rule field of all applicable rules.
1766 * It will traverse the filter lists serarching for rules that contain LSM 1766 * It will traverse the filter lists serarching for rules that contain LSM
1767 * specific filter fields. When such a rule is found, it is copied, the 1767 * specific filter fields. When such a rule is found, it is copied, the
1768 * LSM field is re-initialized, and the old rule is replaced with the 1768 * LSM field is re-initialized, and the old rule is replaced with the
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index c0700535e5c5..56e56ed594a8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -527,14 +527,14 @@ static int audit_filter_rules(struct task_struct *tsk,
527 match for now to avoid losing information that 527 match for now to avoid losing information that
528 may be wanted. An error message will also be 528 may be wanted. An error message will also be
529 logged upon error */ 529 logged upon error */
530 if (f->se_rule) { 530 if (f->lsm_rule) {
531 if (need_sid) { 531 if (need_sid) {
532 security_task_getsecid(tsk, &sid); 532 security_task_getsecid(tsk, &sid);
533 need_sid = 0; 533 need_sid = 0;
534 } 534 }
535 result = security_audit_rule_match(sid, f->type, 535 result = security_audit_rule_match(sid, f->type,
536 f->op, 536 f->op,
537 f->se_rule, 537 f->lsm_rule,
538 ctx); 538 ctx);
539 } 539 }
540 break; 540 break;
@@ -545,18 +545,18 @@ static int audit_filter_rules(struct task_struct *tsk,
545 case AUDIT_OBJ_LEV_HIGH: 545 case AUDIT_OBJ_LEV_HIGH:
546 /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR 546 /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
547 also applies here */ 547 also applies here */
548 if (f->se_rule) { 548 if (f->lsm_rule) {
549 /* Find files that match */ 549 /* Find files that match */
550 if (name) { 550 if (name) {
551 result = security_audit_rule_match( 551 result = security_audit_rule_match(
552 name->osid, f->type, f->op, 552 name->osid, f->type, f->op,
553 f->se_rule, ctx); 553 f->lsm_rule, ctx);
554 } else if (ctx) { 554 } else if (ctx) {
555 for (j = 0; j < ctx->name_count; j++) { 555 for (j = 0; j < ctx->name_count; j++) {
556 if (security_audit_rule_match( 556 if (security_audit_rule_match(
557 ctx->names[j].osid, 557 ctx->names[j].osid,
558 f->type, f->op, 558 f->type, f->op,
559 f->se_rule, ctx)) { 559 f->lsm_rule, ctx)) {
560 ++result; 560 ++result;
561 break; 561 break;
562 } 562 }
@@ -569,7 +569,7 @@ static int audit_filter_rules(struct task_struct *tsk,
569 aux = aux->next) { 569 aux = aux->next) {
570 if (aux->type == AUDIT_IPC) { 570 if (aux->type == AUDIT_IPC) {
571 struct audit_aux_data_ipcctl *axi = (void *)aux; 571 struct audit_aux_data_ipcctl *axi = (void *)aux;
572 if (security_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) { 572 if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) {
573 ++result; 573 ++result;
574 break; 574 break;
575 } 575 }
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
new file mode 100644
index 000000000000..6c8b9ef15579
--- /dev/null
+++ b/security/selinux/include/audit.h
@@ -0,0 +1,65 @@
1/*
2 * SELinux support for the Audit LSM hooks
3 *
4 * Most of below header was moved from include/linux/selinux.h which
5 * is released under below copyrights:
6 *
7 * Author: James Morris <jmorris@redhat.com>
8 *
9 * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com>
10 * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
11 * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2,
15 * as published by the Free Software Foundation.
16 */
17
18#ifndef _SELINUX_AUDIT_H
19#define _SELINUX_AUDIT_H
20
21/**
22 * selinux_audit_rule_init - alloc/init an selinux audit rule structure.
23 * @field: the field this rule refers to
24 * @op: the operater the rule uses
25 * @rulestr: the text "target" of the rule
26 * @rule: pointer to the new rule structure returned via this
27 *
28 * Returns 0 if successful, -errno if not. On success, the rule structure
29 * will be allocated internally. The caller must free this structure with
30 * selinux_audit_rule_free() after use.
31 */
32int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
33
34/**
35 * selinux_audit_rule_free - free an selinux audit rule structure.
36 * @rule: pointer to the audit rule to be freed
37 *
38 * This will free all memory associated with the given rule.
39 * If @rule is NULL, no operation is performed.
40 */
41void selinux_audit_rule_free(void *rule);
42
43/**
44 * selinux_audit_rule_match - determine if a context ID matches a rule.
45 * @sid: the context ID to check
46 * @field: the field this rule refers to
47 * @op: the operater the rule uses
48 * @rule: pointer to the audit rule to check against
49 * @actx: the audit context (can be NULL) associated with the check
50 *
51 * Returns 1 if the context id matches the rule, 0 if it does not, and
52 * -errno on failure.
53 */
54int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule,
55 struct audit_context *actx);
56
57/**
58 * selinux_audit_rule_known - check to see if rule contains selinux fields.
59 * @rule: rule to be checked
60 * Returns 1 if there are selinux fields specified in the rule, 0 otherwise.
61 */
62int selinux_audit_rule_known(struct audit_krule *krule);
63
64#endif /* _SELINUX_AUDIT_H */
65