From mboxrd@z Thu Jan 1 00:00:00 1970 From: William Roberts Subject: [PATCH 2/4] audit: Enable cacheing of cmdline in audit_context Date: Wed, 20 Nov 2013 17:29:17 -0800 Message-ID: <1384997359-23649-3-git-send-email-wroberts@tresys.com> References: <1384997359-23649-1-git-send-email-wroberts@tresys.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1384997359-23649-1-git-send-email-wroberts@tresys.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com To: linux-audit@redhat.com, rgb@redhat.com Cc: William Roberts List-Id: linux-audit@redhat.com Rather then reading from userspace on every call, cache the page in the audit_context and couple to that objects life-cycle. Change-Id: Ia0d432bc4aba8588840f0dc0026a1e9483e5b485 Signed-off-by: William Roberts --- kernel/auditsc.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 45fd3d0..27f8224 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -270,6 +270,7 @@ struct audit_context { } mmap; }; int fds[2]; + char *cmdline; #if AUDIT_DEBUG int put_count; @@ -1044,6 +1045,14 @@ static inline void audit_free_aux(struct audit_context *context) } } +static inline void audit_cmdline_free(struct audit_context *ctx) +{ + if (!ctx->cmdline) + return; + free_page((unsigned long)ctx->cmdline); + ctx->cmdline = NULL; +} + static inline void audit_zero_context(struct audit_context *context, enum audit_state state) { @@ -1118,6 +1127,7 @@ static inline void audit_free_context(struct audit_context *context) audit_free_aux(context); kfree(context->filterkey); kfree(context->sockaddr); + audit_cmdline_free(context); kfree(context); context = previous; } while (context); @@ -1154,35 +1164,51 @@ error_path: EXPORT_SYMBOL(audit_log_task_context); -static void audit_log_add_cmdline(struct audit_buffer *ab, +static char *audit_cmdline_get_page(struct audit_buffer *ab, struct task_struct *tsk) { int len; unsigned long page; - char *msg = "(null)"; - - audit_log_format(ab, " cmdline="); /* Get the process cmdline */ page = __get_free_page(GFP_TEMPORARY); if (!page) { - audit_log_untrustedstring(ab, msg); - return; + return NULL; } len = proc_pid_cmdline(tsk, (char *)page); if (len <= 0) { free_page(page); - audit_log_untrustedstring(ab, msg); - return; + return NULL; } /* * Ensure NULL terminated! Application could * could be using setproctitle(3). */ ((char *)page)[len-1] = '\0'; - msg = (char *)page; + + /* XXX: Re-alloc to something smaller then a page here? */ + return (char *)page; +} + +static void audit_log_cmdline(struct audit_buffer *ab, struct task_struct *tsk, + struct audit_context *context) +{ + char *msg = "(null)"; + + audit_log_format(ab, " cmdline="); + + /* Already cached */ + if (context->cmdline) { + msg = context->cmdline; + goto out; + } + /* Not cached yet */ + context->cmdline = audit_cmdline_get_page(ab, tsk); + if (!context->cmdline) + goto out; + msg = context->cmdline; +out: audit_log_untrustedstring(ab, msg); - free_page(page); } static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) @@ -1211,7 +1237,6 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk } up_read(&mm->mmap_sem); } - audit_log_add_cmdline(ab, tsk); audit_log_task_context(ab); } @@ -1679,6 +1704,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts audit_log_task_info(ab, tsk); + audit_log_cmdline(ab, tsk, context); audit_log_key(ab, context->filterkey); audit_log_end(ab); -- 1.7.9.5