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>
|
2013-05-01 03:30:32 +08:00
|
|
|
#include <uapi/linux/mqueue.h>
|
2016-06-29 00:07:50 +08:00
|
|
|
#include <linux/tty.h>
|
2005-12-16 02:33:52 +08:00
|
|
|
|
2013-05-01 03:30:32 +08:00
|
|
|
/* AUDIT_NAMES is the number of slots we reserve in the audit_context
|
|
|
|
* for saving names from getname(). If we get more names we will allocate
|
|
|
|
* a name dynamically and also add those to the list anchored by names_list. */
|
|
|
|
#define AUDIT_NAMES 5
|
|
|
|
|
2005-12-16 02:33:52 +08:00
|
|
|
/* 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;
|
2015-08-06 04:29:36 +08:00
|
|
|
struct audit_fsnotify_mark;
|
[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
|
|
|
};
|
|
|
|
|
2013-05-01 03:30:32 +08:00
|
|
|
struct audit_cap_data {
|
|
|
|
kernel_cap_t permitted;
|
|
|
|
kernel_cap_t inheritable;
|
|
|
|
union {
|
|
|
|
unsigned int fE; /* effective bit of file cap */
|
|
|
|
kernel_cap_t effective; /* effective set of process */
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2015-01-22 13:00:23 +08:00
|
|
|
/* When fs/namei.c:getname() is called, we store the pointer in name and bump
|
|
|
|
* the refcnt in the associated filename struct.
|
2013-05-01 03:30:32 +08:00
|
|
|
*
|
|
|
|
* Further, in fs/namei.c:path_lookup() we store the inode and device.
|
|
|
|
*/
|
|
|
|
struct audit_names {
|
|
|
|
struct list_head list; /* audit_context->names_list */
|
|
|
|
|
|
|
|
struct filename *name;
|
|
|
|
int name_len; /* number of chars to log */
|
2013-07-09 06:59:36 +08:00
|
|
|
bool hidden; /* don't log this record */
|
2013-05-01 03:30:32 +08:00
|
|
|
|
|
|
|
unsigned long ino;
|
|
|
|
dev_t dev;
|
|
|
|
umode_t mode;
|
|
|
|
kuid_t uid;
|
|
|
|
kgid_t gid;
|
|
|
|
dev_t rdev;
|
|
|
|
u32 osid;
|
|
|
|
struct audit_cap_data fcap;
|
|
|
|
unsigned int fcap_ver;
|
|
|
|
unsigned char type; /* record type */
|
|
|
|
/*
|
|
|
|
* This was an allocated audit_names and not from the array of
|
|
|
|
* names allocated in the task audit context. Thus this name
|
|
|
|
* should be freed on syscall exit.
|
|
|
|
*/
|
|
|
|
bool should_free;
|
|
|
|
};
|
|
|
|
|
audit: Audit proc/<pid>/cmdline aka proctitle
During an audit event, cache and print the value of the process's
proctitle value (proc/<pid>/cmdline). This is useful in situations
where processes are started via fork'd virtual machines where the
comm field is incorrect. Often times, setting the comm field still
is insufficient as the comm width is not very wide and most
virtual machine "package names" do not fit. Also, during execution,
many threads have their comm field set as well. By tying it back to
the global cmdline value for the process, audit records will be more
complete in systems with these properties. An example of where this
is useful and applicable is in the realm of Android. With Android,
their is no fork/exec for VM instances. The bare, preloaded Dalvik
VM listens for a fork and specialize request. When this request comes
in, the VM forks, and the loads the specific application (specializing).
This was done to take advantage of COW and to not require a load of
basic packages by the VM on very app spawn. When this spawn occurs,
the package name is set via setproctitle() and shows up in procfs.
Many of these package names are longer then 16 bytes, the historical
width of task->comm. Having the cmdline in the audit records will
couple the application back to the record directly. Also, on my
Debian development box, some audit records were more useful then
what was printed under comm.
The cached proctitle is tied to the life-cycle of the audit_context
structure and is built on demand.
Proctitle is controllable by userspace, and thus should not be trusted.
It is meant as an aid to assist in debugging. The proctitle event is
emitted during syscall audits, and can be filtered with auditctl.
Example:
type=AVC msg=audit(1391217013.924:386): avc: denied { getattr } for pid=1971 comm="mkdir" name="/" dev="selinuxfs" ino=1 scontext=system_u:system_r:consolekit_t:s0-s0:c0.c255 tcontext=system_u:object_r:security_t:s0 tclass=filesystem
type=SYSCALL msg=audit(1391217013.924:386): arch=c000003e syscall=137 success=yes exit=0 a0=7f019dfc8bd7 a1=7fffa6aed2c0 a2=fffffffffff4bd25 a3=7fffa6aed050 items=0 ppid=1967 pid=1971 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="mkdir" exe="/bin/mkdir" subj=system_u:system_r:consolekit_t:s0-s0:c0.c255 key=(null)
type=UNKNOWN[1327] msg=audit(1391217013.924:386): proctitle=6D6B646972002D70002F7661722F72756E2F636F6E736F6C65
Acked-by: Steve Grubb <sgrubb@redhat.com> (wrt record formating)
Signed-off-by: William Roberts <wroberts@tresys.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
2014-02-12 02:12:01 +08:00
|
|
|
struct audit_proctitle {
|
|
|
|
int len; /* length of the cmdline field. */
|
|
|
|
char *value; /* the cmdline field */
|
|
|
|
};
|
|
|
|
|
2013-05-01 03:30:32 +08:00
|
|
|
/* The per-task audit context. */
|
|
|
|
struct audit_context {
|
|
|
|
int dummy; /* must be the first element */
|
|
|
|
int in_syscall; /* 1 if task is in a syscall */
|
|
|
|
enum audit_state state, current_state;
|
|
|
|
unsigned int serial; /* serial number for record */
|
|
|
|
int major; /* syscall number */
|
|
|
|
struct timespec ctime; /* time of syscall entry */
|
|
|
|
unsigned long argv[4]; /* syscall arguments */
|
|
|
|
long return_code;/* syscall return code */
|
|
|
|
u64 prio;
|
|
|
|
int return_valid; /* return code is valid */
|
|
|
|
/*
|
|
|
|
* The names_list is the list of all audit_names collected during this
|
|
|
|
* syscall. The first AUDIT_NAMES entries in the names_list will
|
|
|
|
* actually be from the preallocated_names array for performance
|
|
|
|
* reasons. Except during allocation they should never be referenced
|
|
|
|
* through the preallocated_names array and should only be found/used
|
|
|
|
* by running the names_list.
|
|
|
|
*/
|
|
|
|
struct audit_names preallocated_names[AUDIT_NAMES];
|
|
|
|
int name_count; /* total records in names_list */
|
|
|
|
struct list_head names_list; /* struct audit_names->list anchor */
|
|
|
|
char *filterkey; /* key for rule that triggered record */
|
|
|
|
struct path pwd;
|
|
|
|
struct audit_aux_data *aux;
|
|
|
|
struct audit_aux_data *aux_pids;
|
|
|
|
struct sockaddr_storage *sockaddr;
|
|
|
|
size_t sockaddr_len;
|
|
|
|
/* Save things to print about task_struct */
|
|
|
|
pid_t pid, ppid;
|
|
|
|
kuid_t uid, euid, suid, fsuid;
|
|
|
|
kgid_t gid, egid, sgid, fsgid;
|
|
|
|
unsigned long personality;
|
|
|
|
int arch;
|
|
|
|
|
|
|
|
pid_t target_pid;
|
|
|
|
kuid_t target_auid;
|
|
|
|
kuid_t target_uid;
|
|
|
|
unsigned int target_sessionid;
|
|
|
|
u32 target_sid;
|
|
|
|
char target_comm[TASK_COMM_LEN];
|
|
|
|
|
|
|
|
struct audit_tree_refs *trees, *first_trees;
|
|
|
|
struct list_head killed_trees;
|
|
|
|
int tree_count;
|
|
|
|
|
|
|
|
int type;
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
int nargs;
|
|
|
|
long args[6];
|
|
|
|
} socketcall;
|
|
|
|
struct {
|
|
|
|
kuid_t uid;
|
|
|
|
kgid_t gid;
|
|
|
|
umode_t mode;
|
|
|
|
u32 osid;
|
|
|
|
int has_perm;
|
|
|
|
uid_t perm_uid;
|
|
|
|
gid_t perm_gid;
|
|
|
|
umode_t perm_mode;
|
|
|
|
unsigned long qbytes;
|
|
|
|
} ipc;
|
|
|
|
struct {
|
|
|
|
mqd_t mqdes;
|
|
|
|
struct mq_attr mqstat;
|
|
|
|
} mq_getsetattr;
|
|
|
|
struct {
|
|
|
|
mqd_t mqdes;
|
|
|
|
int sigev_signo;
|
|
|
|
} mq_notify;
|
|
|
|
struct {
|
|
|
|
mqd_t mqdes;
|
|
|
|
size_t msg_len;
|
|
|
|
unsigned int msg_prio;
|
|
|
|
struct timespec abs_timeout;
|
|
|
|
} mq_sendrecv;
|
|
|
|
struct {
|
|
|
|
int oflag;
|
|
|
|
umode_t mode;
|
|
|
|
struct mq_attr attr;
|
|
|
|
} mq_open;
|
|
|
|
struct {
|
|
|
|
pid_t pid;
|
|
|
|
struct audit_cap_data cap;
|
|
|
|
} capset;
|
|
|
|
struct {
|
|
|
|
int fd;
|
|
|
|
int flags;
|
|
|
|
} mmap;
|
2013-10-31 05:56:13 +08:00
|
|
|
struct {
|
|
|
|
int argc;
|
|
|
|
} execve;
|
2017-02-05 02:10:38 +08:00
|
|
|
struct {
|
|
|
|
char *name;
|
|
|
|
} module;
|
2013-05-01 03:30:32 +08:00
|
|
|
};
|
|
|
|
int fds[2];
|
audit: Audit proc/<pid>/cmdline aka proctitle
During an audit event, cache and print the value of the process's
proctitle value (proc/<pid>/cmdline). This is useful in situations
where processes are started via fork'd virtual machines where the
comm field is incorrect. Often times, setting the comm field still
is insufficient as the comm width is not very wide and most
virtual machine "package names" do not fit. Also, during execution,
many threads have their comm field set as well. By tying it back to
the global cmdline value for the process, audit records will be more
complete in systems with these properties. An example of where this
is useful and applicable is in the realm of Android. With Android,
their is no fork/exec for VM instances. The bare, preloaded Dalvik
VM listens for a fork and specialize request. When this request comes
in, the VM forks, and the loads the specific application (specializing).
This was done to take advantage of COW and to not require a load of
basic packages by the VM on very app spawn. When this spawn occurs,
the package name is set via setproctitle() and shows up in procfs.
Many of these package names are longer then 16 bytes, the historical
width of task->comm. Having the cmdline in the audit records will
couple the application back to the record directly. Also, on my
Debian development box, some audit records were more useful then
what was printed under comm.
The cached proctitle is tied to the life-cycle of the audit_context
structure and is built on demand.
Proctitle is controllable by userspace, and thus should not be trusted.
It is meant as an aid to assist in debugging. The proctitle event is
emitted during syscall audits, and can be filtered with auditctl.
Example:
type=AVC msg=audit(1391217013.924:386): avc: denied { getattr } for pid=1971 comm="mkdir" name="/" dev="selinuxfs" ino=1 scontext=system_u:system_r:consolekit_t:s0-s0:c0.c255 tcontext=system_u:object_r:security_t:s0 tclass=filesystem
type=SYSCALL msg=audit(1391217013.924:386): arch=c000003e syscall=137 success=yes exit=0 a0=7f019dfc8bd7 a1=7fffa6aed2c0 a2=fffffffffff4bd25 a3=7fffa6aed050 items=0 ppid=1967 pid=1971 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="mkdir" exe="/bin/mkdir" subj=system_u:system_r:consolekit_t:s0-s0:c0.c255 key=(null)
type=UNKNOWN[1327] msg=audit(1391217013.924:386): proctitle=6D6B646972002D70002F7661722F72756E2F636F6E736F6C65
Acked-by: Steve Grubb <sgrubb@redhat.com> (wrt record formating)
Signed-off-by: William Roberts <wroberts@tresys.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
2014-02-12 02:12:01 +08:00
|
|
|
struct audit_proctitle proctitle;
|
2013-05-01 03:30:32 +08:00
|
|
|
};
|
|
|
|
|
2014-01-15 02:33:13 +08:00
|
|
|
extern u32 audit_ever_enabled;
|
2008-04-27 17:39:17 +08:00
|
|
|
|
2013-05-01 03:30:32 +08:00
|
|
|
extern void audit_copy_inode(struct audit_names *name,
|
|
|
|
const struct dentry *dentry,
|
2015-12-25 00:09:39 +08:00
|
|
|
struct inode *inode);
|
2013-05-01 03:30:32 +08:00
|
|
|
extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
|
|
|
|
kernel_cap_t *cap);
|
|
|
|
extern void audit_log_name(struct audit_context *context,
|
2016-11-21 09:36:51 +08:00
|
|
|
struct audit_names *n, const struct path *path,
|
2013-05-01 03:30:32 +08:00
|
|
|
int record_num, int *call_panic);
|
2008-04-27 17:39:17 +08:00
|
|
|
|
audit: fix auditd/kernel connection state tracking
What started as a rather straightforward race condition reported by
Dmitry using the syzkaller fuzzer ended up revealing some major
problems with how the audit subsystem managed its netlink sockets and
its connection with the userspace audit daemon. Fixing this properly
had quite the cascading effect and what we are left with is this rather
large and complicated patch. My initial goal was to try and decompose
this patch into multiple smaller patches, but the way these changes
are intertwined makes it difficult to split these changes into
meaningful pieces that don't break or somehow make things worse for
the intermediate states.
The patch makes a number of changes, but the most significant are
highlighted below:
* The auditd tracking variables, e.g. audit_sock, are now gone and
replaced by a RCU/spin_lock protected variable auditd_conn which is
a structure containing all of the auditd tracking information.
* We no longer track the auditd sock directly, instead we track it
via the network namespace in which it resides and we use the audit
socket associated with that namespace. In spirit, this is what the
code was trying to do prior to this patch (at least I think that is
what the original authors intended), but it was done rather poorly
and added a layer of obfuscation that only masked the underlying
problems.
* Big backlog queue cleanup, again. In v4.10 we made some pretty big
changes to how the audit backlog queues work, here we haven't changed
the queue design so much as cleaned up the implementation. Brought
about by the locking changes, we've simplified kauditd_thread() quite
a bit by consolidating the queue handling into a new helper function,
kauditd_send_queue(), which allows us to eliminate a lot of very
similar code and makes the looping logic in kauditd_thread() clearer.
* All netlink messages sent to auditd are now sent via
auditd_send_unicast_skb(). Other than just making sense, this makes
the lock handling easier.
* Change the audit_log_start() sleep behavior so that we never sleep
on auditd events (unchanged) or if the caller is holding the
audit_cmd_mutex (changed). Previously we didn't sleep if the caller
was auditd or if the message type fell between a certain range; the
type check was a poor effort of doing what the cmd_mutex check now
does. Richard Guy Briggs originally proposed not sleeping the
cmd_mutex owner several years ago but his patch wasn't acceptable
at the time. At least the idea lives on here.
* A problem with the lost record counter has been resolved. Steve
Grubb and I both happened to notice this problem and according to
some quick testing by Steve, this problem goes back quite some time.
It's largely a harmless problem, although it may have left some
careful sysadmins quite puzzled.
Cc: <stable@vger.kernel.org> # 4.10.x-
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2017-03-21 23:26:35 +08:00
|
|
|
extern int auditd_test_task(const struct task_struct *task);
|
2005-12-16 02:33:52 +08:00
|
|
|
|
[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);
|
2013-08-14 23:32:45 +08:00
|
|
|
extern struct sk_buff *audit_make_reply(__u32 portid, int seq, int type,
|
|
|
|
int done, int multi,
|
|
|
|
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 {
|
2013-08-14 23:32:45 +08:00
|
|
|
__u32 portid;
|
2014-03-01 02:49:05 +08:00
|
|
|
struct net *net;
|
2006-05-22 13:09:24 +08:00
|
|
|
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;
|
2015-08-06 04:29:36 +08:00
|
|
|
extern int audit_del_rule(struct audit_entry *);
|
[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 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);
|
|
|
|
|
2015-02-23 10:20:00 +08:00
|
|
|
extern void audit_log_d_path_exe(struct audit_buffer *ab,
|
|
|
|
struct mm_struct *mm);
|
|
|
|
|
2016-06-29 00:07:50 +08:00
|
|
|
extern struct tty_struct *audit_get_tty(struct task_struct *tsk);
|
|
|
|
extern void audit_put_tty(struct tty_struct *tty);
|
|
|
|
|
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);
|
2015-08-06 04:29:36 +08:00
|
|
|
|
|
|
|
extern struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pathname, int len);
|
|
|
|
extern char *audit_mark_path(struct audit_fsnotify_mark *mark);
|
|
|
|
extern void audit_remove_mark(struct audit_fsnotify_mark *audit_mark);
|
|
|
|
extern void audit_remove_mark_rule(struct audit_krule *krule);
|
|
|
|
extern int audit_mark_compare(struct audit_fsnotify_mark *mark, unsigned long ino, dev_t dev);
|
2015-08-06 04:29:37 +08:00
|
|
|
extern int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old);
|
|
|
|
extern int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark);
|
2015-08-06 04:29:36 +08:00
|
|
|
|
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
|
|
|
|
|
2015-08-06 04:29:36 +08:00
|
|
|
#define audit_alloc_mark(k, p, l) (ERR_PTR(-EINVAL))
|
|
|
|
#define audit_mark_path(m) ""
|
|
|
|
#define audit_remove_mark(m)
|
|
|
|
#define audit_remove_mark_rule(k)
|
|
|
|
#define audit_mark_compare(m, i, d) 0
|
2015-08-06 04:29:37 +08:00
|
|
|
#define audit_exe_compare(t, m) (-EINVAL)
|
|
|
|
#define audit_dupe_exe(n, o) (-EINVAL)
|
2009-12-18 09:12:06 +08:00
|
|
|
#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 *);
|
2015-11-04 21:23:51 +08:00
|
|
|
extern bool audit_tree_match(struct audit_chunk *, struct audit_tree *);
|
[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 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;
|
|
|
|
|
2016-06-25 04:35:46 +08:00
|
|
|
extern int audit_filter(int msgtype, unsigned int listtype);
|
|
|
|
|
2006-05-25 22:19:47 +08:00
|
|
|
#ifdef CONFIG_AUDITSYSCALL
|
2017-03-28 02:30:06 +08:00
|
|
|
extern int audit_signal_info(int sig, struct task_struct *t);
|
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;
|