audit.h 11.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* 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>
24
#include <linux/skbuff.h>
25
#include <uapi/linux/mqueue.h>
26
#include <linux/tty.h>
27

28 29 30 31 32
/* 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

33 34 35 36 37 38 39 40
/* 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,
41
				 * and fill it in at syscall
42 43 44 45 46 47 48 49 50 51 52
				 * 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 */
53
struct audit_watch;
54
struct audit_fsnotify_mark;
A
Al Viro 已提交
55 56 57
struct audit_tree;
struct audit_chunk;

58
struct audit_entry {
59 60 61
	struct list_head	list;
	struct rcu_head		rcu;
	struct audit_krule	rule;
62 63
};

64 65 66 67 68 69 70
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 */
	};
71
	kernel_cap_t		ambient;
72 73
};

74 75
/* When fs/namei.c:getname() is called, we store the pointer in name and bump
 * the refcnt in the associated filename struct.
76 77 78 79 80 81 82 83
 *
 * 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 */
84
	bool			hidden;		/* don't log this record */
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

	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;
};

104 105 106 107 108
struct audit_proctitle {
	int	len;	/* length of the cmdline field. */
	char	*value;	/* the cmdline field */
};

109 110 111 112 113 114 115
/* 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 */
116
	struct timespec64   ctime;      /* time of syscall entry */
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
	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;
185
			struct timespec64	abs_timeout;
186 187 188 189 190 191 192 193 194 195 196 197 198 199
		} 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;
200 201 202
		struct {
			int			argc;
		} execve;
203 204 205
		struct {
			char			*name;
		} module;
206 207
	};
	int fds[2];
208
	struct audit_proctitle proctitle;
209 210
};

211
extern u32 audit_ever_enabled;
212

213 214
extern void audit_copy_inode(struct audit_names *name,
			     const struct dentry *dentry,
215
			     struct inode *inode);
216 217 218
extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
			  kernel_cap_t *cap);
extern void audit_log_name(struct audit_context *context,
219
			   struct audit_names *n, const struct path *path,
220
			   int record_num, int *call_panic);
221

222
extern int auditd_test_task(struct task_struct *task);
223

A
Amy Griffis 已提交
224 225 226 227 228 229 230 231
#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));
}

232 233 234
/* Indicates that audit should log the full pathname. */
#define AUDIT_NAME_FULL -1

A
Al Viro 已提交
235
extern int audit_match_class(int class, unsigned syscall);
A
Amy Griffis 已提交
236
extern int audit_comparator(const u32 left, const u32 op, const u32 right);
237 238
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);
239
extern int parent_len(const char *path);
240
extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
241
extern struct sk_buff *audit_make_reply(int seq, int type, int done, int multi,
242
					const void *payload, int size);
243
extern void		    audit_panic(const char *message);
244

245
struct audit_netlink_list {
246
	__u32 portid;
247
	struct net *net;
248 249 250
	struct sk_buff_head q;
};

D
Derek Robson 已提交
251
int audit_send_list(void *_dest);
252

253
extern int selinux_audit_rule_update(void);
254

A
Al Viro 已提交
255
extern struct mutex audit_filter_mutex;
D
Derek Robson 已提交
256 257
extern int audit_del_rule(struct audit_entry *entry);
extern void audit_free_rule_rcu(struct rcu_head *head);
258
extern struct list_head audit_filter_list[];
A
Al Viro 已提交
259

E
Eric Paris 已提交
260 261
extern struct audit_entry *audit_dupe_rule(struct audit_krule *old);

262 263 264
extern void audit_log_d_path_exe(struct audit_buffer *ab,
				 struct mm_struct *mm);

265 266 267
extern struct tty_struct *audit_get_tty(struct task_struct *tsk);
extern void audit_put_tty(struct tty_struct *tty);

268
/* audit watch functions */
E
Eric Paris 已提交
269
#ifdef CONFIG_AUDIT_WATCH
270 271 272
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);
273
extern int audit_add_watch(struct audit_krule *krule, struct list_head **list);
274
extern void audit_remove_watch_rule(struct audit_krule *krule);
275
extern char *audit_watch_path(struct audit_watch *watch);
276
extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev);
277 278 279 280 281 282

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);
283 284
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);
285

E
Eric Paris 已提交
286 287 288 289 290 291 292 293 294
#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

295 296 297 298 299
#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
300 301
#define audit_exe_compare(t, m) (-EINVAL)
#define audit_dupe_exe(n, o) (-EINVAL)
E
Eric Paris 已提交
302
#endif /* CONFIG_AUDIT_WATCH */
303

A
Al Viro 已提交
304
#ifdef CONFIG_AUDIT_TREE
D
Derek Robson 已提交
305 306 307 308 309 310
extern struct audit_chunk *audit_tree_lookup(const struct inode *inode);
extern void audit_put_chunk(struct audit_chunk *chunk);
extern bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree);
extern int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op);
extern int audit_add_tree_rule(struct audit_krule *rule);
extern int audit_remove_tree_rule(struct audit_krule *rule);
A
Al Viro 已提交
311 312
extern void audit_trim_trees(void);
extern int audit_tag_tree(char *old, char *new);
D
Derek Robson 已提交
313 314 315
extern const char *audit_tree_path(struct audit_tree *tree);
extern void audit_put_tree(struct audit_tree *tree);
extern void audit_kill_trees(struct list_head *list);
A
Al Viro 已提交
316 317 318 319 320 321 322 323
#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 */
A
Al Viro 已提交
324
#define audit_kill_trees(list) BUG()
A
Al Viro 已提交
325 326
#endif

D
Derek Robson 已提交
327
extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len);
A
Al Viro 已提交
328

329
extern pid_t audit_sig_pid;
330
extern kuid_t audit_sig_uid;
331 332
extern u32 audit_sig_sid;

333 334
extern int audit_filter(int msgtype, unsigned int listtype);

335
#ifdef CONFIG_AUDITSYSCALL
336
extern int audit_signal_info(int sig, struct task_struct *t);
D
Derek Robson 已提交
337
extern void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx);
A
Al Viro 已提交
338
extern struct list_head *audit_killed_trees(void);
339
#else
A
Amy Griffis 已提交
340
#define audit_signal_info(s,t) AUDIT_DISABLED
A
Amy Griffis 已提交
341
#define audit_filter_inodes(t,c) AUDIT_DISABLED
342
#endif
A
Al Viro 已提交
343 344

extern struct mutex audit_cmd_mutex;