xref: /openbmc/linux/kernel/audit.h (revision b24a30a7305418ff138ff51776fc555ec57c011a)
1fe7752baSDavid Woodhouse /* audit -- definition of audit_context structure and supporting types
2fe7752baSDavid Woodhouse  *
3fe7752baSDavid Woodhouse  * Copyright 2003-2004 Red Hat, Inc.
4fe7752baSDavid Woodhouse  * Copyright 2005 Hewlett-Packard Development Company, L.P.
5fe7752baSDavid Woodhouse  * Copyright 2005 IBM Corporation
6fe7752baSDavid Woodhouse  *
7fe7752baSDavid Woodhouse  * This program is free software; you can redistribute it and/or modify
8fe7752baSDavid Woodhouse  * it under the terms of the GNU General Public License as published by
9fe7752baSDavid Woodhouse  * the Free Software Foundation; either version 2 of the License, or
10fe7752baSDavid Woodhouse  * (at your option) any later version.
11fe7752baSDavid Woodhouse  *
12fe7752baSDavid Woodhouse  * This program is distributed in the hope that it will be useful,
13fe7752baSDavid Woodhouse  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14fe7752baSDavid Woodhouse  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15fe7752baSDavid Woodhouse  * GNU General Public License for more details.
16fe7752baSDavid Woodhouse  *
17fe7752baSDavid Woodhouse  * You should have received a copy of the GNU General Public License
18fe7752baSDavid Woodhouse  * along with this program; if not, write to the Free Software
19fe7752baSDavid Woodhouse  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20fe7752baSDavid Woodhouse  */
21fe7752baSDavid Woodhouse 
22fe7752baSDavid Woodhouse #include <linux/fs.h>
23fe7752baSDavid Woodhouse #include <linux/audit.h>
249044e6bcSAl Viro #include <linux/skbuff.h>
25*b24a30a7SEric Paris #include <uapi/linux/mqueue.h>
26fe7752baSDavid Woodhouse 
27fe7752baSDavid Woodhouse /* 0 = no checking
28fe7752baSDavid Woodhouse    1 = put_count checking
29fe7752baSDavid Woodhouse    2 = verbose put_count checking
30fe7752baSDavid Woodhouse */
31fe7752baSDavid Woodhouse #define AUDIT_DEBUG 0
32fe7752baSDavid Woodhouse 
33*b24a30a7SEric Paris /* AUDIT_NAMES is the number of slots we reserve in the audit_context
34*b24a30a7SEric Paris  * for saving names from getname().  If we get more names we will allocate
35*b24a30a7SEric Paris  * a name dynamically and also add those to the list anchored by names_list. */
36*b24a30a7SEric Paris #define AUDIT_NAMES	5
37*b24a30a7SEric Paris 
38fe7752baSDavid Woodhouse /* At task start time, the audit_state is set in the audit_context using
39fe7752baSDavid Woodhouse    a per-task filter.  At syscall entry, the audit_state is augmented by
40fe7752baSDavid Woodhouse    the syscall filter. */
41fe7752baSDavid Woodhouse enum audit_state {
42fe7752baSDavid Woodhouse 	AUDIT_DISABLED,		/* Do not create per-task audit_context.
43fe7752baSDavid Woodhouse 				 * No syscall-specific audit records can
44fe7752baSDavid Woodhouse 				 * be generated. */
45fe7752baSDavid Woodhouse 	AUDIT_BUILD_CONTEXT,	/* Create the per-task audit_context,
46997f5b64SEric Paris 				 * and fill it in at syscall
47fe7752baSDavid Woodhouse 				 * entry time.  This makes a full
48fe7752baSDavid Woodhouse 				 * syscall record available if some
49fe7752baSDavid Woodhouse 				 * other part of the kernel decides it
50fe7752baSDavid Woodhouse 				 * should be recorded. */
51fe7752baSDavid Woodhouse 	AUDIT_RECORD_CONTEXT	/* Create the per-task audit_context,
52fe7752baSDavid Woodhouse 				 * always fill it in at syscall entry
53fe7752baSDavid Woodhouse 				 * time, and always write out the audit
54fe7752baSDavid Woodhouse 				 * record at syscall exit time.  */
55fe7752baSDavid Woodhouse };
56fe7752baSDavid Woodhouse 
57fe7752baSDavid Woodhouse /* Rule lists */
58cfcad62cSEric Paris struct audit_watch;
5974c3cbe3SAl Viro struct audit_tree;
6074c3cbe3SAl Viro struct audit_chunk;
6174c3cbe3SAl Viro 
62fe7752baSDavid Woodhouse struct audit_entry {
63fe7752baSDavid Woodhouse 	struct list_head	list;
64fe7752baSDavid Woodhouse 	struct rcu_head		rcu;
6593315ed6SAmy Griffis 	struct audit_krule	rule;
66fe7752baSDavid Woodhouse };
67fe7752baSDavid Woodhouse 
68*b24a30a7SEric Paris struct audit_cap_data {
69*b24a30a7SEric Paris 	kernel_cap_t		permitted;
70*b24a30a7SEric Paris 	kernel_cap_t		inheritable;
71*b24a30a7SEric Paris 	union {
72*b24a30a7SEric Paris 		unsigned int	fE;		/* effective bit of file cap */
73*b24a30a7SEric Paris 		kernel_cap_t	effective;	/* effective set of process */
74*b24a30a7SEric Paris 	};
75*b24a30a7SEric Paris };
76*b24a30a7SEric Paris 
77*b24a30a7SEric Paris /* When fs/namei.c:getname() is called, we store the pointer in name and
78*b24a30a7SEric Paris  * we don't let putname() free it (instead we free all of the saved
79*b24a30a7SEric Paris  * pointers at syscall exit time).
80*b24a30a7SEric Paris  *
81*b24a30a7SEric Paris  * Further, in fs/namei.c:path_lookup() we store the inode and device.
82*b24a30a7SEric Paris  */
83*b24a30a7SEric Paris struct audit_names {
84*b24a30a7SEric Paris 	struct list_head	list;		/* audit_context->names_list */
85*b24a30a7SEric Paris 
86*b24a30a7SEric Paris 	struct filename		*name;
87*b24a30a7SEric Paris 	int			name_len;	/* number of chars to log */
88*b24a30a7SEric Paris 	bool			name_put;	/* call __putname()? */
89*b24a30a7SEric Paris 
90*b24a30a7SEric Paris 	unsigned long		ino;
91*b24a30a7SEric Paris 	dev_t			dev;
92*b24a30a7SEric Paris 	umode_t			mode;
93*b24a30a7SEric Paris 	kuid_t			uid;
94*b24a30a7SEric Paris 	kgid_t			gid;
95*b24a30a7SEric Paris 	dev_t			rdev;
96*b24a30a7SEric Paris 	u32			osid;
97*b24a30a7SEric Paris 	struct audit_cap_data	fcap;
98*b24a30a7SEric Paris 	unsigned int		fcap_ver;
99*b24a30a7SEric Paris 	unsigned char		type;		/* record type */
100*b24a30a7SEric Paris 	/*
101*b24a30a7SEric Paris 	 * This was an allocated audit_names and not from the array of
102*b24a30a7SEric Paris 	 * names allocated in the task audit context.  Thus this name
103*b24a30a7SEric Paris 	 * should be freed on syscall exit.
104*b24a30a7SEric Paris 	 */
105*b24a30a7SEric Paris 	bool			should_free;
106*b24a30a7SEric Paris };
107*b24a30a7SEric Paris 
108*b24a30a7SEric Paris /* The per-task audit context. */
109*b24a30a7SEric Paris struct audit_context {
110*b24a30a7SEric Paris 	int		    dummy;	/* must be the first element */
111*b24a30a7SEric Paris 	int		    in_syscall;	/* 1 if task is in a syscall */
112*b24a30a7SEric Paris 	enum audit_state    state, current_state;
113*b24a30a7SEric Paris 	unsigned int	    serial;     /* serial number for record */
114*b24a30a7SEric Paris 	int		    major;      /* syscall number */
115*b24a30a7SEric Paris 	struct timespec	    ctime;      /* time of syscall entry */
116*b24a30a7SEric Paris 	unsigned long	    argv[4];    /* syscall arguments */
117*b24a30a7SEric Paris 	long		    return_code;/* syscall return code */
118*b24a30a7SEric Paris 	u64		    prio;
119*b24a30a7SEric Paris 	int		    return_valid; /* return code is valid */
120*b24a30a7SEric Paris 	/*
121*b24a30a7SEric Paris 	 * The names_list is the list of all audit_names collected during this
122*b24a30a7SEric Paris 	 * syscall.  The first AUDIT_NAMES entries in the names_list will
123*b24a30a7SEric Paris 	 * actually be from the preallocated_names array for performance
124*b24a30a7SEric Paris 	 * reasons.  Except during allocation they should never be referenced
125*b24a30a7SEric Paris 	 * through the preallocated_names array and should only be found/used
126*b24a30a7SEric Paris 	 * by running the names_list.
127*b24a30a7SEric Paris 	 */
128*b24a30a7SEric Paris 	struct audit_names  preallocated_names[AUDIT_NAMES];
129*b24a30a7SEric Paris 	int		    name_count; /* total records in names_list */
130*b24a30a7SEric Paris 	struct list_head    names_list;	/* struct audit_names->list anchor */
131*b24a30a7SEric Paris 	char		    *filterkey;	/* key for rule that triggered record */
132*b24a30a7SEric Paris 	struct path	    pwd;
133*b24a30a7SEric Paris 	struct audit_aux_data *aux;
134*b24a30a7SEric Paris 	struct audit_aux_data *aux_pids;
135*b24a30a7SEric Paris 	struct sockaddr_storage *sockaddr;
136*b24a30a7SEric Paris 	size_t sockaddr_len;
137*b24a30a7SEric Paris 				/* Save things to print about task_struct */
138*b24a30a7SEric Paris 	pid_t		    pid, ppid;
139*b24a30a7SEric Paris 	kuid_t		    uid, euid, suid, fsuid;
140*b24a30a7SEric Paris 	kgid_t		    gid, egid, sgid, fsgid;
141*b24a30a7SEric Paris 	unsigned long	    personality;
142*b24a30a7SEric Paris 	int		    arch;
143*b24a30a7SEric Paris 
144*b24a30a7SEric Paris 	pid_t		    target_pid;
145*b24a30a7SEric Paris 	kuid_t		    target_auid;
146*b24a30a7SEric Paris 	kuid_t		    target_uid;
147*b24a30a7SEric Paris 	unsigned int	    target_sessionid;
148*b24a30a7SEric Paris 	u32		    target_sid;
149*b24a30a7SEric Paris 	char		    target_comm[TASK_COMM_LEN];
150*b24a30a7SEric Paris 
151*b24a30a7SEric Paris 	struct audit_tree_refs *trees, *first_trees;
152*b24a30a7SEric Paris 	struct list_head killed_trees;
153*b24a30a7SEric Paris 	int tree_count;
154*b24a30a7SEric Paris 
155*b24a30a7SEric Paris 	int type;
156*b24a30a7SEric Paris 	union {
157*b24a30a7SEric Paris 		struct {
158*b24a30a7SEric Paris 			int nargs;
159*b24a30a7SEric Paris 			long args[6];
160*b24a30a7SEric Paris 		} socketcall;
161*b24a30a7SEric Paris 		struct {
162*b24a30a7SEric Paris 			kuid_t			uid;
163*b24a30a7SEric Paris 			kgid_t			gid;
164*b24a30a7SEric Paris 			umode_t			mode;
165*b24a30a7SEric Paris 			u32			osid;
166*b24a30a7SEric Paris 			int			has_perm;
167*b24a30a7SEric Paris 			uid_t			perm_uid;
168*b24a30a7SEric Paris 			gid_t			perm_gid;
169*b24a30a7SEric Paris 			umode_t			perm_mode;
170*b24a30a7SEric Paris 			unsigned long		qbytes;
171*b24a30a7SEric Paris 		} ipc;
172*b24a30a7SEric Paris 		struct {
173*b24a30a7SEric Paris 			mqd_t			mqdes;
174*b24a30a7SEric Paris 			struct mq_attr		mqstat;
175*b24a30a7SEric Paris 		} mq_getsetattr;
176*b24a30a7SEric Paris 		struct {
177*b24a30a7SEric Paris 			mqd_t			mqdes;
178*b24a30a7SEric Paris 			int			sigev_signo;
179*b24a30a7SEric Paris 		} mq_notify;
180*b24a30a7SEric Paris 		struct {
181*b24a30a7SEric Paris 			mqd_t			mqdes;
182*b24a30a7SEric Paris 			size_t			msg_len;
183*b24a30a7SEric Paris 			unsigned int		msg_prio;
184*b24a30a7SEric Paris 			struct timespec		abs_timeout;
185*b24a30a7SEric Paris 		} mq_sendrecv;
186*b24a30a7SEric Paris 		struct {
187*b24a30a7SEric Paris 			int			oflag;
188*b24a30a7SEric Paris 			umode_t			mode;
189*b24a30a7SEric Paris 			struct mq_attr		attr;
190*b24a30a7SEric Paris 		} mq_open;
191*b24a30a7SEric Paris 		struct {
192*b24a30a7SEric Paris 			pid_t			pid;
193*b24a30a7SEric Paris 			struct audit_cap_data	cap;
194*b24a30a7SEric Paris 		} capset;
195*b24a30a7SEric Paris 		struct {
196*b24a30a7SEric Paris 			int			fd;
197*b24a30a7SEric Paris 			int			flags;
198*b24a30a7SEric Paris 		} mmap;
199*b24a30a7SEric Paris 	};
200*b24a30a7SEric Paris 	int fds[2];
201*b24a30a7SEric Paris 
202*b24a30a7SEric Paris #if AUDIT_DEBUG
203*b24a30a7SEric Paris 	int		    put_count;
204*b24a30a7SEric Paris 	int		    ino_count;
205*b24a30a7SEric Paris #endif
206*b24a30a7SEric Paris };
207*b24a30a7SEric Paris 
208c782f242SHarvey Harrison #ifdef CONFIG_AUDIT
209*b24a30a7SEric Paris extern int audit_enabled;
210c782f242SHarvey Harrison extern int audit_ever_enabled;
211*b24a30a7SEric Paris 
212*b24a30a7SEric Paris extern void audit_copy_inode(struct audit_names *name,
213*b24a30a7SEric Paris 			     const struct dentry *dentry,
214*b24a30a7SEric Paris 			     const struct inode *inode);
215*b24a30a7SEric Paris extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
216*b24a30a7SEric Paris 			  kernel_cap_t *cap);
217*b24a30a7SEric Paris extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name);
218*b24a30a7SEric Paris extern void audit_log_name(struct audit_context *context,
219*b24a30a7SEric Paris 			   struct audit_names *n, struct path *path,
220*b24a30a7SEric Paris 			   int record_num, int *call_panic);
221c782f242SHarvey Harrison #endif
222c782f242SHarvey Harrison 
223fe7752baSDavid Woodhouse extern int audit_pid;
224fe7752baSDavid Woodhouse 
225f368c07dSAmy Griffis #define AUDIT_INODE_BUCKETS	32
226f368c07dSAmy Griffis extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
227f368c07dSAmy Griffis 
228f368c07dSAmy Griffis static inline int audit_hash_ino(u32 ino)
229f368c07dSAmy Griffis {
230f368c07dSAmy Griffis 	return (ino & (AUDIT_INODE_BUCKETS-1));
231f368c07dSAmy Griffis }
232f368c07dSAmy Griffis 
233e3d6b07bSJeff Layton /* Indicates that audit should log the full pathname. */
234e3d6b07bSJeff Layton #define AUDIT_NAME_FULL -1
235e3d6b07bSJeff Layton 
23655669bfaSAl Viro extern int audit_match_class(int class, unsigned syscall);
237f368c07dSAmy Griffis extern int audit_comparator(const u32 left, const u32 op, const u32 right);
238ca57ec0fSEric W. Biederman extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
239ca57ec0fSEric W. Biederman extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
240bfcec708SJeff Layton extern int parent_len(const char *path);
241e3d6b07bSJeff Layton extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
2429044e6bcSAl Viro extern struct sk_buff *	    audit_make_reply(int pid, int seq, int type,
2439044e6bcSAl Viro 					     int done, int multi,
244b8800aa5SStephen Hemminger 					     const void *payload, int size);
245fe7752baSDavid Woodhouse extern void		    audit_panic(const char *message);
2463dc7e315SDarrel Goeddel 
2479044e6bcSAl Viro struct audit_netlink_list {
2489044e6bcSAl Viro 	int pid;
2499044e6bcSAl Viro 	struct sk_buff_head q;
2509044e6bcSAl Viro };
2519044e6bcSAl Viro 
2529044e6bcSAl Viro int audit_send_list(void *);
2539044e6bcSAl Viro 
2543dc7e315SDarrel Goeddel extern int selinux_audit_rule_update(void);
255e1396065SAl Viro 
25674c3cbe3SAl Viro extern struct mutex audit_filter_mutex;
25774c3cbe3SAl Viro extern void audit_free_rule_rcu(struct rcu_head *);
258c782f242SHarvey Harrison extern struct list_head audit_filter_list[];
25974c3cbe3SAl Viro 
260939a67fcSEric Paris extern struct audit_entry *audit_dupe_rule(struct audit_krule *old);
261939a67fcSEric Paris 
262cfcad62cSEric Paris /* audit watch functions */
263939a67fcSEric Paris #ifdef CONFIG_AUDIT_WATCH
264cfcad62cSEric Paris extern void audit_put_watch(struct audit_watch *watch);
265cfcad62cSEric Paris extern void audit_get_watch(struct audit_watch *watch);
266cfcad62cSEric Paris extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op);
267ae7b8f41SEric Paris extern int audit_add_watch(struct audit_krule *krule, struct list_head **list);
268a05fb6ccSEric Paris extern void audit_remove_watch_rule(struct audit_krule *krule);
269cfcad62cSEric Paris extern char *audit_watch_path(struct audit_watch *watch);
270ae7b8f41SEric Paris extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev);
271939a67fcSEric Paris #else
272939a67fcSEric Paris #define audit_put_watch(w) {}
273939a67fcSEric Paris #define audit_get_watch(w) {}
274939a67fcSEric Paris #define audit_to_watch(k, p, l, o) (-EINVAL)
275939a67fcSEric Paris #define audit_add_watch(k, l) (-EINVAL)
276939a67fcSEric Paris #define audit_remove_watch_rule(k) BUG()
277939a67fcSEric Paris #define audit_watch_path(w) ""
278939a67fcSEric Paris #define audit_watch_compare(w, i, d) 0
279939a67fcSEric Paris 
280939a67fcSEric Paris #endif /* CONFIG_AUDIT_WATCH */
281cfcad62cSEric Paris 
28274c3cbe3SAl Viro #ifdef CONFIG_AUDIT_TREE
28374c3cbe3SAl Viro extern struct audit_chunk *audit_tree_lookup(const struct inode *);
28474c3cbe3SAl Viro extern void audit_put_chunk(struct audit_chunk *);
28574c3cbe3SAl Viro extern int audit_tree_match(struct audit_chunk *, struct audit_tree *);
28674c3cbe3SAl Viro extern int audit_make_tree(struct audit_krule *, char *, u32);
28774c3cbe3SAl Viro extern int audit_add_tree_rule(struct audit_krule *);
28874c3cbe3SAl Viro extern int audit_remove_tree_rule(struct audit_krule *);
28974c3cbe3SAl Viro extern void audit_trim_trees(void);
29074c3cbe3SAl Viro extern int audit_tag_tree(char *old, char *new);
29174c3cbe3SAl Viro extern const char *audit_tree_path(struct audit_tree *);
29274c3cbe3SAl Viro extern void audit_put_tree(struct audit_tree *);
293916d7576SAl Viro extern void audit_kill_trees(struct list_head *);
29474c3cbe3SAl Viro #else
29574c3cbe3SAl Viro #define audit_remove_tree_rule(rule) BUG()
29674c3cbe3SAl Viro #define audit_add_tree_rule(rule) -EINVAL
29774c3cbe3SAl Viro #define audit_make_tree(rule, str, op) -EINVAL
29874c3cbe3SAl Viro #define audit_trim_trees() (void)0
29974c3cbe3SAl Viro #define audit_put_tree(tree) (void)0
30074c3cbe3SAl Viro #define audit_tag_tree(old, new) -EINVAL
30174c3cbe3SAl Viro #define audit_tree_path(rule) ""	/* never called */
302916d7576SAl Viro #define audit_kill_trees(list) BUG()
30374c3cbe3SAl Viro #endif
30474c3cbe3SAl Viro 
30574c3cbe3SAl Viro extern char *audit_unpack_string(void **, size_t *, size_t);
30674c3cbe3SAl Viro 
307c782f242SHarvey Harrison extern pid_t audit_sig_pid;
308cca080d9SEric W. Biederman extern kuid_t audit_sig_uid;
309c782f242SHarvey Harrison extern u32 audit_sig_sid;
310c782f242SHarvey Harrison 
311e1396065SAl Viro #ifdef CONFIG_AUDITSYSCALL
312e54dc243SAmy Griffis extern int __audit_signal_info(int sig, struct task_struct *t);
313e54dc243SAmy Griffis static inline int audit_signal_info(int sig, struct task_struct *t)
314e1396065SAl Viro {
315e54dc243SAmy Griffis 	if (unlikely((audit_pid && t->tgid == audit_pid) ||
316e54dc243SAmy Griffis 		     (audit_signals && !audit_dummy_context())))
317e54dc243SAmy Griffis 		return __audit_signal_info(sig, t);
318e54dc243SAmy Griffis 	return 0;
319e1396065SAl Viro }
3200590b933SAl Viro extern void audit_filter_inodes(struct task_struct *, struct audit_context *);
321916d7576SAl Viro extern struct list_head *audit_killed_trees(void);
322e1396065SAl Viro #else
323e54dc243SAmy Griffis #define audit_signal_info(s,t) AUDIT_DISABLED
324f368c07dSAmy Griffis #define audit_filter_inodes(t,c) AUDIT_DISABLED
325e1396065SAl Viro #endif
326916d7576SAl Viro 
327916d7576SAl Viro extern struct mutex audit_cmd_mutex;
328