diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-07-13 17:47:07 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-07-13 17:47:07 -0400 |
commit | f55619642e863990d5a46cf2c2c840170d22a9f9 (patch) | |
tree | faf2447562a26c4620d254fd1b46f3ae7e6fc678 | |
parent | 582edda586120004d0fb67113115fa442a0a1571 (diff) |
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 @@ | |||
41 | #include <linux/time.h> | 41 | #include <linux/time.h> |
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <linux/netlink.h> | 43 | #include <linux/netlink.h> |
44 | #include <linux/compiler.h> | ||
44 | #include <asm/unistd.h> | 45 | #include <asm/unistd.h> |
45 | 46 | ||
46 | /* 0 = no checking | 47 | /* 0 = no checking |
@@ -778,13 +779,13 @@ static void audit_log_task_info(struct audit_buffer *ab) | |||
778 | up_read(&mm->mmap_sem); | 779 | up_read(&mm->mmap_sem); |
779 | } | 780 | } |
780 | 781 | ||
781 | static void audit_log_exit(struct audit_context *context) | 782 | static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask) |
782 | { | 783 | { |
783 | int i; | 784 | int i; |
784 | struct audit_buffer *ab; | 785 | struct audit_buffer *ab; |
785 | struct audit_aux_data *aux; | 786 | struct audit_aux_data *aux; |
786 | 787 | ||
787 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); | 788 | ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL); |
788 | if (!ab) | 789 | if (!ab) |
789 | return; /* audit_panic has been called */ | 790 | return; /* audit_panic has been called */ |
790 | audit_log_format(ab, "arch=%x syscall=%d", | 791 | audit_log_format(ab, "arch=%x syscall=%d", |
@@ -900,9 +901,11 @@ void audit_free(struct task_struct *tsk) | |||
900 | return; | 901 | return; |
901 | 902 | ||
902 | /* Check for system calls that do not go through the exit | 903 | /* Check for system calls that do not go through the exit |
903 | * function (e.g., exit_group), then free context block. */ | 904 | * function (e.g., exit_group), then free context block. |
905 | * We use GFP_ATOMIC here because we might be doing this | ||
906 | * in the context of the idle thread */ | ||
904 | if (context->in_syscall && context->auditable) | 907 | if (context->in_syscall && context->auditable) |
905 | audit_log_exit(context); | 908 | audit_log_exit(context, GFP_ATOMIC); |
906 | 909 | ||
907 | audit_free_context(context); | 910 | audit_free_context(context); |
908 | } | 911 | } |
@@ -1007,7 +1010,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) | |||
1007 | return; | 1010 | return; |
1008 | 1011 | ||
1009 | if (context->in_syscall && context->auditable) | 1012 | if (context->in_syscall && context->auditable) |
1010 | audit_log_exit(context); | 1013 | audit_log_exit(context, GFP_KERNEL); |
1011 | 1014 | ||
1012 | context->in_syscall = 0; | 1015 | context->in_syscall = 0; |
1013 | context->auditable = 0; | 1016 | context->auditable = 0; |