* [PATCH] audit: audit on the future execution of a binary.
@ 2012-08-23 19:24 Peter Moody
2012-09-06 21:34 ` Peter Moody
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Peter Moody @ 2012-08-23 19:24 UTC (permalink / raw)
To: linux-audit
This adds the ability audit the actions of a not-yet-running process,
as well as the children of a not-yet-running process.
Signed-off-by: Peter Moody <pmoody@google.com>
---
include/linux/audit.h | 2 ++
kernel/auditfilter.c | 6 ++++++
kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 22f292a..5506cb1 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -260,6 +260,8 @@
#define AUDIT_OBJ_UID 109
#define AUDIT_OBJ_GID 110
#define AUDIT_FIELD_COMPARE 111
+#define AUDIT_EXE 112
+#define AUDIT_EXE_CHILDREN 113
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index a6c3f1a..1e6c571 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
if (f->val > AUDIT_MAX_FIELD_COMPARE)
goto exit_free;
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ if (f->op != Audit_equal) {
+ goto exit_free;
+ }
+ break;
default:
goto exit_free;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4b96415..9cebe95 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -46,6 +46,7 @@
#include <asm/types.h>
#include <linux/atomic.h>
#include <linux/fs.h>
+#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/mm.h>
#include <linux/export.h>
@@ -68,6 +69,7 @@
#include <linux/capability.h>
#include <linux/fs_struct.h>
#include <linux/compat.h>
+#include <linux/sched.h>
#include "audit.h"
@@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
return 0;
}
+int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
+{
+ int result = 0;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+
+ if (!tsk)
+ goto out;
+
+ mm = tsk->mm;
+ if (!mm)
+ goto out;
+
+ down_read(&mm->mmap_sem);
+ vma = mm->mmap;
+ while (vma) {
+ if ((vma->vm_flags & VM_EXECUTABLE) &&
+ vma->vm_file) {
+ struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
+ result = audit_comparator(ino->i_ino, f->op, f->val);
+ break;
+ }
+ vma = vma->vm_next;
+ }
+ up_read(&mm->mmap_sem);
+out:
+ return result;
+}
+
/* Determine if any context name data matches a rule's watch data */
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise.
@@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
result = audit_comparator(ctx->ppid, f->op, f->val);
}
break;
+ case AUDIT_EXE:
+ result = audit_match_exe(tsk, f);
+ break;
+ case AUDIT_EXE_CHILDREN:
+ {
+ struct task_struct *ptsk;
+ for (ptsk = tsk;
+ ptsk->parent->pid > 0;
+ ptsk = find_task_by_vpid(ptsk->parent->pid)) {
+ if (audit_match_exe(ptsk, f)) {
+ ++result;
+ break;
+ }
+ }
+ }
+ break;
case AUDIT_UID:
result = audit_comparator(cred->uid, f->op, f->val);
break;
--
1.7.7.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2012-08-23 19:24 [PATCH] audit: audit on the future execution of a binary Peter Moody
@ 2012-09-06 21:34 ` Peter Moody
2013-04-11 18:08 ` Eric Paris
2013-07-04 2:48 ` Richard Guy Briggs
2 siblings, 0 replies; 11+ messages in thread
From: Peter Moody @ 2012-09-06 21:34 UTC (permalink / raw)
To: linux-audit
Hey Eric,
did you have any comments on this? Is there a better way to do this?
Cheers,
peter
On Thu, Aug 23, 2012 at 12:24 PM, Peter Moody <pmoody@google.com> wrote:
> This adds the ability audit the actions of a not-yet-running process,
> as well as the children of a not-yet-running process.
>
> Signed-off-by: Peter Moody <pmoody@google.com>
> ---
> include/linux/audit.h | 2 ++
> kernel/auditfilter.c | 6 ++++++
> kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 55 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 22f292a..5506cb1 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -260,6 +260,8 @@
> #define AUDIT_OBJ_UID 109
> #define AUDIT_OBJ_GID 110
> #define AUDIT_FIELD_COMPARE 111
> +#define AUDIT_EXE 112
> +#define AUDIT_EXE_CHILDREN 113
>
> #define AUDIT_ARG0 200
> #define AUDIT_ARG1 (AUDIT_ARG0+1)
> diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
> index a6c3f1a..1e6c571 100644
> --- a/kernel/auditfilter.c
> +++ b/kernel/auditfilter.c
> @@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
> if (f->val > AUDIT_MAX_FIELD_COMPARE)
> goto exit_free;
> break;
> + case AUDIT_EXE:
> + case AUDIT_EXE_CHILDREN:
> + if (f->op != Audit_equal) {
> + goto exit_free;
> + }
> + break;
> default:
> goto exit_free;
> }
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 4b96415..9cebe95 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -46,6 +46,7 @@
> #include <asm/types.h>
> #include <linux/atomic.h>
> #include <linux/fs.h>
> +#include <linux/dcache.h>
> #include <linux/namei.h>
> #include <linux/mm.h>
> #include <linux/export.h>
> @@ -68,6 +69,7 @@
> #include <linux/capability.h>
> #include <linux/fs_struct.h>
> #include <linux/compat.h>
> +#include <linux/sched.h>
>
> #include "audit.h"
>
> @@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
> return 0;
> }
>
> +int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
> +{
> + int result = 0;
> + struct mm_struct *mm;
> + struct vm_area_struct *vma;
> +
> + if (!tsk)
> + goto out;
> +
> + mm = tsk->mm;
> + if (!mm)
> + goto out;
> +
> + down_read(&mm->mmap_sem);
> + vma = mm->mmap;
> + while (vma) {
> + if ((vma->vm_flags & VM_EXECUTABLE) &&
> + vma->vm_file) {
> + struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
> + result = audit_comparator(ino->i_ino, f->op, f->val);
> + break;
> + }
> + vma = vma->vm_next;
> + }
> + up_read(&mm->mmap_sem);
> +out:
> + return result;
> +}
> +
> /* Determine if any context name data matches a rule's watch data */
> /* Compare a task_struct with an audit_rule. Return 1 on match, 0
> * otherwise.
> @@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
> result = audit_comparator(ctx->ppid, f->op, f->val);
> }
> break;
> + case AUDIT_EXE:
> + result = audit_match_exe(tsk, f);
> + break;
> + case AUDIT_EXE_CHILDREN:
> + {
> + struct task_struct *ptsk;
> + for (ptsk = tsk;
> + ptsk->parent->pid > 0;
> + ptsk = find_task_by_vpid(ptsk->parent->pid)) {
> + if (audit_match_exe(ptsk, f)) {
> + ++result;
> + break;
> + }
> + }
> + }
> + break;
> case AUDIT_UID:
> result = audit_comparator(cred->uid, f->op, f->val);
> break;
> --
> 1.7.7.3
>
--
Peter Moody Google 1.650.253.7306
Security Engineer pgp:0xC3410038
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2012-08-23 19:24 [PATCH] audit: audit on the future execution of a binary Peter Moody
2012-09-06 21:34 ` Peter Moody
@ 2013-04-11 18:08 ` Eric Paris
2013-04-11 18:13 ` Peter Moody
2013-07-04 2:48 ` Richard Guy Briggs
2 siblings, 1 reply; 11+ messages in thread
From: Eric Paris @ 2013-04-11 18:08 UTC (permalink / raw)
To: Peter Moody; +Cc: linux-audit
Is this late enough? I suck a LOT as a maintainer. Anyway, I'm not in love.
inode numbers are not unique across the system. If you had 2 binaries, completely unrelated, that just happened to have the same i_ino, we'd have false positives. I'm not, off the top of my head, thinking of a good way to fix it. But it does seem to me like maybe it could be something like audit watches where we give the path to the kernel and do some marking on the inode in question inside the kernel.
Possibly such that we even remark it if another binary is dropped on top of the present binary? I'll think on it for a bit...
----- Original Message -----
> This adds the ability audit the actions of a not-yet-running process,
> as well as the children of a not-yet-running process.
>
> Signed-off-by: Peter Moody <pmoody@google.com>
> ---
> include/linux/audit.h | 2 ++
> kernel/auditfilter.c | 6 ++++++
> kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 55 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 22f292a..5506cb1 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -260,6 +260,8 @@
> #define AUDIT_OBJ_UID 109
> #define AUDIT_OBJ_GID 110
> #define AUDIT_FIELD_COMPARE 111
> +#define AUDIT_EXE 112
> +#define AUDIT_EXE_CHILDREN 113
>
> #define AUDIT_ARG0 200
> #define AUDIT_ARG1 (AUDIT_ARG0+1)
> diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
> index a6c3f1a..1e6c571 100644
> --- a/kernel/auditfilter.c
> +++ b/kernel/auditfilter.c
> @@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct
> audit_rule_data *data,
> if (f->val > AUDIT_MAX_FIELD_COMPARE)
> goto exit_free;
> break;
> + case AUDIT_EXE:
> + case AUDIT_EXE_CHILDREN:
> + if (f->op != Audit_equal) {
> + goto exit_free;
> + }
> + break;
> default:
> goto exit_free;
> }
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 4b96415..9cebe95 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -46,6 +46,7 @@
> #include <asm/types.h>
> #include <linux/atomic.h>
> #include <linux/fs.h>
> +#include <linux/dcache.h>
> #include <linux/namei.h>
> #include <linux/mm.h>
> #include <linux/export.h>
> @@ -68,6 +69,7 @@
> #include <linux/capability.h>
> #include <linux/fs_struct.h>
> #include <linux/compat.h>
> +#include <linux/sched.h>
>
> #include "audit.h"
>
> @@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
> return 0;
> }
>
> +int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
> +{
> + int result = 0;
> + struct mm_struct *mm;
> + struct vm_area_struct *vma;
> +
> + if (!tsk)
> + goto out;
> +
> + mm = tsk->mm;
> + if (!mm)
> + goto out;
> +
> + down_read(&mm->mmap_sem);
> + vma = mm->mmap;
> + while (vma) {
> + if ((vma->vm_flags & VM_EXECUTABLE) &&
> + vma->vm_file) {
> + struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
> + result = audit_comparator(ino->i_ino, f->op, f->val);
> + break;
> + }
> + vma = vma->vm_next;
> + }
> + up_read(&mm->mmap_sem);
> +out:
> + return result;
> +}
> +
> /* Determine if any context name data matches a rule's watch data */
> /* Compare a task_struct with an audit_rule. Return 1 on match, 0
> * otherwise.
> @@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
> result = audit_comparator(ctx->ppid, f->op, f->val);
> }
> break;
> + case AUDIT_EXE:
> + result = audit_match_exe(tsk, f);
> + break;
> + case AUDIT_EXE_CHILDREN:
> + {
> + struct task_struct *ptsk;
> + for (ptsk = tsk;
> + ptsk->parent->pid > 0;
> + ptsk = find_task_by_vpid(ptsk->parent->pid)) {
> + if (audit_match_exe(ptsk, f)) {
> + ++result;
> + break;
> + }
> + }
> + }
> + break;
> case AUDIT_UID:
> result = audit_comparator(cred->uid, f->op, f->val);
> break;
> --
> 1.7.7.3
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-04-11 18:08 ` Eric Paris
@ 2013-04-11 18:13 ` Peter Moody
0 siblings, 0 replies; 11+ messages in thread
From: Peter Moody @ 2013-04-11 18:13 UTC (permalink / raw)
To: Eric Paris; +Cc: linux-audit
On Thu, Apr 11, 2013 at 11:08 AM, Eric Paris <eparis@redhat.com> wrote:
> Is this late enough? I suck a LOT as a maintainer. Anyway, I'm not in love.
Hah. I actually figured that you hated it, so 'not in love' is a step
up from what I was expecting.
> inode numbers are not unique across the system. If you had 2 binaries, completely unrelated, that just happened to have the same i_ino, we'd have false positives. I'm not, off the top of my head, thinking of a good way to fix it. But it does seem to me like maybe it could be something like audit watches where we give the path to the kernel and do some marking on the inode in question inside the kernel.
I'd been meaning to get back to this, figuring that there were some
fundamental issues with the inode approach but I had a bunch of stuff
creep onto my plate in the intervening months and this wasn't a
must-have feature anyway.
If you do think of a better way to attack this, I'd be interested to
hear it. The watch sounds promising.
> Possibly such that we even remark it if another binary is dropped on top of the present binary? I'll think on it for a bit...
Cheers,
peter
> ----- Original Message -----
>> This adds the ability audit the actions of a not-yet-running process,
>> as well as the children of a not-yet-running process.
>>
>> Signed-off-by: Peter Moody <pmoody@google.com>
>> ---
>> include/linux/audit.h | 2 ++
>> kernel/auditfilter.c | 6 ++++++
>> kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 55 insertions(+), 0 deletions(-)
>>
>> diff --git a/include/linux/audit.h b/include/linux/audit.h
>> index 22f292a..5506cb1 100644
>> --- a/include/linux/audit.h
>> +++ b/include/linux/audit.h
>> @@ -260,6 +260,8 @@
>> #define AUDIT_OBJ_UID 109
>> #define AUDIT_OBJ_GID 110
>> #define AUDIT_FIELD_COMPARE 111
>> +#define AUDIT_EXE 112
>> +#define AUDIT_EXE_CHILDREN 113
>>
>> #define AUDIT_ARG0 200
>> #define AUDIT_ARG1 (AUDIT_ARG0+1)
>> diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
>> index a6c3f1a..1e6c571 100644
>> --- a/kernel/auditfilter.c
>> +++ b/kernel/auditfilter.c
>> @@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct
>> audit_rule_data *data,
>> if (f->val > AUDIT_MAX_FIELD_COMPARE)
>> goto exit_free;
>> break;
>> + case AUDIT_EXE:
>> + case AUDIT_EXE_CHILDREN:
>> + if (f->op != Audit_equal) {
>> + goto exit_free;
>> + }
>> + break;
>> default:
>> goto exit_free;
>> }
>> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
>> index 4b96415..9cebe95 100644
>> --- a/kernel/auditsc.c
>> +++ b/kernel/auditsc.c
>> @@ -46,6 +46,7 @@
>> #include <asm/types.h>
>> #include <linux/atomic.h>
>> #include <linux/fs.h>
>> +#include <linux/dcache.h>
>> #include <linux/namei.h>
>> #include <linux/mm.h>
>> #include <linux/export.h>
>> @@ -68,6 +69,7 @@
>> #include <linux/capability.h>
>> #include <linux/fs_struct.h>
>> #include <linux/compat.h>
>> +#include <linux/sched.h>
>>
>> #include "audit.h"
>>
>> @@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
>> return 0;
>> }
>>
>> +int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
>> +{
>> + int result = 0;
>> + struct mm_struct *mm;
>> + struct vm_area_struct *vma;
>> +
>> + if (!tsk)
>> + goto out;
>> +
>> + mm = tsk->mm;
>> + if (!mm)
>> + goto out;
>> +
>> + down_read(&mm->mmap_sem);
>> + vma = mm->mmap;
>> + while (vma) {
>> + if ((vma->vm_flags & VM_EXECUTABLE) &&
>> + vma->vm_file) {
>> + struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
>> + result = audit_comparator(ino->i_ino, f->op, f->val);
>> + break;
>> + }
>> + vma = vma->vm_next;
>> + }
>> + up_read(&mm->mmap_sem);
>> +out:
>> + return result;
>> +}
>> +
>> /* Determine if any context name data matches a rule's watch data */
>> /* Compare a task_struct with an audit_rule. Return 1 on match, 0
>> * otherwise.
>> @@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
>> result = audit_comparator(ctx->ppid, f->op, f->val);
>> }
>> break;
>> + case AUDIT_EXE:
>> + result = audit_match_exe(tsk, f);
>> + break;
>> + case AUDIT_EXE_CHILDREN:
>> + {
>> + struct task_struct *ptsk;
>> + for (ptsk = tsk;
>> + ptsk->parent->pid > 0;
>> + ptsk = find_task_by_vpid(ptsk->parent->pid)) {
>> + if (audit_match_exe(ptsk, f)) {
>> + ++result;
>> + break;
>> + }
>> + }
>> + }
>> + break;
>> case AUDIT_UID:
>> result = audit_comparator(cred->uid, f->op, f->val);
>> break;
>> --
>> 1.7.7.3
>>
>>
--
[ Peter Moody | Security Engineer | Google ]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2012-08-23 19:24 [PATCH] audit: audit on the future execution of a binary Peter Moody
2012-09-06 21:34 ` Peter Moody
2013-04-11 18:08 ` Eric Paris
@ 2013-07-04 2:48 ` Richard Guy Briggs
2013-07-07 22:41 ` Peter Moody
2013-07-08 19:57 ` Steve Grubb
2 siblings, 2 replies; 11+ messages in thread
From: Richard Guy Briggs @ 2013-07-04 2:48 UTC (permalink / raw)
To: Peter Moody; +Cc: linux-audit
On Thu, Aug 23, 2012 at 12:24:00PM -0700, Peter Moody wrote:
> This adds the ability audit the actions of a not-yet-running process,
> as well as the children of a not-yet-running process.
Hi Peter,
I've gone back over the discussion of this feature and some of the
background in the past couple of years on this list...
We've got a kernel deadline coming up in the next month if we want to
get something included in RHEL7 if you have the interest and time to
evolve this patch (the userspace patch can follow...).
As has been discussed, passing in an inode reference is incomplete,
since it would need to be qualified by a device reference at minimum.
And even then, it isn't atomic and could change by the time the kernel
even sees this rule request.
So, the next step is to convert the path to a device/inode in the kernel. If
this is done at the time of registering the filter rule, if/when the
rule is invalidated then the rule would be dropped, logged. It also
means that anything else also hardlinked to it would be acted upon.
Going one step further, if instead we can arrange an fsnotify() hook on
rule registration, we could act on that path when it is executed,
renamed, unlinked (and destroyed if the refcount goes to zero), etc.
So, it should be passed as a path, logging the rule addition with path
only at first. When the rule is triggered then log the requested path,
effective path, device/inode along with the user context.
The user, carefully crafting other rules can give other information.
A watch on the containing directory (/usr/bin) could help in case that
executable pathname disappears and re-appears since the containing
directory is less likely to go away, but it will be noisy.
Does all this make sense?
Let's deal later with namespaces, containers, mounts, chroots, bind
mounts, etc...
> Signed-off-by: Peter Moody <pmoody@google.com>
> ---
> include/linux/audit.h | 2 ++
> kernel/auditfilter.c | 6 ++++++
> kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 55 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 22f292a..5506cb1 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -260,6 +260,8 @@
> #define AUDIT_OBJ_UID 109
> #define AUDIT_OBJ_GID 110
> #define AUDIT_FIELD_COMPARE 111
> +#define AUDIT_EXE 112
> +#define AUDIT_EXE_CHILDREN 113
>
> #define AUDIT_ARG0 200
> #define AUDIT_ARG1 (AUDIT_ARG0+1)
> diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
> index a6c3f1a..1e6c571 100644
> --- a/kernel/auditfilter.c
> +++ b/kernel/auditfilter.c
> @@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
> if (f->val > AUDIT_MAX_FIELD_COMPARE)
> goto exit_free;
> break;
> + case AUDIT_EXE:
> + case AUDIT_EXE_CHILDREN:
> + if (f->op != Audit_equal) {
> + goto exit_free;
> + }
> + break;
> default:
> goto exit_free;
> }
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 4b96415..9cebe95 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -46,6 +46,7 @@
> #include <asm/types.h>
> #include <linux/atomic.h>
> #include <linux/fs.h>
> +#include <linux/dcache.h>
> #include <linux/namei.h>
> #include <linux/mm.h>
> #include <linux/export.h>
> @@ -68,6 +69,7 @@
> #include <linux/capability.h>
> #include <linux/fs_struct.h>
> #include <linux/compat.h>
> +#include <linux/sched.h>
>
> #include "audit.h"
>
> @@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
> return 0;
> }
>
> +int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
> +{
> + int result = 0;
> + struct mm_struct *mm;
> + struct vm_area_struct *vma;
> +
> + if (!tsk)
> + goto out;
> +
> + mm = tsk->mm;
> + if (!mm)
> + goto out;
> +
> + down_read(&mm->mmap_sem);
> + vma = mm->mmap;
> + while (vma) {
> + if ((vma->vm_flags & VM_EXECUTABLE) &&
> + vma->vm_file) {
> + struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
> + result = audit_comparator(ino->i_ino, f->op, f->val);
> + break;
> + }
> + vma = vma->vm_next;
> + }
> + up_read(&mm->mmap_sem);
> +out:
> + return result;
> +}
> +
> /* Determine if any context name data matches a rule's watch data */
> /* Compare a task_struct with an audit_rule. Return 1 on match, 0
> * otherwise.
> @@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
> result = audit_comparator(ctx->ppid, f->op, f->val);
> }
> break;
> + case AUDIT_EXE:
> + result = audit_match_exe(tsk, f);
> + break;
> + case AUDIT_EXE_CHILDREN:
> + {
> + struct task_struct *ptsk;
> + for (ptsk = tsk;
> + ptsk->parent->pid > 0;
> + ptsk = find_task_by_vpid(ptsk->parent->pid)) {
> + if (audit_match_exe(ptsk, f)) {
> + ++result;
> + break;
> + }
> + }
> + }
> + break;
> case AUDIT_UID:
> result = audit_comparator(cred->uid, f->op, f->val);
> break;
> --
> 1.7.7.3
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-07-04 2:48 ` Richard Guy Briggs
@ 2013-07-07 22:41 ` Peter Moody
2013-07-08 19:35 ` Richard Guy Briggs
2013-07-08 19:57 ` Steve Grubb
1 sibling, 1 reply; 11+ messages in thread
From: Peter Moody @ 2013-07-07 22:41 UTC (permalink / raw)
To: Richard Guy Briggs; +Cc: linux-audit
On Wed, Jul 03 2013 at 19:48, Richard Guy Briggs wrote:
> On Thu, Aug 23, 2012 at 12:24:00PM -0700, Peter Moody wrote:
>> This adds the ability audit the actions of a not-yet-running process,
>> as well as the children of a not-yet-running process.
>
> Hi Peter,
>
> I've gone back over the discussion of this feature and some of the
> background in the past couple of years on this list...
>
> We've got a kernel deadline coming up in the next month if we want to
> get something included in RHEL7 if you have the interest and time to
> evolve this patch (the userspace patch can follow...).
>
> As has been discussed, passing in an inode reference is incomplete,
> since it would need to be qualified by a device reference at minimum.
> And even then, it isn't atomic and could change by the time the kernel
> even sees this rule request.
>
> So, the next step is to convert the path to a device/inode in the kernel. If
> this is done at the time of registering the filter rule, if/when the
> rule is invalidated then the rule would be dropped, logged. It also
> means that anything else also hardlinked to it would be acted upon.
>
> Going one step further, if instead we can arrange an fsnotify() hook on
> rule registration, we could act on that path when it is executed,
> renamed, unlinked (and destroyed if the refcount goes to zero), etc.
>
> So, it should be passed as a path, logging the rule addition with path
> only at first. When the rule is triggered then log the requested path,
> effective path, device/inode along with the user context.
>
> The user, carefully crafting other rules can give other information.
>
> A watch on the containing directory (/usr/bin) could help in case that
> executable pathname disappears and re-appears since the containing
> directory is less likely to go away, but it will be noisy.
>
> Does all this make sense?
Hey Richard,
Sorry for the late reply, we had a short week last week.
This makes a lot of sense, yes. Unfortunately I think it's unlikely that
I'll have a chance to work on this in time for your freeze b/c my wife
is due on Friday and as much as I'd like to thin that I'll be able to
get some free time during paternity leave to do some kernel hacking,
everyone tells me I'm crazy to think that.
I *think* I'm the only one who's been asking for this feature, so
hopefully my not getting to it won't be putting anyone out.
Cheers,
peter
> Let's deal later with namespaces, containers, mounts, chroots, bind
> mounts, etc...
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-07-07 22:41 ` Peter Moody
@ 2013-07-08 19:35 ` Richard Guy Briggs
0 siblings, 0 replies; 11+ messages in thread
From: Richard Guy Briggs @ 2013-07-08 19:35 UTC (permalink / raw)
To: Peter Moody; +Cc: linux-audit
On Sun, Jul 07, 2013 at 03:41:41PM -0700, Peter Moody wrote:
>
> On Wed, Jul 03 2013 at 19:48, Richard Guy Briggs wrote:
> > On Thu, Aug 23, 2012 at 12:24:00PM -0700, Peter Moody wrote:
> >> This adds the ability audit the actions of a not-yet-running process,
> >> as well as the children of a not-yet-running process.
> >
> > Hi Peter,
> >
> > I've gone back over the discussion of this feature and some of the
> > background in the past couple of years on this list...
> >
> > We've got a kernel deadline coming up in the next month if we want to
> > get something included in RHEL7 if you have the interest and time to
> > evolve this patch (the userspace patch can follow...).
> >
> > As has been discussed, passing in an inode reference is incomplete,
> > since it would need to be qualified by a device reference at minimum.
> > And even then, it isn't atomic and could change by the time the kernel
> > even sees this rule request.
> >
> > So, the next step is to convert the path to a device/inode in the kernel. If
> > this is done at the time of registering the filter rule, if/when the
> > rule is invalidated then the rule would be dropped, logged. It also
> > means that anything else also hardlinked to it would be acted upon.
> >
> > Going one step further, if instead we can arrange an fsnotify() hook on
> > rule registration, we could act on that path when it is executed,
> > renamed, unlinked (and destroyed if the refcount goes to zero), etc.
> >
> > So, it should be passed as a path, logging the rule addition with path
> > only at first. When the rule is triggered then log the requested path,
> > effective path, device/inode along with the user context.
> >
> > The user, carefully crafting other rules can give other information.
> >
> > A watch on the containing directory (/usr/bin) could help in case that
> > executable pathname disappears and re-appears since the containing
> > directory is less likely to go away, but it will be noisy.
> >
> > Does all this make sense?
>
> Hey Richard,
>
> Sorry for the late reply, we had a short week last week.
No worries.
> This makes a lot of sense, yes. Unfortunately I think it's unlikely that
> I'll have a chance to work on this in time for your freeze b/c my wife
> is due on Friday and as much as I'd like to thin that I'll be able to
> get some free time during paternity leave to do some kernel hacking,
> everyone tells me I'm crazy to think that.
A bit delusional, yes. First child, I gather. Welcome to parenting.
It is quite a ride. It can be a lot of fun. :)
> I *think* I'm the only one who's been asking for this feature, so
> hopefully my not getting to it won't be putting anyone out.
What's your timeline and availability?
> Cheers,
> peter
>
> > Let's deal later with namespaces, containers, mounts, chroots, bind
> > mounts, etc...
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-07-04 2:48 ` Richard Guy Briggs
2013-07-07 22:41 ` Peter Moody
@ 2013-07-08 19:57 ` Steve Grubb
2013-07-09 19:03 ` Steve Grubb
1 sibling, 1 reply; 11+ messages in thread
From: Steve Grubb @ 2013-07-08 19:57 UTC (permalink / raw)
To: linux-audit; +Cc: Richard Guy Briggs
On Wednesday, July 03, 2013 10:48:56 PM Richard Guy Briggs wrote:
> I've gone back over the discussion of this feature and some of the
> background in the past couple of years on this list...
>
> We've got a kernel deadline coming up in the next month if we want to
> get something included in RHEL7 if you have the interest and time to
> evolve this patch (the userspace patch can follow...).
>
> As has been discussed, passing in an inode reference is incomplete,
> since it would need to be qualified by a device reference at minimum.
> And even then, it isn't atomic and could change by the time the kernel
> even sees this rule request.
>
> So, the next step is to convert the path to a device/inode in the kernel.
> If this is done at the time of registering the filter rule, if/when the
> rule is invalidated then the rule would be dropped, logged. It also means
> that anything else also hardlinked to it would be acted upon.
>
> Going one step further, if instead we can arrange an fsnotify() hook on
> rule registration, we could act on that path when it is executed,
> renamed, unlinked (and destroyed if the refcount goes to zero), etc.
>
> So, it should be passed as a path, logging the rule addition with path
> only at first. When the rule is triggered then log the requested path,
> effective path, device/inode along with the user context.
>
> The user, carefully crafting other rules can give other information.
This sounds like how I would expect it to be. You pass a path and the kernel
converts is very much like filesystem watches to device/inode. But the next
step is when the execve syscall matches with the path, then the rule is
further converted to have the pid instead of the inode/device. This is
basically following the established pattern we already have for watching files.
> A watch on the containing directory (/usr/bin) could help in case that
> executable pathname disappears and re-appears since the containing
> directory is less likely to go away, but it will be noisy.
Not sure this is necessary. If this is done for file system watches, then its
an established pattern and we should continue to follow it.
-Steve
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-07-08 19:57 ` Steve Grubb
@ 2013-07-09 19:03 ` Steve Grubb
2013-09-20 16:18 ` Steve Grubb
0 siblings, 1 reply; 11+ messages in thread
From: Steve Grubb @ 2013-07-09 19:03 UTC (permalink / raw)
To: linux-audit
On Sunday, July 07, 2013 15:41:41 Peter Moody wrote:
>I *think* I'm the only one who's been asking for this feature, so
>hopefully my not getting to it won't be putting anyone out.
The reason that this is needed is that what we have available for auditing
strange problems that a particular program might have is the
equivalent of audit by inode. You have to have the pid in order to write a
rule. Another invocation and we need a new rule. This feature would allow you
to do investigations like:
- give me all EPERM events generated by apache.
- give me all files opened by gnash
- give me all execve calls made by bind
- record any time sendmail fails to change uid
- exclude any opens with ENOENT by top secret processes <- real important
-Steve
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] audit: audit on the future execution of a binary.
2013-07-09 19:03 ` Steve Grubb
@ 2013-09-20 16:18 ` Steve Grubb
0 siblings, 0 replies; 11+ messages in thread
From: Steve Grubb @ 2013-09-20 16:18 UTC (permalink / raw)
To: linux-audit
On Tuesday, July 09, 2013 03:03:59 PM Steve Grubb wrote:
> On Sunday, July 07, 2013 15:41:41 Peter Moody wrote:
> >I *think* I'm the only one who's been asking for this feature, so
> >hopefully my not getting to it won't be putting anyone out.
>
> The reason that this is needed is that what we have available for auditing
> strange problems that a particular program might have is the
> equivalent of audit by inode. You have to have the pid in order to write a
> rule. Another invocation and we need a new rule. This feature would allow
> you to do investigations like:
>
> - give me all EPERM events generated by apache.
> - give me all files opened by gnash
> - give me all execve calls made by bind
> - record any time sendmail fails to change uid
> - exclude any opens with ENOENT by top secret processes <- real important
Another use case someone asked for this week:
- Give me all files transferred by scp.
-Steve
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] audit: audit on the future execution of a binary.
2014-05-05 20:41 [PATCH] audit: log on the future execution of a path Richard Guy Briggs
@ 2014-05-05 20:41 ` Richard Guy Briggs
0 siblings, 0 replies; 11+ messages in thread
From: Richard Guy Briggs @ 2014-05-05 20:41 UTC (permalink / raw)
To: linux-audit; +Cc: Richard Guy Briggs
Enable creation of rules to monitor for the execution of a future path.
This adds the ability to audit the actions of a not-yet-running process,
possibly not-yet-existing path, as well as the children of a process/path.
A path is supplied and stored with the rule, which is subsequently compared
with the path stored by sys_execve() when called.
Based-on-code-by: Peter Moody <pmoody@google.com>
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
include/linux/audit.h | 1 +
include/uapi/linux/audit.h | 2 ++
kernel/auditfilter.c | 35 +++++++++++++++++++++++++++++++++++
kernel/auditsc.c | 35 +++++++++++++++++++++++++++++++++++
4 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 7c42075..293759e 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -62,6 +62,7 @@ struct audit_krule {
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
struct list_head list; /* for AUDIT_LIST* purposes only */
u64 prio;
+ char *path; /* associated path */
};
struct audit_field {
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 573dc36..f4a72b9 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -266,6 +266,8 @@
#define AUDIT_OBJ_UID 109
#define AUDIT_OBJ_GID 110
#define AUDIT_FIELD_COMPARE 111
+#define AUDIT_EXE 112
+#define AUDIT_EXE_CHILDREN 113
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 6daea0a..3309943 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -87,6 +87,7 @@ static inline void audit_free_rule(struct audit_entry *e)
}
kfree(erule->fields);
kfree(erule->filterkey);
+ kfree(erule->path);
kfree(e);
}
@@ -390,6 +391,11 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ if (f->op != Audit_equal)
+ return -EINVAL;
+ break;
};
return 0;
}
@@ -539,6 +545,16 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
entry->rule.buflen += f->val;
entry->rule.filterkey = str;
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ if (entry->rule.path || f->val > PATH_MAX)
+ goto exit_free;
+ str = audit_unpack_string(&bufp, &remain, f->val);
+ if (IS_ERR(str))
+ goto exit_free;
+ entry->rule.buflen += f->val;
+ entry->rule.path = str;
+ break;
}
}
@@ -617,6 +633,11 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
data->buflen += data->values[i] =
audit_pack_string(&bufp, krule->filterkey);
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ data->buflen += data->values[i] =
+ audit_pack_string(&bufp, krule->path);
+ break;
default:
data->values[i] = f->val;
}
@@ -672,6 +693,12 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
if (strcmp(a->filterkey, b->filterkey))
return 1;
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ /* both paths exist based on above type compare */
+ if (strcmp(a->path, b->path))
+ return 1;
+ break;
case AUDIT_UID:
case AUDIT_EUID:
case AUDIT_SUID:
@@ -742,6 +769,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
struct audit_entry *entry;
struct audit_krule *new;
char *fk;
+ char *path;
int i, err = 0;
entry = audit_init_entry(fcount);
@@ -793,6 +821,13 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
err = -ENOMEM;
else
new->filterkey = fk;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ path = kstrdup(old->path, GFP_KERNEL);
+ if (unlikely(!path))
+ err = -ENOMEM;
+ else
+ new->path = path;
}
if (err) {
audit_free_rule(entry);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index f251a5e..6c6963d 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -48,6 +48,7 @@
#include <asm/types.h>
#include <linux/atomic.h>
#include <linux/fs.h>
+#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/mm.h>
#include <linux/export.h>
@@ -70,6 +71,7 @@
#include <linux/capability.h>
#include <linux/fs_struct.h>
#include <linux/compat.h>
+#include <linux/sched.h>
#include <linux/ctype.h>
#include "audit.h"
@@ -432,6 +434,23 @@ static int audit_field_compare(struct task_struct *tsk,
return 0;
}
+int audit_match_exe(struct task_struct *tsk, struct audit_context *ctx, struct audit_names *name, unsigned char *path)
+{
+ struct audit_names *n;
+
+ if ((!tsk || !tsk->audit_context) && !ctx && !name)
+ return 0;
+
+ if (name)
+ if (!strcmp(name->name->name, path))
+ return 1;
+
+ list_for_each_entry(n, &(ctx ?: tsk->audit_context)->names_list, list)
+ if (n->name && !strcmp(n->name->name, path))
+ return 1;
+ return 0;
+}
+
/* Determine if any context name data matches a rule's watch data */
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise.
@@ -471,6 +490,22 @@ static int audit_filter_rules(struct task_struct *tsk,
result = audit_comparator(ctx->ppid, f->op, f->val);
}
break;
+ case AUDIT_EXE:
+ result = audit_match_exe(tsk, ctx, name, rule->path);
+ break;
+ case AUDIT_EXE_CHILDREN:
+ {
+ struct task_struct *ptsk;
+ for (ptsk = tsk;
+ ptsk->parent->pid > 0;
+ ptsk = find_task_by_vpid(ptsk->parent->pid)) {
+ if (audit_match_exe(ptsk, ctx, name, rule->path)) {
+ ++result;
+ break;
+ }
+ }
+ }
+ break;
case AUDIT_UID:
result = audit_uid_comparator(cred->uid, f->op, f->uid);
break;
--
1.7.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-05-05 20:41 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-23 19:24 [PATCH] audit: audit on the future execution of a binary Peter Moody
2012-09-06 21:34 ` Peter Moody
2013-04-11 18:08 ` Eric Paris
2013-04-11 18:13 ` Peter Moody
2013-07-04 2:48 ` Richard Guy Briggs
2013-07-07 22:41 ` Peter Moody
2013-07-08 19:35 ` Richard Guy Briggs
2013-07-08 19:57 ` Steve Grubb
2013-07-09 19:03 ` Steve Grubb
2013-09-20 16:18 ` Steve Grubb
2014-05-05 20:41 [PATCH] audit: log on the future execution of a path Richard Guy Briggs
2014-05-05 20:41 ` [PATCH] audit: audit on the future execution of a binary Richard Guy Briggs
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.