* Follow up on command line auditing @ 2013-12-02 15:42 William Roberts 2013-12-02 15:42 ` [PATCH] audit: Audit proc cmdline value William Roberts 2013-12-02 16:07 ` Follow up on command line auditing Richard Guy Briggs 0 siblings, 2 replies; 8+ messages in thread From: William Roberts @ 2013-12-02 15:42 UTC (permalink / raw) To: linux-audit; +Cc: rgb Just following up on this since the holiday, any traction? Changelog since last post: * Rebase on latest master [PATCH] audit: Audit proc cmdline value ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] audit: Audit proc cmdline value 2013-12-02 15:42 Follow up on command line auditing William Roberts @ 2013-12-02 15:42 ` William Roberts 2013-12-02 16:07 ` Follow up on command line auditing Richard Guy Briggs 1 sibling, 0 replies; 8+ messages in thread From: William Roberts @ 2013-12-02 15:42 UTC (permalink / raw) To: linux-audit; +Cc: rgb, William Roberts During an audit event, cache and print the value of the process's cmdline value (proc/<pid>/cmdline). This is useful in situations where processes are started via fork'd virtual machines where the comm field is incorrect. Often times, setting the comm field still is insufficient as the comm width is not very wide and most virtual machine "package names" do not fit. Also, during execution, many threads have thier comm field set as well. By tying it back to the global cmdline value for the process, audit records will be more complete in systems with these properties. An example of where this is useful and applicable is in the realm of Android. The cached cmdline is tied to the lifecycle of the audit_context structure and is built on demand. Signed-off-by: William Roberts <wroberts@tresys.com> --- fs/proc/base.c | 35 +++++++--------------- include/linux/mm.h | 7 +++++ kernel/audit.h | 1 + kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mm/util.c | 48 ++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 25 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 03c8d74..fb4eda5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -203,37 +203,22 @@ static int proc_root_link(struct dentry *dentry, struct path *path) static int proc_pid_cmdline(struct task_struct *task, char * buffer) { int res = 0; - unsigned int len; + unsigned int len = 0; struct mm_struct *mm = get_task_mm(task); if (!mm) - goto out; - if (!mm->arg_end) - goto out_mm; /* Shh! No looking before we're done */ + return 0; - len = mm->arg_end - mm->arg_start; - + len = get_cmdline_length(mm); + if (!len) + goto mm_out; + + /*The caller of this allocates a page */ if (len > PAGE_SIZE) len = PAGE_SIZE; - - res = access_process_vm(task, mm->arg_start, buffer, len, 0); - - // If the nul at the end of args has been overwritten, then - // assume application is using setproctitle(3). - if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) { - len = strnlen(buffer, res); - if (len < res) { - res = len; - } else { - len = mm->env_end - mm->env_start; - if (len > PAGE_SIZE - res) - len = PAGE_SIZE - res; - res += access_process_vm(task, mm->env_start, buffer+res, len, 0); - res = strnlen(buffer, res); - } - } -out_mm: + + res = copy_cmdline(task, mm, buffer, len); +mm_out: mmput(mm); -out: return res; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 1cedd00..b4d7c26 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1135,6 +1135,13 @@ int set_page_dirty(struct page *page); int set_page_dirty_lock(struct page *page); int clear_page_dirty_for_io(struct page *page); +extern int copy_cmdline(struct task_struct *task, struct mm_struct *mm, + char *buf, unsigned int buflen); +static inline unsigned int get_cmdline_length(struct mm_struct *mm) +{ + return mm->arg_end ? mm->arg_end - mm->arg_start : 0; +} + /* Is the vma a continuation of the stack vma above it? */ static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr) { diff --git a/kernel/audit.h b/kernel/audit.h index b779642..bd6211f 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -202,6 +202,7 @@ struct audit_context { } execve; }; int fds[2]; + char *cmdline; #if AUDIT_DEBUG int put_count; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 90594c9..bfb1698 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -842,6 +842,14 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, return context; } +static inline void audit_cmdline_free(struct audit_context *context) +{ + if (!context->cmdline) + return; + kfree(context->cmdline); + context->cmdline = NULL; +} + static inline void audit_free_names(struct audit_context *context) { struct audit_names *n, *next; @@ -955,6 +963,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); } @@ -1271,6 +1280,78 @@ static void show_special(struct audit_context *context, int *call_panic) audit_log_end(ab); } +static char *audit_cmdline_get(struct audit_buffer *ab, + struct task_struct *task) +{ + int len; + int res; + char *buf; + struct mm_struct *mm; + + if (!ab || !task) + return NULL; + + mm = get_task_mm(task); + if (!mm) + return NULL; + + len = get_cmdline_length(mm); + if (!len) + goto mm_err; + + if (len > PATH_MAX) + len = PATH_MAX; + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + goto mm_err; + + res = copy_cmdline(task, mm, buf, len); + if (res <= 0) + goto alloc_err; + + mmput(mm); + /* + * res is guarenteed not to be longer than + * than the buf as it was truncated to len + * in copy_cmdline() + */ + len = res; + + /* + * Ensure NULL terminated as application + * could be using setproctitle(3) + */ + buf[len-1] = '\0'; + return buf; + +alloc_err: + kfree(buf); +mm_err: + mmput(mm); + return NULL; +} + +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 */ + context->cmdline = audit_cmdline_get(ab, tsk); + if (!context->cmdline) + goto out; + msg = context->cmdline; +out: + audit_log_untrustedstring(ab, msg); +} + static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) { int i, call_panic = 0; @@ -1302,6 +1383,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts context->name_count); audit_log_task_info(ab, tsk); + audit_log_cmdline(ab, tsk, context); audit_log_key(ab, context->filterkey); audit_log_end(ab); diff --git a/mm/util.c b/mm/util.c index f7bc209..c8cad32 100644 --- a/mm/util.c +++ b/mm/util.c @@ -9,6 +9,7 @@ #include <linux/swapops.h> #include <linux/mman.h> #include <linux/hugetlb.h> +#include <linux/mm.h> #include <asm/uaccess.h> @@ -410,6 +411,53 @@ unsigned long vm_commit_limit(void) * sysctl_overcommit_ratio / 100) + total_swap_pages; } +/** + * copy_cmdline - Copy's the tasks commandline value to a buffer + * @task: The task whose command line to copy + * @mm: The mm struct refering to task with proper semaphores held + * @buf: The buffer to copy the value into + * @buflen: The length og the buffer. It trucates the value to + * buflen. + * @return: The number of chars copied. + */ +int copy_cmdline(struct task_struct *task, struct mm_struct *mm, + char *buf, unsigned int buflen) +{ + int res = 0; + unsigned int len; + + if (!task || !mm || !buf) + return -1; + + res = access_process_vm(task, mm->arg_start, buf, buflen, 0); + if (res <= 0) + return 0; + + if (res > buflen) + res = buflen; + /* + * If the nul at the end of args had been overwritten, then + * assume application is using setproctitle(3). + */ + if (buf[res-1] != '\0') { + /* Nul between start and end of vm space? + If so then truncate */ + len = strnlen(buf, res); + if (len < res) { + res = len; + } else { + /* No nul, truncate buflen if to big */ + len = mm->env_end - mm->env_start; + if (len > buflen - res) + len = buflen - res; + /* Copy any remaining data */ + res += access_process_vm(task, mm->env_start, buf+res, + len, 0); + res = strnlen(buf, res); + } + } + return res; +} /* Tracepoints definitions. */ EXPORT_TRACEPOINT_SYMBOL(kmalloc); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: Follow up on command line auditing 2013-12-02 15:42 Follow up on command line auditing William Roberts 2013-12-02 15:42 ` [PATCH] audit: Audit proc cmdline value William Roberts @ 2013-12-02 16:07 ` Richard Guy Briggs 2013-12-02 16:20 ` William Roberts 1 sibling, 1 reply; 8+ messages in thread From: Richard Guy Briggs @ 2013-12-02 16:07 UTC (permalink / raw) To: William Roberts; +Cc: linux-audit On Mon, Dec 02, 2013 at 07:42:20AM -0800, William Roberts wrote: > Changelog since last post: > * Rebase on latest master > > [PATCH] audit: Audit proc cmdline value Hi Bill, I wasn't expecting that you would squash everything down into one patch. I think it should be at least two. I'm comfortable with the changes in the audit subsystem. Could those be one patch? As for the changes to proc (including base and util) those might be better as a seperate patch. - RGB -- Richard Guy Briggs <rbriggs@redhat.com> Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat Remote, Ottawa, Canada Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Follow up on command line auditing 2013-12-02 16:07 ` Follow up on command line auditing Richard Guy Briggs @ 2013-12-02 16:20 ` William Roberts 2013-12-02 17:18 ` Richard Guy Briggs 0 siblings, 1 reply; 8+ messages in thread From: William Roberts @ 2013-12-02 16:20 UTC (permalink / raw) To: Richard Guy Briggs; +Cc: linux-audit On Mon, Dec 2, 2013 at 8:07 AM, Richard Guy Briggs <rgb@redhat.com> wrote: > On Mon, Dec 02, 2013 at 07:42:20AM -0800, William Roberts wrote: >> Changelog since last post: >> * Rebase on latest master >> >> [PATCH] audit: Audit proc cmdline value > > Hi Bill, > > I wasn't expecting that you would squash everything down into one patch. > I think it should be at least two. I'm comfortable with the changes in > the audit subsystem. Could those be one patch? As for the changes to > proc (including base and util) those might be better as a seperate > patch. > > Richard, Ok so what do you think the best way forward is? I don't want to duplicate code from proc/base.c. I would need to export proc_pid_cmdline() in the first patch or re-implement it in the audit subsystem, followed by a patch to merge the functionality. What would you prefer? Thanks, Bill ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Follow up on command line auditing 2013-12-02 16:20 ` William Roberts @ 2013-12-02 17:18 ` Richard Guy Briggs 2013-12-02 18:10 ` William Roberts 0 siblings, 1 reply; 8+ messages in thread From: Richard Guy Briggs @ 2013-12-02 17:18 UTC (permalink / raw) To: William Roberts; +Cc: linux-audit On Mon, Dec 02, 2013 at 08:20:10AM -0800, William Roberts wrote: > On Mon, Dec 2, 2013 at 8:07 AM, Richard Guy Briggs <rgb@redhat.com> wrote: > > On Mon, Dec 02, 2013 at 07:42:20AM -0800, William Roberts wrote: > >> Changelog since last post: > >> * Rebase on latest master > >> > >> [PATCH] audit: Audit proc cmdline value > > > > Hi Bill, > > > > I wasn't expecting that you would squash everything down into one patch. > > I think it should be at least two. I'm comfortable with the changes in > > the audit subsystem. Could those be one patch? As for the changes to > > proc (including base and util) those might be better as a seperate > > patch. > > Richard, > Ok so what do you think the best way forward is? I don't want to duplicate > code from proc/base.c. I would need to export proc_pid_cmdline() > in the first patch or re-implement it in the audit subsystem, followed > by a patch > to merge the functionality. What would you prefer? I would split them into 3 patches: 1) implement the length and copy funcitons: include/linux/mm.h | 7 +++++ mm/util.c | 48 ++++++++++++++++++++++++++++++ 2) use them in the proc call: fs/proc/base.c | 35 +++++++--------------- 3) use them in audit: kernel/audit.h | 1 + kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Does this split make sense? Combining 1 and 2 might be acceptable to those subsystem maintainers... > Bill - RGB -- Richard Guy Briggs <rbriggs@redhat.com> Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat Remote, Ottawa, Canada Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Follow up on command line auditing 2013-12-02 17:18 ` Richard Guy Briggs @ 2013-12-02 18:10 ` William Roberts 2013-12-02 18:19 ` Richard Guy Briggs 0 siblings, 1 reply; 8+ messages in thread From: William Roberts @ 2013-12-02 18:10 UTC (permalink / raw) To: Richard Guy Briggs; +Cc: linux-audit On Mon, Dec 2, 2013 at 9:18 AM, Richard Guy Briggs <rgb@redhat.com> wrote: > On Mon, Dec 02, 2013 at 08:20:10AM -0800, William Roberts wrote: >> On Mon, Dec 2, 2013 at 8:07 AM, Richard Guy Briggs <rgb@redhat.com> wrote: >> > On Mon, Dec 02, 2013 at 07:42:20AM -0800, William Roberts wrote: >> >> Changelog since last post: >> >> * Rebase on latest master >> >> >> >> [PATCH] audit: Audit proc cmdline value >> > >> > Hi Bill, >> > >> > I wasn't expecting that you would squash everything down into one patch. >> > I think it should be at least two. I'm comfortable with the changes in >> > the audit subsystem. Could those be one patch? As for the changes to >> > proc (including base and util) those might be better as a seperate >> > patch. >> >> Richard, >> Ok so what do you think the best way forward is? I don't want to duplicate >> code from proc/base.c. I would need to export proc_pid_cmdline() >> in the first patch or re-implement it in the audit subsystem, followed >> by a patch >> to merge the functionality. What would you prefer? > > I would split them into 3 patches: > > 1) implement the length and copy funcitons: > include/linux/mm.h | 7 +++++ > mm/util.c | 48 ++++++++++++++++++++++++++++++ > > 2) use them in the proc call: > fs/proc/base.c | 35 +++++++--------------- > > 3) use them in audit: > kernel/audit.h | 1 + > kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > Does this split make sense? Combining 1 and 2 might be acceptable to > those subsystem maintainers... You read my mind here after I sent this, this is exactly what I was thinking. When I am done do I publish this to kernel mainline, here, or elsewhere? Bill <snip> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Follow up on command line auditing 2013-12-02 18:10 ` William Roberts @ 2013-12-02 18:19 ` Richard Guy Briggs 0 siblings, 0 replies; 8+ messages in thread From: Richard Guy Briggs @ 2013-12-02 18:19 UTC (permalink / raw) To: William Roberts; +Cc: linux-audit On Mon, Dec 02, 2013 at 10:10:27AM -0800, William Roberts wrote: > On Mon, Dec 2, 2013 at 9:18 AM, Richard Guy Briggs <rgb@redhat.com> wrote: > > On Mon, Dec 02, 2013 at 08:20:10AM -0800, William Roberts wrote: > >> On Mon, Dec 2, 2013 at 8:07 AM, Richard Guy Briggs <rgb@redhat.com> wrote: > >> > On Mon, Dec 02, 2013 at 07:42:20AM -0800, William Roberts wrote: > >> >> Changelog since last post: > >> >> * Rebase on latest master > >> >> > >> >> [PATCH] audit: Audit proc cmdline value > >> > > >> > Hi Bill, > >> > > >> > I wasn't expecting that you would squash everything down into one patch. > >> > I think it should be at least two. I'm comfortable with the changes in > >> > the audit subsystem. Could those be one patch? As for the changes to > >> > proc (including base and util) those might be better as a seperate > >> > patch. > >> > >> Richard, > >> Ok so what do you think the best way forward is? I don't want to duplicate > >> code from proc/base.c. I would need to export proc_pid_cmdline() > >> in the first patch or re-implement it in the audit subsystem, followed > >> by a patch > >> to merge the functionality. What would you prefer? > > > > I would split them into 3 patches: > > > > 1) implement the length and copy funcitons: > > include/linux/mm.h | 7 +++++ > > mm/util.c | 48 ++++++++++++++++++++++++++++++ > > > > 2) use them in the proc call: > > fs/proc/base.c | 35 +++++++--------------- > > > > 3) use them in audit: > > kernel/audit.h | 1 + > > kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > > Does this split make sense? Combining 1 and 2 might be acceptable to > > those subsystem maintainers... > > You read my mind here after I sent this, this is exactly what I was thinking. > > When I am done do I publish this to kernel mainline, here, or elsewhere? Both here and lkml would make sense. Find the respective maintainers using scripts/get_maintainer.pl and Cc: them. > Bill - RGB -- Richard Guy Briggs <rbriggs@redhat.com> Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat Remote, Ottawa, Canada Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Updated patches @ 2013-11-25 16:11 William Roberts 2013-11-25 16:11 ` [PATCH] audit: Audit proc cmdline value William Roberts 0 siblings, 1 reply; 8+ messages in thread From: William Roberts @ 2013-11-25 16:11 UTC (permalink / raw) To: linux-audit, rgb What's changed since last time? * Squashed all the patches down * Patches are relative to master This is the version I would like to get merged. [PATCH] audit: Audit proc cmdline value ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] audit: Audit proc cmdline value 2013-11-25 16:11 Updated patches William Roberts @ 2013-11-25 16:11 ` William Roberts 0 siblings, 0 replies; 8+ messages in thread From: William Roberts @ 2013-11-25 16:11 UTC (permalink / raw) To: linux-audit, rgb; +Cc: William Roberts During an audit event, cache and print the value of the process's cmdline value (proc/<pid>/cmdline). This is useful in situations where processes are started via fork'd virtual machines where the comm field is incorrect. Often times, setting the comm field still is insufficient as the comm width is not very wide and most virtual machine "package names" do not fit. Also, during execution, many threads have thier comm field set as well. By tying it back to the global cmdline value for the process, audit records will be more complete in systems with these properties. An example of where this is useful and applicable is in the realm of Android. The cached cmdline is tied to the lifecycle of the audit_context structure and is built on demand. Signed-off-by: William Roberts <wroberts@tresys.com> --- fs/proc/base.c | 35 +++++++--------------- include/linux/mm.h | 7 +++++ kernel/audit.h | 1 + kernel/auditsc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mm/util.c | 48 ++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 25 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 03c8d74..fb4eda5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -203,37 +203,22 @@ static int proc_root_link(struct dentry *dentry, struct path *path) static int proc_pid_cmdline(struct task_struct *task, char * buffer) { int res = 0; - unsigned int len; + unsigned int len = 0; struct mm_struct *mm = get_task_mm(task); if (!mm) - goto out; - if (!mm->arg_end) - goto out_mm; /* Shh! No looking before we're done */ + return 0; - len = mm->arg_end - mm->arg_start; - + len = get_cmdline_length(mm); + if (!len) + goto mm_out; + + /*The caller of this allocates a page */ if (len > PAGE_SIZE) len = PAGE_SIZE; - - res = access_process_vm(task, mm->arg_start, buffer, len, 0); - - // If the nul at the end of args has been overwritten, then - // assume application is using setproctitle(3). - if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) { - len = strnlen(buffer, res); - if (len < res) { - res = len; - } else { - len = mm->env_end - mm->env_start; - if (len > PAGE_SIZE - res) - len = PAGE_SIZE - res; - res += access_process_vm(task, mm->env_start, buffer+res, len, 0); - res = strnlen(buffer, res); - } - } -out_mm: + + res = copy_cmdline(task, mm, buffer, len); +mm_out: mmput(mm); -out: return res; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 1cedd00..b4d7c26 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1135,6 +1135,13 @@ int set_page_dirty(struct page *page); int set_page_dirty_lock(struct page *page); int clear_page_dirty_for_io(struct page *page); +extern int copy_cmdline(struct task_struct *task, struct mm_struct *mm, + char *buf, unsigned int buflen); +static inline unsigned int get_cmdline_length(struct mm_struct *mm) +{ + return mm->arg_end ? mm->arg_end - mm->arg_start : 0; +} + /* Is the vma a continuation of the stack vma above it? */ static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr) { diff --git a/kernel/audit.h b/kernel/audit.h index b779642..bd6211f 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -202,6 +202,7 @@ struct audit_context { } execve; }; int fds[2]; + char *cmdline; #if AUDIT_DEBUG int put_count; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 90594c9..bfb1698 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -842,6 +842,14 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, return context; } +static inline void audit_cmdline_free(struct audit_context *context) +{ + if (!context->cmdline) + return; + kfree(context->cmdline); + context->cmdline = NULL; +} + static inline void audit_free_names(struct audit_context *context) { struct audit_names *n, *next; @@ -955,6 +963,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); } @@ -1271,6 +1280,78 @@ static void show_special(struct audit_context *context, int *call_panic) audit_log_end(ab); } +static char *audit_cmdline_get(struct audit_buffer *ab, + struct task_struct *task) +{ + int len; + int res; + char *buf; + struct mm_struct *mm; + + if (!ab || !task) + return NULL; + + mm = get_task_mm(task); + if (!mm) + return NULL; + + len = get_cmdline_length(mm); + if (!len) + goto mm_err; + + if (len > PATH_MAX) + len = PATH_MAX; + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + goto mm_err; + + res = copy_cmdline(task, mm, buf, len); + if (res <= 0) + goto alloc_err; + + mmput(mm); + /* + * res is guarenteed not to be longer than + * than the buf as it was truncated to len + * in copy_cmdline() + */ + len = res; + + /* + * Ensure NULL terminated as application + * could be using setproctitle(3) + */ + buf[len-1] = '\0'; + return buf; + +alloc_err: + kfree(buf); +mm_err: + mmput(mm); + return NULL; +} + +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 */ + context->cmdline = audit_cmdline_get(ab, tsk); + if (!context->cmdline) + goto out; + msg = context->cmdline; +out: + audit_log_untrustedstring(ab, msg); +} + static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) { int i, call_panic = 0; @@ -1302,6 +1383,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts context->name_count); audit_log_task_info(ab, tsk); + audit_log_cmdline(ab, tsk, context); audit_log_key(ab, context->filterkey); audit_log_end(ab); diff --git a/mm/util.c b/mm/util.c index f7bc209..c8cad32 100644 --- a/mm/util.c +++ b/mm/util.c @@ -9,6 +9,7 @@ #include <linux/swapops.h> #include <linux/mman.h> #include <linux/hugetlb.h> +#include <linux/mm.h> #include <asm/uaccess.h> @@ -410,6 +411,53 @@ unsigned long vm_commit_limit(void) * sysctl_overcommit_ratio / 100) + total_swap_pages; } +/** + * copy_cmdline - Copy's the tasks commandline value to a buffer + * @task: The task whose command line to copy + * @mm: The mm struct refering to task with proper semaphores held + * @buf: The buffer to copy the value into + * @buflen: The length og the buffer. It trucates the value to + * buflen. + * @return: The number of chars copied. + */ +int copy_cmdline(struct task_struct *task, struct mm_struct *mm, + char *buf, unsigned int buflen) +{ + int res = 0; + unsigned int len; + + if (!task || !mm || !buf) + return -1; + + res = access_process_vm(task, mm->arg_start, buf, buflen, 0); + if (res <= 0) + return 0; + + if (res > buflen) + res = buflen; + /* + * If the nul at the end of args had been overwritten, then + * assume application is using setproctitle(3). + */ + if (buf[res-1] != '\0') { + /* Nul between start and end of vm space? + If so then truncate */ + len = strnlen(buf, res); + if (len < res) { + res = len; + } else { + /* No nul, truncate buflen if to big */ + len = mm->env_end - mm->env_start; + if (len > buflen - res) + len = buflen - res; + /* Copy any remaining data */ + res += access_process_vm(task, mm->env_start, buf+res, + len, 0); + res = strnlen(buf, res); + } + } + return res; +} /* Tracepoints definitions. */ EXPORT_TRACEPOINT_SYMBOL(kmalloc); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-12-02 18:19 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-12-02 15:42 Follow up on command line auditing William Roberts 2013-12-02 15:42 ` [PATCH] audit: Audit proc cmdline value William Roberts 2013-12-02 16:07 ` Follow up on command line auditing Richard Guy Briggs 2013-12-02 16:20 ` William Roberts 2013-12-02 17:18 ` Richard Guy Briggs 2013-12-02 18:10 ` William Roberts 2013-12-02 18:19 ` Richard Guy Briggs -- strict thread matches above, loose matches on Subject: below -- 2013-11-25 16:11 Updated patches William Roberts 2013-11-25 16:11 ` [PATCH] audit: Audit proc cmdline value William Roberts
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox