The purpose of audit_bprm() is to log the argv array to a userspace daemon at
the end of the execve system call. Since user-space hasn't had time to run,
this array is still in pristine state on the process' stack; so no need to copy
it, we can just grab it from there.
In order to minimize the damage to audit_log_*() copy each string into a
temporary kernel buffer first.
Currently the audit code requires that the full argument vector fits in a
single packet. So currently it does clip the argv size to a (sysctl) limit, but
only when execve auditing is enabled.
If the audit protocol gets extended to allow for multiple packets this check
can be removed.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ollie Wild <aaw@google.com>
Cc: linux-audit@redhat.com
---
fs/exec.c | 3 +
include/linux/binfmts.h | 1
include/linux/sysctl.h | 1
kernel/audit.c | 16 +++++++++
kernel/audit.h | 1
kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++----------------
kernel/sysctl.c | 11 ++++++
7 files changed, 89 insertions(+), 26 deletions(-)
Index: linux-2.6-2/kernel/auditsc.c
===================================================================
--- linux-2.6-2.orig/kernel/auditsc.c 2007-06-05 09:51:53.000000000 +0200
+++ linux-2.6-2/kernel/auditsc.c 2007-06-05 10:03:31.000000000 +0200
@@ -156,7 +156,7 @@ struct audit_aux_data_execve {
struct audit_aux_data d;
int argc;
int envc;
- char mem[0];
+ struct mm_struct *mm;
};
struct audit_aux_data_socketcall {
@@ -834,6 +834,47 @@ static int audit_log_pid_context(struct
return rc;
}
+static void audit_log_execve_info(struct audit_buffer *ab,
+ struct audit_aux_data_execve *axi)
+{
+ int i;
+ long len;
+ const char __user *p = (const char __user *)axi->mm->arg_start;
+
+ if (axi->mm != current->mm)
+ return; /* execve failed, no additional info */
+
+ for (i = 0; i < axi->argc; i++, p += len) {
+ long ...