On Thu, Apr 11, 2013 at 11:08 AM, Eric Paris <eparis(a)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(a)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 ]