diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-07-13 22:47:07 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-07-13 22:47:07 +0100 |
commit | f55619642e863990d5a46cf2c2c840170d22a9f9 (patch) | |
tree | faf2447562a26c4620d254fd1b46f3ae7e6fc678 | |
parent | 582edda586120004d0fb67113115fa442a0a1571 (diff) | |
download | lwn-f55619642e863990d5a46cf2c2c840170d22a9f9.tar.gz lwn-f55619642e863990d5a46cf2c2c840170d22a9f9.zip |
AUDIT: Avoid scheduling in idle thread
When we flush a pending syscall audit record due to audit_free(), we
might be doing that in the context of the idle thread. So use GFP_ATOMIC
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | kernel/auditsc.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 86d91fe2d93a..517b253f1efe 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -41,6 +41,7 @@ #include <linux/time.h> #include <linux/kthread.h> #include <linux/netlink.h> +#include <linux/compiler.h> #include <asm/unistd.h> /* 0 = no checking @@ -778,13 +779,13 @@ static void audit_log_task_info(struct audit_buffer *ab) up_read(&mm->mmap_sem); } -static void audit_log_exit(struct audit_context *context) +static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask) { int i; struct audit_buffer *ab; struct audit_aux_data *aux; - ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); + ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL); if (!ab) return; /* audit_panic has been called */ audit_log_format(ab, "arch=%x syscall=%d", @@ -900,9 +901,11 @@ void audit_free(struct task_struct *tsk) return; /* Check for system calls that do not go through the exit - * function (e.g., exit_group), then free context block. */ + * function (e.g., exit_group), then free context block. + * We use GFP_ATOMIC here because we might be doing this + * in the context of the idle thread */ if (context->in_syscall && context->auditable) - audit_log_exit(context); + audit_log_exit(context, GFP_ATOMIC); audit_free_context(context); } @@ -1007,7 +1010,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) return; if (context->in_syscall && context->auditable) - audit_log_exit(context); + audit_log_exit(context, GFP_KERNEL); context->in_syscall = 0; context->auditable = 0; |