forked from Minki/linux
Audit: internally use the new LSM audit hooks
Convert Audit to use the new LSM Audit hooks instead of the exported SELinux interface. Basically, use: security_audit_rule_init secuirty_audit_rule_free security_audit_rule_known security_audit_rule_match instad of (respectively) : selinux_audit_rule_init selinux_audit_rule_free audit_rule_has_selinux selinux_audit_rule_match Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com> Acked-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
03d37d25e0
commit
d7a96f3a1a
@ -21,7 +21,7 @@
|
||||
*
|
||||
* Written by Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
* Goals: 1) Integrate fully with SELinux.
|
||||
* Goals: 1) Integrate fully with Security Modules.
|
||||
* 2) Minimal run-time overhead:
|
||||
* a) Minimal when syscall auditing is disabled (audit_enable=0).
|
||||
* b) Small when syscall auditing is enabled and no audit record
|
||||
@ -55,7 +55,6 @@
|
||||
#include <net/netlink.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/selinux.h>
|
||||
#include <linux/inotify.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/tty.h>
|
||||
@ -882,10 +881,6 @@ static int __init audit_init(void)
|
||||
audit_enabled = audit_default;
|
||||
audit_ever_enabled |= !!audit_default;
|
||||
|
||||
/* Register the callback with selinux. This callback will be invoked
|
||||
* when a new policy is loaded. */
|
||||
selinux_audit_set_callback(&selinux_audit_rule_update);
|
||||
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
|
||||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/inotify.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/selinux.h>
|
||||
#include "audit.h"
|
||||
|
||||
/*
|
||||
@ -39,7 +38,7 @@
|
||||
* Synchronizes writes and blocking reads of audit's filterlist
|
||||
* data. Rcu is used to traverse the filterlist and access
|
||||
* contents of structs audit_entry, audit_watch and opaque
|
||||
* selinux rules during filtering. If modified, these structures
|
||||
* LSM rules during filtering. If modified, these structures
|
||||
* must be copied and replace their counterparts in the filterlist.
|
||||
* An audit_parent struct is not accessed during filtering, so may
|
||||
* be written directly provided audit_filter_mutex is held.
|
||||
@ -141,7 +140,7 @@ static inline void audit_free_rule(struct audit_entry *e)
|
||||
for (i = 0; i < e->rule.field_count; i++) {
|
||||
struct audit_field *f = &e->rule.fields[i];
|
||||
kfree(f->se_str);
|
||||
selinux_audit_rule_free(f->se_rule);
|
||||
security_audit_rule_free(f->se_rule);
|
||||
}
|
||||
kfree(e->rule.fields);
|
||||
kfree(e->rule.filterkey);
|
||||
@ -598,12 +597,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
||||
goto exit_free;
|
||||
entry->rule.buflen += f->val;
|
||||
|
||||
err = selinux_audit_rule_init(f->type, f->op, str,
|
||||
&f->se_rule);
|
||||
err = security_audit_rule_init(f->type, f->op, str,
|
||||
(void **)&f->se_rule);
|
||||
/* Keep currently invalid fields around in case they
|
||||
* become valid after a policy reload. */
|
||||
if (err == -EINVAL) {
|
||||
printk(KERN_WARNING "audit rule for selinux "
|
||||
printk(KERN_WARNING "audit rule for LSM "
|
||||
"\'%s\' is invalid\n", str);
|
||||
err = 0;
|
||||
}
|
||||
@ -863,9 +862,9 @@ out:
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Duplicate selinux field information. The se_rule is opaque, so must be
|
||||
/* Duplicate LSM field information. The se_rule is opaque, so must be
|
||||
* re-initialized. */
|
||||
static inline int audit_dupe_selinux_field(struct audit_field *df,
|
||||
static inline int audit_dupe_lsm_field(struct audit_field *df,
|
||||
struct audit_field *sf)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -878,12 +877,12 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
|
||||
df->se_str = se_str;
|
||||
|
||||
/* our own (refreshed) copy of se_rule */
|
||||
ret = selinux_audit_rule_init(df->type, df->op, df->se_str,
|
||||
&df->se_rule);
|
||||
ret = security_audit_rule_init(df->type, df->op, df->se_str,
|
||||
(void **)&df->se_rule);
|
||||
/* Keep currently invalid fields around in case they
|
||||
* become valid after a policy reload. */
|
||||
if (ret == -EINVAL) {
|
||||
printk(KERN_WARNING "audit rule for selinux \'%s\' is "
|
||||
printk(KERN_WARNING "audit rule for LSM \'%s\' is "
|
||||
"invalid\n", df->se_str);
|
||||
ret = 0;
|
||||
}
|
||||
@ -892,7 +891,7 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
|
||||
}
|
||||
|
||||
/* Duplicate an audit rule. This will be a deep copy with the exception
|
||||
* of the watch - that pointer is carried over. The selinux specific fields
|
||||
* of the watch - that pointer is carried over. The LSM specific fields
|
||||
* will be updated in the copy. The point is to be able to replace the old
|
||||
* rule with the new rule in the filterlist, then free the old rule.
|
||||
* The rlist element is undefined; list manipulations are handled apart from
|
||||
@ -945,7 +944,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
|
||||
case AUDIT_OBJ_TYPE:
|
||||
case AUDIT_OBJ_LEV_LOW:
|
||||
case AUDIT_OBJ_LEV_HIGH:
|
||||
err = audit_dupe_selinux_field(&new->fields[i],
|
||||
err = audit_dupe_lsm_field(&new->fields[i],
|
||||
&old->fields[i]);
|
||||
break;
|
||||
case AUDIT_FILTERKEY:
|
||||
@ -1763,38 +1762,12 @@ unlock_and_return:
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Check to see if the rule contains any selinux fields. Returns 1 if there
|
||||
are selinux fields specified in the rule, 0 otherwise. */
|
||||
static inline int audit_rule_has_selinux(struct audit_krule *rule)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rule->field_count; i++) {
|
||||
struct audit_field *f = &rule->fields[i];
|
||||
switch (f->type) {
|
||||
case AUDIT_SUBJ_USER:
|
||||
case AUDIT_SUBJ_ROLE:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function will re-initialize the se_rule field of all applicable rules.
|
||||
* It will traverse the filter lists serarching for rules that contain selinux
|
||||
* It will traverse the filter lists serarching for rules that contain LSM
|
||||
* specific filter fields. When such a rule is found, it is copied, the
|
||||
* selinux field is re-initialized, and the old rule is replaced with the
|
||||
* LSM field is re-initialized, and the old rule is replaced with the
|
||||
* updated rule. */
|
||||
int selinux_audit_rule_update(void)
|
||||
int audit_update_lsm_rules(void)
|
||||
{
|
||||
struct audit_entry *entry, *n, *nentry;
|
||||
struct audit_watch *watch;
|
||||
@ -1806,7 +1779,7 @@ int selinux_audit_rule_update(void)
|
||||
|
||||
for (i = 0; i < AUDIT_NR_FILTERS; i++) {
|
||||
list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
|
||||
if (!audit_rule_has_selinux(&entry->rule))
|
||||
if (!security_audit_rule_known(&entry->rule))
|
||||
continue;
|
||||
|
||||
watch = entry->rule.watch;
|
||||
@ -1817,7 +1790,7 @@ int selinux_audit_rule_update(void)
|
||||
* return value */
|
||||
if (!err)
|
||||
err = PTR_ERR(nentry);
|
||||
audit_panic("error updating selinux filters");
|
||||
audit_panic("error updating LSM filters");
|
||||
if (watch)
|
||||
list_del(&entry->rule.rlist);
|
||||
list_del_rcu(&entry->list);
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/selinux.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/syscalls.h>
|
||||
@ -533,7 +532,7 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
security_task_getsecid(tsk, &sid);
|
||||
need_sid = 0;
|
||||
}
|
||||
result = selinux_audit_rule_match(sid, f->type,
|
||||
result = security_audit_rule_match(sid, f->type,
|
||||
f->op,
|
||||
f->se_rule,
|
||||
ctx);
|
||||
@ -549,12 +548,12 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
if (f->se_rule) {
|
||||
/* Find files that match */
|
||||
if (name) {
|
||||
result = selinux_audit_rule_match(
|
||||
result = security_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(
|
||||
if (security_audit_rule_match(
|
||||
ctx->names[j].osid,
|
||||
f->type, f->op,
|
||||
f->se_rule, ctx)) {
|
||||
@ -570,7 +569,7 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
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)) {
|
||||
if (security_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
|
||||
++result;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user