Audit: break a large single execve argument into smaller records
Eric Paris
maintainerPATCH 2/3 Audit: break a large single execve argument into smaller records
support single arguments that are large, not just large lists of execve args. This also means we never have to get a kernel buffer larger than MAX_EXECVE_AUDIT_LEN no matter how large the argument is. Before this patch we could need to allocate 32 consecutive pages to hold one argument which could pretty easily oom.
a single argument larger than MAX_EXECVE_AUDIT_LEN is broken into multiple
records and have a format like a10[0] a10[1] a10[2] etc.
---
example audit log (about 50k long) for the whole patch series can be found at http://people.redhat.com/~eparis/audit/audit.log the execve in question was something like:
program_name [about 50 arguments] [one argument which is about 17k long] [about 1000 arguments]
kernel/auditsc.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-)
kernel/auditsc.c +42 -0
@@ -853,6 +853,48 @@ static void audit_log_execve_info(struct audit_context *context,send_sig (SIGKILL , current,0 ); } +if (unlikely (len >MAX_EXECVE_AUDIT_LEN )) { +/* deal with single arugments > MAX_EXECVE_AUDIT_LEN */ +int j; +const long tmplen =sizeof (char ) *MAX_EXECVE_AUDIT_LEN ; + + buf =kmalloc (tmplen +1 ,GFP_KERNEL ); +if (!buf) { +audit_panic ("out of memory for argv string\n" ); +return ; + } + buf[tmplen] ='\0' ; +for (j =0 ; len >0 ; j++) { +if (len > tmplen) { + ret =copy_from_user (buf, p, tmplen); + p += tmplen; + len -= tmplen; + }else { + ret =copy_from_user (buf, p, len); +/* p is at the next arg */ + p += len; +/* 27 is the max length of a%d[%d] */ + len_sent = len +27 ; + len =0 ; + } +if (ret) { +WARN_ON (1 ); +send_sig (SIGKILL , current,0 ); + } +audit_log_end (*ab); + *ab =audit_log_start (context,GFP_KERNEL , +AUDIT_EXECVE ); +if (!*ab) { +kfree (buf); +return ; + } +audit_log_format (*ab,"a%d[%d]=" , i, j); +audit_log_untrustedstring (*ab, buf); +audit_log_format (*ab,"\n" ); + } +continue ; + } + buf =kmalloc (len,GFP_KERNEL );if (!buf) {audit_panic ("out of memory for argv string\n" );