When caller tells us that there are constraints on allocations we are allowed
to do, we'd better follow those for more than the first allocation.
Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk>
---
kernel/auditsc.c | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
483cfcd5b5076acedd1729b23f84a901ab165baf
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 8b92132..a9e991b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -503,7 +503,7 @@ static inline void audit_free_context(st
printk(KERN_ERR "audit: freed %d contexts\n", count);
}
-static void audit_log_task_context(struct audit_buffer *ab)
+static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask)
{
char *ctx = NULL;
ssize_t len = 0;
@@ -515,7 +515,7 @@ static void audit_log_task_context(struc
return;
}
- ctx = kmalloc(len, GFP_KERNEL);
+ ctx = kmalloc(len, gfp_mask);
if (!ctx)
goto error_path;
@@ -533,7 +533,7 @@ error_path:
return;
}
-static void audit_log_task_info(struct audit_buffer *ab)
+static void audit_log_task_info(struct audit_buffer *ab, gfp_t gfp_mask)
{
char name[sizeof(current->comm)];
struct mm_struct *mm = current->mm;
@@ -546,6 +546,10 @@ static void audit_log_task_info(struct a
if (!mm)
return;
+ /*
+ * this is brittle; all callers that pass GFP_ATOMIC will have
+ * NULL current->mm and we won't get here.
+ */
down_read(&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
@@ -559,7 +563,7 @@ static void audit_log_task_info(struct a
vma = vma->vm_next;
}
up_read(&mm->mmap_sem);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, gfp_mask);
}
static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
@@ -595,12 +599,12 @@ static void audit_log_exit(struct audit_
context->gid,
context->euid, context->suid, context->fsuid,
context->egid, context->sgid, context->fsgid);
- audit_log_task_info(ab);
+ audit_log_task_info(ab, gfp_mask);
audit_log_end(ab);
for (aux = context->aux; aux; aux = aux->next) {
- ab = audit_log_start(context, GFP_KERNEL, aux->type);
+ ab = audit_log_start(context, gfp_mask, aux->type);
if (!ab)
continue; /* audit_panic has been called */
@@ -637,7 +641,7 @@ static void audit_log_exit(struct audit_
}
if (context->pwd && context->pwdmnt) {
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
+ ab = audit_log_start(context, gfp_mask, AUDIT_CWD);
if (ab) {
audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
audit_log_end(ab);
@@ -647,7 +651,7 @@ static void audit_log_exit(struct audit_
unsigned long ino = context->names[i].ino;
unsigned long pino = context->names[i].pino;
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
+ ab = audit_log_start(context, gfp_mask, AUDIT_PATH);
if (!ab)
continue; /* audit_panic has been called */
--
0.99.9.GIT