aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-06-24 00:02:38 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-24 00:02:38 -0400
commit916d75761c971b6e630a26bd4ba472e90ac9a4b9 (patch)
tree3a4b18d0d29c1d12f64fefbb2bc5559813a686f7 /kernel/auditsc.c
parent9d9609851003ebed15957f0f2ce18492739ee124 (diff)
Fix rule eviction order for AUDIT_DIR
If syscall removes the root of subtree being watched, we definitely do not want the rules refering that subtree to be destroyed without the syscall in question having a chance to match them. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2de95d1582bc..68d3c6a0ecd6 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -199,6 +199,7 @@ struct audit_context {
199 199
200 struct audit_tree_refs *trees, *first_trees; 200 struct audit_tree_refs *trees, *first_trees;
201 int tree_count; 201 int tree_count;
202 struct list_head killed_trees;
202 203
203 int type; 204 int type;
204 union { 205 union {
@@ -853,6 +854,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state)
853 if (!(context = kmalloc(sizeof(*context), GFP_KERNEL))) 854 if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
854 return NULL; 855 return NULL;
855 audit_zero_context(context, state); 856 audit_zero_context(context, state);
857 INIT_LIST_HEAD(&context->killed_trees);
856 return context; 858 return context;
857} 859}
858 860
@@ -1545,6 +1547,8 @@ void audit_free(struct task_struct *tsk)
1545 /* that can happen only if we are called from do_exit() */ 1547 /* that can happen only if we are called from do_exit() */
1546 if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) 1548 if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
1547 audit_log_exit(context, tsk); 1549 audit_log_exit(context, tsk);
1550 if (!list_empty(&context->killed_trees))
1551 audit_kill_trees(&context->killed_trees);
1548 1552
1549 audit_free_context(context); 1553 audit_free_context(context);
1550} 1554}
@@ -1688,6 +1692,9 @@ void audit_syscall_exit(int valid, long return_code)
1688 context->in_syscall = 0; 1692 context->in_syscall = 0;
1689 context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; 1693 context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
1690 1694
1695 if (!list_empty(&context->killed_trees))
1696 audit_kill_trees(&context->killed_trees);
1697
1691 if (context->previous) { 1698 if (context->previous) {
1692 struct audit_context *new_context = context->previous; 1699 struct audit_context *new_context = context->previous;
1693 context->previous = NULL; 1700 context->previous = NULL;
@@ -2521,3 +2528,11 @@ void audit_core_dumps(long signr)
2521 audit_log_format(ab, " sig=%ld", signr); 2528 audit_log_format(ab, " sig=%ld", signr);
2522 audit_log_end(ab); 2529 audit_log_end(ab);
2523} 2530}
2531
2532struct list_head *audit_killed_trees(void)
2533{
2534 struct audit_context *ctx = current->audit_context;
2535 if (likely(!ctx || !ctx->in_syscall))
2536 return NULL;
2537 return &ctx->killed_trees;
2538}