2005-12-16 02:33:52 +08:00
|
|
|
/* audit -- definition of audit_context structure and supporting types
|
|
|
|
*
|
|
|
|
* Copyright 2003-2004 Red Hat, Inc.
|
|
|
|
* Copyright 2005 Hewlett-Packard Development Company, L.P.
|
|
|
|
* Copyright 2005 IBM Corporation
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <linux/audit.h>
|
2006-05-22 13:09:24 +08:00
|
|
|
#include <linux/skbuff.h>
|
2005-12-16 02:33:52 +08:00
|
|
|
|
|
|
|
/* 0 = no checking
|
|
|
|
1 = put_count checking
|
|
|
|
2 = verbose put_count checking
|
|
|
|
*/
|
|
|
|
#define AUDIT_DEBUG 0
|
|
|
|
|
|
|
|
/* At task start time, the audit_state is set in the audit_context using
|
|
|
|
a per-task filter. At syscall entry, the audit_state is augmented by
|
|
|
|
the syscall filter. */
|
|
|
|
enum audit_state {
|
|
|
|
AUDIT_DISABLED, /* Do not create per-task audit_context.
|
|
|
|
* No syscall-specific audit records can
|
|
|
|
* be generated. */
|
|
|
|
AUDIT_BUILD_CONTEXT, /* Create the per-task audit_context,
|
2012-01-04 03:23:06 +08:00
|
|
|
* and fill it in at syscall
|
2005-12-16 02:33:52 +08:00
|
|
|
* entry time. This makes a full
|
|
|
|
* syscall record available if some
|
|
|
|
* other part of the kernel decides it
|
|
|
|
* should be recorded. */
|
|
|
|
AUDIT_RECORD_CONTEXT /* Create the per-task audit_context,
|
|
|
|
* always fill it in at syscall entry
|
|
|
|
* time, and always write out the audit
|
|
|
|
* record at syscall exit time. */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Rule lists */
|
2009-06-12 02:31:36 +08:00
|
|
|
struct audit_watch;
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
struct audit_tree;
|
|
|
|
struct audit_chunk;
|
|
|
|
|
2005-12-16 02:33:52 +08:00
|
|
|
struct audit_entry {
|
2006-02-08 01:05:27 +08:00
|
|
|
struct list_head list;
|
|
|
|
struct rcu_head rcu;
|
|
|
|
struct audit_krule rule;
|
2005-12-16 02:33:52 +08:00
|
|
|
};
|
|
|
|
|
2008-04-27 17:39:17 +08:00
|
|
|
extern int audit_ever_enabled;
|
|
|
|
|
2005-12-16 02:33:52 +08:00
|
|
|
extern int audit_pid;
|
|
|
|
|
[PATCH] audit: path-based rules
In this implementation, audit registers inotify watches on the parent
directories of paths specified in audit rules. When audit's inotify
event handler is called, it updates any affected rules based on the
filesystem event. If the parent directory is renamed, removed, or its
filesystem is unmounted, audit removes all rules referencing that
inotify watch.
To keep things simple, this implementation limits location-based
auditing to the directory entries in an existing directory. Given
a path-based rule for /foo/bar/passwd, the following table applies:
passwd modified -- audit event logged
passwd replaced -- audit event logged, rules list updated
bar renamed -- rule removed
foo renamed -- untracked, meaning that the rule now applies to
the new location
Audit users typically want to have many rules referencing filesystem
objects, which can significantly impact filtering performance. This
patch also adds an inode-number-based rule hash to mitigate this
situation.
The patch is relative to the audit git tree:
http://kernel.org/git/?p=linux/kernel/git/viro/audit-current.git;a=summary
and uses the inotify kernel API:
http://lkml.org/lkml/2006/6/1/145
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2006-04-08 04:55:56 +08:00
|
|
|
#define AUDIT_INODE_BUCKETS 32
|
|
|
|
extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
|
|
|
|
|
|
|
|
static inline int audit_hash_ino(u32 ino)
|
|
|
|
{
|
|
|
|
return (ino & (AUDIT_INODE_BUCKETS-1));
|
|
|
|
}
|
|
|
|
|
2012-10-11 03:25:25 +08:00
|
|
|
/* Indicates that audit should log the full pathname. */
|
|
|
|
#define AUDIT_NAME_FULL -1
|
|
|
|
|
2006-09-01 07:26:40 +08:00
|
|
|
extern int audit_match_class(int class, unsigned syscall);
|
[PATCH] audit: path-based rules
In this implementation, audit registers inotify watches on the parent
directories of paths specified in audit rules. When audit's inotify
event handler is called, it updates any affected rules based on the
filesystem event. If the parent directory is renamed, removed, or its
filesystem is unmounted, audit removes all rules referencing that
inotify watch.
To keep things simple, this implementation limits location-based
auditing to the directory entries in an existing directory. Given
a path-based rule for /foo/bar/passwd, the following table applies:
passwd modified -- audit event logged
passwd replaced -- audit event logged, rules list updated
bar renamed -- rule removed
foo renamed -- untracked, meaning that the rule now applies to
the new location
Audit users typically want to have many rules referencing filesystem
objects, which can significantly impact filtering performance. This
patch also adds an inode-number-based rule hash to mitigate this
situation.
The patch is relative to the audit git tree:
http://kernel.org/git/?p=linux/kernel/git/viro/audit-current.git;a=summary
and uses the inotify kernel API:
http://lkml.org/lkml/2006/6/1/145
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2006-04-08 04:55:56 +08:00
|
|
|
extern int audit_comparator(const u32 left, const u32 op, const u32 right);
|
2012-09-11 17:18:08 +08:00
|
|
|
extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
|
|
|
|
extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
|
2012-10-11 03:25:23 +08:00
|
|
|
extern int parent_len(const char *path);
|
2012-10-11 03:25:25 +08:00
|
|
|
extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
|
2006-05-22 13:09:24 +08:00
|
|
|
extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
|
|
|
|
int done, int multi,
|
2010-10-21 08:23:50 +08:00
|
|
|
const void *payload, int size);
|
2005-12-16 02:33:52 +08:00
|
|
|
extern void audit_panic(const char *message);
|
2006-03-11 08:14:06 +08:00
|
|
|
|
2006-05-22 13:09:24 +08:00
|
|
|
struct audit_netlink_list {
|
|
|
|
int pid;
|
|
|
|
struct sk_buff_head q;
|
|
|
|
};
|
|
|
|
|
|
|
|
int audit_send_list(void *);
|
|
|
|
|
2006-03-11 08:14:06 +08:00
|
|
|
extern int selinux_audit_rule_update(void);
|
2006-05-25 22:19:47 +08:00
|
|
|
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
extern struct mutex audit_filter_mutex;
|
|
|
|
extern void audit_free_rule_rcu(struct rcu_head *);
|
2008-04-27 17:39:17 +08:00
|
|
|
extern struct list_head audit_filter_list[];
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
|
2009-12-18 09:12:06 +08:00
|
|
|
extern struct audit_entry *audit_dupe_rule(struct audit_krule *old);
|
|
|
|
|
2009-06-12 02:31:36 +08:00
|
|
|
/* audit watch functions */
|
2009-12-18 09:12:06 +08:00
|
|
|
#ifdef CONFIG_AUDIT_WATCH
|
2009-06-12 02:31:36 +08:00
|
|
|
extern void audit_put_watch(struct audit_watch *watch);
|
|
|
|
extern void audit_get_watch(struct audit_watch *watch);
|
|
|
|
extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op);
|
2009-12-18 09:12:04 +08:00
|
|
|
extern int audit_add_watch(struct audit_krule *krule, struct list_head **list);
|
2009-12-18 09:12:05 +08:00
|
|
|
extern void audit_remove_watch_rule(struct audit_krule *krule);
|
2009-06-12 02:31:36 +08:00
|
|
|
extern char *audit_watch_path(struct audit_watch *watch);
|
2009-12-18 09:12:04 +08:00
|
|
|
extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev);
|
2009-12-18 09:12:06 +08:00
|
|
|
#else
|
|
|
|
#define audit_put_watch(w) {}
|
|
|
|
#define audit_get_watch(w) {}
|
|
|
|
#define audit_to_watch(k, p, l, o) (-EINVAL)
|
|
|
|
#define audit_add_watch(k, l) (-EINVAL)
|
|
|
|
#define audit_remove_watch_rule(k) BUG()
|
|
|
|
#define audit_watch_path(w) ""
|
|
|
|
#define audit_watch_compare(w, i, d) 0
|
|
|
|
|
|
|
|
#endif /* CONFIG_AUDIT_WATCH */
|
2009-06-12 02:31:36 +08:00
|
|
|
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
#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 const char *audit_tree_path(struct audit_tree *);
|
|
|
|
extern void audit_put_tree(struct audit_tree *);
|
2009-06-24 12:02:38 +08:00
|
|
|
extern void audit_kill_trees(struct list_head *);
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
#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 */
|
2009-06-24 12:02:38 +08:00
|
|
|
#define audit_kill_trees(list) BUG()
|
[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 <viro@zeniv.linux.org.uk>
2007-07-22 20:04:18 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
extern char *audit_unpack_string(void **, size_t *, size_t);
|
|
|
|
|
2008-04-27 17:39:17 +08:00
|
|
|
extern pid_t audit_sig_pid;
|
2012-02-08 08:53:48 +08:00
|
|
|
extern kuid_t audit_sig_uid;
|
2008-04-27 17:39:17 +08:00
|
|
|
extern u32 audit_sig_sid;
|
|
|
|
|
2006-05-25 22:19:47 +08:00
|
|
|
#ifdef CONFIG_AUDITSYSCALL
|
2007-03-30 06:01:04 +08:00
|
|
|
extern int __audit_signal_info(int sig, struct task_struct *t);
|
|
|
|
static inline int audit_signal_info(int sig, struct task_struct *t)
|
2006-05-25 22:19:47 +08:00
|
|
|
{
|
2007-03-30 06:01:04 +08:00
|
|
|
if (unlikely((audit_pid && t->tgid == audit_pid) ||
|
|
|
|
(audit_signals && !audit_dummy_context())))
|
|
|
|
return __audit_signal_info(sig, t);
|
|
|
|
return 0;
|
2006-05-25 22:19:47 +08:00
|
|
|
}
|
2008-12-15 12:45:27 +08:00
|
|
|
extern void audit_filter_inodes(struct task_struct *, struct audit_context *);
|
2009-06-24 12:02:38 +08:00
|
|
|
extern struct list_head *audit_killed_trees(void);
|
2006-05-25 22:19:47 +08:00
|
|
|
#else
|
2007-03-30 06:01:04 +08:00
|
|
|
#define audit_signal_info(s,t) AUDIT_DISABLED
|
[PATCH] audit: path-based rules
In this implementation, audit registers inotify watches on the parent
directories of paths specified in audit rules. When audit's inotify
event handler is called, it updates any affected rules based on the
filesystem event. If the parent directory is renamed, removed, or its
filesystem is unmounted, audit removes all rules referencing that
inotify watch.
To keep things simple, this implementation limits location-based
auditing to the directory entries in an existing directory. Given
a path-based rule for /foo/bar/passwd, the following table applies:
passwd modified -- audit event logged
passwd replaced -- audit event logged, rules list updated
bar renamed -- rule removed
foo renamed -- untracked, meaning that the rule now applies to
the new location
Audit users typically want to have many rules referencing filesystem
objects, which can significantly impact filtering performance. This
patch also adds an inode-number-based rule hash to mitigate this
situation.
The patch is relative to the audit git tree:
http://kernel.org/git/?p=linux/kernel/git/viro/audit-current.git;a=summary
and uses the inotify kernel API:
http://lkml.org/lkml/2006/6/1/145
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2006-04-08 04:55:56 +08:00
|
|
|
#define audit_filter_inodes(t,c) AUDIT_DISABLED
|
2006-05-25 22:19:47 +08:00
|
|
|
#endif
|
2009-06-24 12:02:38 +08:00
|
|
|
|
|
|
|
extern struct mutex audit_cmd_mutex;
|