From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Paris Subject: [PATCH 3/3] audit: convert audit_exe to audit_fsnotify Date: Tue, 13 May 2014 18:11:21 -0400 Message-ID: <1400019081-27887-3-git-send-email-eparis@redhat.com> References: <1400019081-27887-1-git-send-email-eparis@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from paris.rdu.redhat.com (paris.rdu.redhat.com [10.13.136.28]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4DMBM7D018669 for ; Tue, 13 May 2014 18:11:23 -0400 In-Reply-To: <1400019081-27887-1-git-send-email-eparis@redhat.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 List-Id: linux-audit@redhat.com Instead of just hard coding the ino and dev of the executable we care about at the moment the rule is inserted into the kernel, use the new audit_fsnotify infrastructure. This means that if the inode in question is unlinked and creat'd (aka updated) the rule will just continue to work. Signed-off-by: Eric Paris --- include/linux/audit.h | 2 +- kernel/audit.h | 31 +++++------------- kernel/audit_exe.c | 87 +++++++-------------------------------------------- kernel/auditfilter.c | 18 ++++++----- 4 files changed, 31 insertions(+), 107 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index 84e7bc4..9bdb5dd 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -59,7 +59,7 @@ struct audit_krule { struct audit_field *inode_f; /* quick access to an inode field */ struct audit_watch *watch; /* associated watch */ struct audit_tree *tree; /* associated watched tree */ - struct audit_exe *exe; + struct audit_fsnotify_mark *exe; struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ struct list_head list; /* for AUDIT_LIST* purposes only */ u64 prio; diff --git a/kernel/audit.h b/kernel/audit.h index 8d863d4..61688ba0 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -57,7 +57,6 @@ enum audit_state { /* Rule lists */ struct audit_watch; struct audit_fsnotify_mark; -struct audit_exe; struct audit_tree; struct audit_chunk; @@ -289,11 +288,8 @@ char *audit_mark_path(struct audit_fsnotify_mark *mark); void audit_remove_mark(struct audit_fsnotify_mark *audit_mark); int audit_mark_compare(struct audit_fsnotify_mark *mark, unsigned long ino, dev_t dev); -int audit_make_exe_rule(struct audit_krule *krule, char *pathname, int len, u32 op); -void audit_remove_exe_rule(struct audit_krule *krule); -char *audit_exe_path(struct audit_exe *exe); int audit_dup_exe(struct audit_krule *new, struct audit_krule *old); -int audit_exe_compare(struct task_struct *tsk, struct audit_exe *exe); +int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark); #else #define audit_put_watch(w) {} @@ -320,31 +316,18 @@ static inline void audit_remove_mark(struct audit_fsnotify_mark *audit_mark) BUG(); } -static inline int audit_mark_compare(struct audit_fsnotify_mark *mark, unsigned long ino, dev_t dev) +static inline int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark) { BUG(); - return 0; -} - -static inline int audit_make_exe_rule(struct audit_krule *krule, char *pathname, int len, u32 op) { return -EINVAL; } -static inline void audit_remove_exe_rule(struct audit_krule *krule) { - BUG(); - return 0; -} -static inline char *audit_exe_path(struct audit_exe *exe) { - BUG(); - return ""; -} -static inline int audit_dup_exe(struct audit_krule *new, struct audit_krule *old) { - BUG(); - return -EINVAL -} -static inline int audit_exe_compare(struct task_struct *tsk, struct audit_exe *exe) { + +static inline int audit_dup_exe(struct audit_krule *new, struct audit_krule *old) +{ BUG(); - return 0; + return -EINVAL; } + #endif /* CONFIG_AUDIT_WATCH */ #ifdef CONFIG_AUDIT_TREE diff --git a/kernel/audit_exe.c b/kernel/audit_exe.c index 09c436c..d704a54 100644 --- a/kernel/audit_exe.c +++ b/kernel/audit_exe.c @@ -21,93 +21,30 @@ #include #include -#include #include #include #include #include "audit.h" -struct audit_exe { - char *pathname; - unsigned long ino; - dev_t dev; -}; - -/* Translate a watch string to kernel respresentation. */ -int audit_make_exe_rule(struct audit_krule *krule, char *pathname, int len, u32 op) -{ - struct audit_exe *exe; - struct path path; - struct dentry *dentry; - unsigned long ino; - dev_t dev; - - if (pathname[0] != '/' || pathname[len-1] == '/') - return -EINVAL; - - dentry = kern_path_locked(pathname, &path); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - mutex_unlock(&path.dentry->d_inode->i_mutex); - - if (!dentry->d_inode) - return -ENOENT; - dev = dentry->d_inode->i_sb->s_dev; - ino = dentry->d_inode->i_ino; - dput(dentry); - - exe = kmalloc(sizeof(*exe), GFP_KERNEL); - if (!exe) - return -ENOMEM; - exe->ino = ino; - exe->dev = dev; - exe->pathname = pathname; - krule->exe = exe; - - return 0; -} - -void audit_remove_exe_rule(struct audit_krule *krule) -{ - struct audit_exe *exe; - - exe = krule->exe; - krule->exe = NULL; - kfree(exe->pathname); - kfree(exe); -} - -char *audit_exe_path(struct audit_exe *exe) -{ - return exe->pathname; -} - int audit_dup_exe(struct audit_krule *new, struct audit_krule *old) { - struct audit_exe *exe; - - exe = kmalloc(sizeof(*exe), GFP_KERNEL); - if (!exe) - return -ENOMEM; + struct audit_fsnotify_mark *audit_mark; + char *pathname; - exe->pathname = kstrdup(old->exe->pathname, GFP_KERNEL); - if (!exe->pathname) { - kfree(exe); - return -ENOMEM; - } + pathname = audit_mark_path(old->exe); - exe->ino = old->exe->ino; - exe->dev = old->exe->dev; - new->exe = exe; + audit_mark = audit_alloc_mark(pathname, strlen(pathname), new); + if (IS_ERR(audit_mark)) + return PTR_ERR(audit_mark); + new->exe = audit_mark; return 0; } -int audit_exe_compare(struct task_struct *tsk, struct audit_exe *exe) +int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark) { - if (tsk->mm->exe_file->f_inode->i_ino != exe->ino) - return 0; - if (tsk->mm->exe_file->f_inode->i_sb->s_dev != exe->dev) - return 0; - return 1; + unsigned long ino = tsk->mm->exe_file->f_inode->i_ino; + dev_t dev = tsk->mm->exe_file->f_inode->i_sb->s_dev; + + return audit_mark_compare(mark, ino, dev); } diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 5c1951a..30091ce 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -411,6 +411,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, size_t remain = datasz - sizeof(struct audit_rule_data); int i; char *str; + struct audit_fsnotify_mark *audit_mark; entry = audit_to_entry_common(data); if (IS_ERR(entry)) @@ -550,6 +551,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, break; case AUDIT_EXE: case AUDIT_EXE_CHILDREN: + if (entry->rule.exe || f->val > PATH_MAX) goto exit_free; str = audit_unpack_string(&bufp, &remain, f->val); @@ -559,11 +561,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, } entry->rule.buflen += f->val; - err = audit_make_exe_rule(&entry->rule, str, f->val, f->op); - if (err) { - kfree(str); + audit_mark = audit_alloc_mark(str, f->val, &entry->rule); + kfree(str); + if (IS_ERR(audit_mark)) { + err = PTR_ERR(audit_mark); goto exit_free; } + entry->rule.exe = audit_mark; break; } } @@ -646,7 +650,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) case AUDIT_EXE: case AUDIT_EXE_CHILDREN: data->buflen += data->values[i] = - audit_pack_string(&bufp, audit_exe_path(krule->exe)); + audit_pack_string(&bufp, audit_mark_path(krule->exe)); break; default: data->values[i] = f->val; @@ -706,8 +710,8 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) case AUDIT_EXE: case AUDIT_EXE_CHILDREN: /* both paths exist based on above type compare */ - if (strcmp(audit_exe_path(a->exe), - audit_exe_path(b->exe))) + if (strcmp(audit_mark_path(a->exe), + audit_mark_path(b->exe))) return 1; break; case AUDIT_UID: @@ -1008,7 +1012,7 @@ int audit_del_rule(struct audit_entry *entry) audit_remove_tree_rule(&e->rule); if (e->rule.exe) - audit_remove_exe_rule(&e->rule); + audit_remove_mark(e->rule.exe); list_del_rcu(&e->list); list_del(&e->rule.list); call_rcu(&e->rcu, audit_free_rule_rcu); -- 1.9.0