From 74c3cbe33bc077ac1159cadfea608b501e100344 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jul 2007 08:04:18 -0400 Subject: [PATCH] audit: watching subtrees New kind of audit rule predicates: "object is visible in given subtree". The part that can be sanely implemented, that is. Limitations: * if you have hardlink from outside of tree, you'd better watch it too (or just watch the object itself, obviously) * if you mount something under a watched tree, tell audit that new chunk should be added to watched subtrees * if you umount something in a watched tree and it's still mounted elsewhere, you will get matches on events happening there. New command tells audit to recalculate the trees, trimming such sources of false positives. Note that it's _not_ about path - if something mounted in several places (multiple mount, bindings, different namespaces, etc.), the match does _not_ depend on which one we are using for access. Signed-off-by: Al Viro --- kernel/audit.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'kernel/audit.h') diff --git a/kernel/audit.h b/kernel/audit.h index 95877435c347..2554bd524fd1 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -73,6 +73,9 @@ struct audit_field { struct selinux_audit_rule *se_rule; }; +struct audit_tree; +struct audit_chunk; + struct audit_krule { int vers_ops; u32 flags; @@ -86,7 +89,8 @@ struct audit_krule { struct audit_field *arch_f; /* quick access to arch field */ struct audit_field *inode_f; /* quick access to an inode field */ struct audit_watch *watch; /* associated watch */ - struct list_head rlist; /* entry in audit_watch.rules list */ + struct audit_tree *tree; /* associated watched tree */ + struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ }; struct audit_entry { @@ -130,6 +134,34 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, const char *, struct inode *); extern int selinux_audit_rule_update(void); +extern struct mutex audit_filter_mutex; +extern void audit_free_rule_rcu(struct rcu_head *); + +#ifdef CONFIG_AUDIT_TREE +extern struct audit_chunk *audit_tree_lookup(const struct inode *); +extern void audit_put_chunk(struct audit_chunk *); +extern int audit_tree_match(struct audit_chunk *, struct audit_tree *); +extern int audit_make_tree(struct audit_krule *, char *, u32); +extern int audit_add_tree_rule(struct audit_krule *); +extern int audit_remove_tree_rule(struct audit_krule *); +extern void audit_trim_trees(void); +extern int audit_tag_tree(char *old, char *new); +extern void audit_schedule_prune(void); +extern void audit_prune_trees(void); +extern const char *audit_tree_path(struct audit_tree *); +extern void audit_put_tree(struct audit_tree *); +#else +#define audit_remove_tree_rule(rule) BUG() +#define audit_add_tree_rule(rule) -EINVAL +#define audit_make_tree(rule, str, op) -EINVAL +#define audit_trim_trees() (void)0 +#define audit_put_tree(tree) (void)0 +#define audit_tag_tree(old, new) -EINVAL +#define audit_tree_path(rule) "" /* never called */ +#endif + +extern char *audit_unpack_string(void **, size_t *, size_t); + #ifdef CONFIG_AUDITSYSCALL extern int __audit_signal_info(int sig, struct task_struct *t); static inline int audit_signal_info(int sig, struct task_struct *t) -- cgit v1.2.1