Blame view

kernel/auditsc.c 66.5 KB
85c8721ff   David Woodhouse   audit: update poi...
1
  /* auditsc.c -- System-call auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
   * Handles all system-call specific auditing features.
   *
   * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
73241ccca   Amy Griffis   [PATCH] Collect m...
5
   * Copyright 2005 Hewlett-Packard Development Company, L.P.
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
6
   * Copyright (C) 2005, 2006 IBM Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   * All Rights Reserved.
   *
   * 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
   *
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
   * Many of the ideas implemented here are from Stephen C. Tweedie,
   * especially the idea of avoiding a copy by using getname.
   *
   * The method for actual interception of syscall entry and exit (not in
   * this file -- see entry.S) is based on a GPL'd patch written by
   * okir@suse.de and Copyright 2003 SuSE Linux AG.
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
32
33
34
   * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
   * 2006.
   *
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
35
36
37
   * The support of additional filter rules compares (>, <, >=, <=) was
   * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
   *
73241ccca   Amy Griffis   [PATCH] Collect m...
38
39
   * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
   * filesystem information.
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
40
41
42
   *
   * Subject and object context labeling support added by <danjones@us.ibm.com>
   * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
   */
  
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  #include <asm/types.h>
60063497a   Arun Sharma   atomic: use <linu...
47
  #include <linux/atomic.h>
73241ccca   Amy Griffis   [PATCH] Collect m...
48
49
  #include <linux/fs.h>
  #include <linux/namei.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
51
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
52
  #include <linux/slab.h>
011161051   Stephen Smalley   AUDIT: Avoid slee...
53
  #include <linux/mount.h>
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
54
  #include <linux/socket.h>
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
55
  #include <linux/mqueue.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  #include <linux/audit.h>
  #include <linux/personality.h>
  #include <linux/time.h>
5bb289b5a   David Woodhouse   AUDIT: Clean up u...
59
  #include <linux/netlink.h>
f55619642   David Woodhouse   AUDIT: Avoid sche...
60
  #include <linux/compiler.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #include <asm/unistd.h>
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
62
  #include <linux/security.h>
fe7752bab   David Woodhouse   [PATCH] Fix audit...
63
  #include <linux/list.h>
a6c043a88   Steve Grubb   [PATCH] Add tty t...
64
  #include <linux/tty.h>
473ae30bc   Al Viro   [PATCH] execve ar...
65
  #include <linux/binfmts.h>
a1f8e7f7f   Al Viro   [PATCH] severing ...
66
  #include <linux/highmem.h>
f46038ff7   Al Viro   [PATCH] log ppid
67
  #include <linux/syscalls.h>
851f7ff56   Eric Paris   This patch will p...
68
  #include <linux/capability.h>
5ad4e53bd   Al Viro   Get rid of indire...
69
  #include <linux/fs_struct.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70

fe7752bab   David Woodhouse   [PATCH] Fix audit...
71
  #include "audit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
  /* AUDIT_NAMES is the number of slots we reserve in the audit_context
   * for saving names from getname(). */
  #define AUDIT_NAMES    20
9c937dcc7   Amy Griffis   [PATCH] log more ...
76
77
  /* Indicates that audit should log the full pathname. */
  #define AUDIT_NAME_FULL -1
de6bbd1d3   Eric Paris   [AUDIT] break lar...
78
79
  /* no execve audit message should be longer than this (userspace limits) */
  #define MAX_EXECVE_AUDIT_LEN 7500
471a5c7c8   Al Viro   [PATCH] introduce...
80
81
  /* number of audit rules */
  int audit_n_rules;
e54dc2431   Amy Griffis   [PATCH] audit sig...
82
83
  /* determines whether we collect data for signals sent */
  int audit_signals;
851f7ff56   Eric Paris   This patch will p...
84
85
86
87
88
89
90
91
  struct audit_cap_data {
  	kernel_cap_t		permitted;
  	kernel_cap_t		inheritable;
  	union {
  		unsigned int	fE;		/* effective bit of a file capability */
  		kernel_cap_t	effective;	/* effective set of a process */
  	};
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
97
98
  /* When fs/namei.c:getname() is called, we store the pointer in name and
   * we don't let putname() free it (instead we free all of the saved
   * pointers at syscall exit time).
   *
   * Further, in fs/namei.c:path_lookup() we store the inode and device. */
  struct audit_names {
  	const char	*name;
9c937dcc7   Amy Griffis   [PATCH] log more ...
99
100
  	int		name_len;	/* number of name's characters to log */
  	unsigned	name_put;	/* call __putname() for this name */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
  	unsigned long	ino;
  	dev_t		dev;
  	umode_t		mode;
  	uid_t		uid;
  	gid_t		gid;
  	dev_t		rdev;
1b50eed9c   Steve Grubb   [PATCH] audit ino...
107
  	u32		osid;
851f7ff56   Eric Paris   This patch will p...
108
109
  	struct audit_cap_data fcap;
  	unsigned int	fcap_ver;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
114
115
116
117
  };
  
  struct audit_aux_data {
  	struct audit_aux_data	*next;
  	int			type;
  };
  
  #define AUDIT_AUX_IPCPERM	0
e54dc2431   Amy Griffis   [PATCH] audit sig...
118
119
  /* Number of target pids per aux struct. */
  #define AUDIT_AUX_PIDS	16
473ae30bc   Al Viro   [PATCH] execve ar...
120
121
122
123
  struct audit_aux_data_execve {
  	struct audit_aux_data	d;
  	int argc;
  	int envc;
bdf4c48af   Peter Zijlstra   audit: rework exe...
124
  	struct mm_struct *mm;
473ae30bc   Al Viro   [PATCH] execve ar...
125
  };
e54dc2431   Amy Griffis   [PATCH] audit sig...
126
127
128
  struct audit_aux_data_pids {
  	struct audit_aux_data	d;
  	pid_t			target_pid[AUDIT_AUX_PIDS];
c2a7780ef   Eric Paris   [AUDIT] collect u...
129
130
  	uid_t			target_auid[AUDIT_AUX_PIDS];
  	uid_t			target_uid[AUDIT_AUX_PIDS];
4746ec5b0   Eric Paris   [AUDIT] add sessi...
131
  	unsigned int		target_sessionid[AUDIT_AUX_PIDS];
e54dc2431   Amy Griffis   [PATCH] audit sig...
132
  	u32			target_sid[AUDIT_AUX_PIDS];
c2a7780ef   Eric Paris   [AUDIT] collect u...
133
  	char 			target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
e54dc2431   Amy Griffis   [PATCH] audit sig...
134
135
  	int			pid_count;
  };
3fc689e96   Eric Paris   Any time fcaps or...
136
137
138
139
140
141
142
  struct audit_aux_data_bprm_fcaps {
  	struct audit_aux_data	d;
  	struct audit_cap_data	fcap;
  	unsigned int		fcap_ver;
  	struct audit_cap_data	old_pcap;
  	struct audit_cap_data	new_pcap;
  };
e68b75a02   Eric Paris   When the capset s...
143
144
145
146
147
  struct audit_aux_data_capset {
  	struct audit_aux_data	d;
  	pid_t			pid;
  	struct audit_cap_data	cap;
  };
74c3cbe33   Al Viro   [PATCH] audit: wa...
148
149
150
151
  struct audit_tree_refs {
  	struct audit_tree_refs *next;
  	struct audit_chunk *c[31];
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
  /* The per-task audit context. */
  struct audit_context {
d51374adf   Al Viro   [PATCH] mark cont...
154
  	int		    dummy;	/* must be the first element */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  	int		    in_syscall;	/* 1 if task is in a syscall */
0590b9335   Al Viro   fixing audit rule...
156
  	enum audit_state    state, current_state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  	unsigned int	    serial;     /* serial number for record */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  	int		    major;      /* syscall number */
44e51a1b7   Eric Paris   Audit: rearrange ...
159
  	struct timespec	    ctime;      /* time of syscall entry */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  	unsigned long	    argv[4];    /* syscall arguments */
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
161
  	long		    return_code;/* syscall return code */
0590b9335   Al Viro   fixing audit rule...
162
  	u64		    prio;
44e51a1b7   Eric Paris   Audit: rearrange ...
163
  	int		    return_valid; /* return code is valid */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
  	int		    name_count;
  	struct audit_names  names[AUDIT_NAMES];
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
166
  	char *		    filterkey;	/* key for rule that triggered record */
44707fdf5   Jan Blunck   d_path: Use struc...
167
  	struct path	    pwd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  	struct audit_context *previous; /* For nested syscalls */
  	struct audit_aux_data *aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
170
  	struct audit_aux_data *aux_pids;
4f6b434fe   Al Viro   don't reallocate ...
171
172
  	struct sockaddr_storage *sockaddr;
  	size_t sockaddr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  				/* Save things to print about task_struct */
f46038ff7   Al Viro   [PATCH] log ppid
174
  	pid_t		    pid, ppid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
  	uid_t		    uid, euid, suid, fsuid;
  	gid_t		    gid, egid, sgid, fsgid;
  	unsigned long	    personality;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
178
  	int		    arch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179

a5cb013da   Al Viro   [PATCH] auditing ...
180
  	pid_t		    target_pid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
181
182
  	uid_t		    target_auid;
  	uid_t		    target_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
183
  	unsigned int	    target_sessionid;
a5cb013da   Al Viro   [PATCH] auditing ...
184
  	u32		    target_sid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
185
  	char		    target_comm[TASK_COMM_LEN];
a5cb013da   Al Viro   [PATCH] auditing ...
186

74c3cbe33   Al Viro   [PATCH] audit: wa...
187
  	struct audit_tree_refs *trees, *first_trees;
916d75761   Al Viro   Fix rule eviction...
188
  	struct list_head killed_trees;
44e51a1b7   Eric Paris   Audit: rearrange ...
189
  	int tree_count;
74c3cbe33   Al Viro   [PATCH] audit: wa...
190

f3298dc4f   Al Viro   sanitize audit_so...
191
192
193
194
195
196
  	int type;
  	union {
  		struct {
  			int nargs;
  			long args[6];
  		} socketcall;
a33e67510   Al Viro   sanitize audit_ip...
197
198
199
  		struct {
  			uid_t			uid;
  			gid_t			gid;
2570ebbd1   Al Viro   switch kern_ipc_p...
200
  			umode_t			mode;
a33e67510   Al Viro   sanitize audit_ip...
201
  			u32			osid;
e816f370c   Al Viro   sanitize audit_ip...
202
203
204
  			int			has_perm;
  			uid_t			perm_uid;
  			gid_t			perm_gid;
2570ebbd1   Al Viro   switch kern_ipc_p...
205
  			umode_t			perm_mode;
e816f370c   Al Viro   sanitize audit_ip...
206
  			unsigned long		qbytes;
a33e67510   Al Viro   sanitize audit_ip...
207
  		} ipc;
7392906ea   Al Viro   sanitize audit_mq...
208
209
210
211
  		struct {
  			mqd_t			mqdes;
  			struct mq_attr 		mqstat;
  		} mq_getsetattr;
20114f71b   Al Viro   sanitize audit_mq...
212
213
214
215
  		struct {
  			mqd_t			mqdes;
  			int			sigev_signo;
  		} mq_notify;
c32c8af43   Al Viro   sanitize AUDIT_MQ...
216
217
218
219
220
221
  		struct {
  			mqd_t			mqdes;
  			size_t			msg_len;
  			unsigned int		msg_prio;
  			struct timespec		abs_timeout;
  		} mq_sendrecv;
564f6993f   Al Viro   sanitize audit_mq...
222
223
  		struct {
  			int			oflag;
df0a42837   Al Viro   switch mq_open() ...
224
  			umode_t			mode;
564f6993f   Al Viro   sanitize audit_mq...
225
226
  			struct mq_attr		attr;
  		} mq_open;
57f71a0af   Al Viro   sanitize audit_lo...
227
228
229
230
  		struct {
  			pid_t			pid;
  			struct audit_cap_data	cap;
  		} capset;
120a795da   Al Viro   audit mmap
231
232
233
234
  		struct {
  			int			fd;
  			int			flags;
  		} mmap;
f3298dc4f   Al Viro   sanitize audit_so...
235
  	};
157cf649a   Al Viro   sanitize audit_fd...
236
  	int fds[2];
f3298dc4f   Al Viro   sanitize audit_so...
237

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
240
241
242
  #if AUDIT_DEBUG
  	int		    put_count;
  	int		    ino_count;
  #endif
  };
55669bfa1   Al Viro   [PATCH] audit: AU...
243
244
245
246
247
248
249
250
251
252
  static inline int open_arg(int flags, int mask)
  {
  	int n = ACC_MODE(flags);
  	if (flags & (O_TRUNC | O_CREAT))
  		n |= AUDIT_PERM_WRITE;
  	return n & mask;
  }
  
  static int audit_match_perm(struct audit_context *ctx, int mask)
  {
c4bacefb7   Cordelia   [PATCH] audit: Mo...
253
  	unsigned n;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
254
255
  	if (unlikely(!ctx))
  		return 0;
c4bacefb7   Cordelia   [PATCH] audit: Mo...
256
  	n = ctx->major;
dbda4c0b9   Alan Cox   tty: Fix abusers ...
257

55669bfa1   Al Viro   [PATCH] audit: AU...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  	switch (audit_classify_syscall(ctx->arch, n)) {
  	case 0:	/* native */
  		if ((mask & AUDIT_PERM_WRITE) &&
  		     audit_match_class(AUDIT_CLASS_WRITE, n))
  			return 1;
  		if ((mask & AUDIT_PERM_READ) &&
  		     audit_match_class(AUDIT_CLASS_READ, n))
  			return 1;
  		if ((mask & AUDIT_PERM_ATTR) &&
  		     audit_match_class(AUDIT_CLASS_CHATTR, n))
  			return 1;
  		return 0;
  	case 1: /* 32bit on biarch */
  		if ((mask & AUDIT_PERM_WRITE) &&
  		     audit_match_class(AUDIT_CLASS_WRITE_32, n))
  			return 1;
  		if ((mask & AUDIT_PERM_READ) &&
  		     audit_match_class(AUDIT_CLASS_READ_32, n))
  			return 1;
  		if ((mask & AUDIT_PERM_ATTR) &&
  		     audit_match_class(AUDIT_CLASS_CHATTR_32, n))
  			return 1;
  		return 0;
  	case 2: /* open */
  		return mask & ACC_MODE(ctx->argv[1]);
  	case 3: /* openat */
  		return mask & ACC_MODE(ctx->argv[2]);
  	case 4: /* socketcall */
  		return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND);
  	case 5: /* execve */
  		return mask & AUDIT_PERM_EXEC;
  	default:
  		return 0;
  	}
  }
8b67dca94   Al Viro   [PATCH] new predi...
293
294
295
  static int audit_match_filetype(struct audit_context *ctx, int which)
  {
  	unsigned index = which & ~S_IFMT;
93d3a10ef   Al Viro   auditsc: propage ...
296
  	umode_t mode = which & S_IFMT;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
297
298
299
  
  	if (unlikely(!ctx))
  		return 0;
8b67dca94   Al Viro   [PATCH] new predi...
300
301
302
303
304
305
306
307
  	if (index >= ctx->name_count)
  		return 0;
  	if (ctx->names[index].ino == -1)
  		return 0;
  	if ((ctx->names[index].mode ^ mode) & S_IFMT)
  		return 0;
  	return 1;
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
308
309
310
311
312
313
314
315
316
317
318
  /*
   * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
   * ->first_trees points to its beginning, ->trees - to the current end of data.
   * ->tree_count is the number of free entries in array pointed to by ->trees.
   * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
   * "empty" becomes (p, p, 31) afterwards.  We don't shrink the list (and seriously,
   * it's going to remain 1-element for almost any setup) until we free context itself.
   * References in it _are_ dropped - at the same time we free/drop aux stuff.
   */
  
  #ifdef CONFIG_AUDIT_TREE
679173b72   Eric Paris   audit: audit_set_...
319
320
321
322
323
324
325
  static void audit_set_auditable(struct audit_context *ctx)
  {
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
  {
  	struct audit_tree_refs *p = ctx->trees;
  	int left = ctx->tree_count;
  	if (likely(left)) {
  		p->c[--left] = chunk;
  		ctx->tree_count = left;
  		return 1;
  	}
  	if (!p)
  		return 0;
  	p = p->next;
  	if (p) {
  		p->c[30] = chunk;
  		ctx->trees = p;
  		ctx->tree_count = 30;
  		return 1;
  	}
  	return 0;
  }
  
  static int grow_tree_refs(struct audit_context *ctx)
  {
  	struct audit_tree_refs *p = ctx->trees;
  	ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
  	if (!ctx->trees) {
  		ctx->trees = p;
  		return 0;
  	}
  	if (p)
  		p->next = ctx->trees;
  	else
  		ctx->first_trees = ctx->trees;
  	ctx->tree_count = 31;
  	return 1;
  }
  #endif
  
  static void unroll_tree_refs(struct audit_context *ctx,
  		      struct audit_tree_refs *p, int count)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_tree_refs *q;
  	int n;
  	if (!p) {
  		/* we started with empty chain */
  		p = ctx->first_trees;
  		count = 31;
  		/* if the very first allocation has failed, nothing to do */
  		if (!p)
  			return;
  	}
  	n = count;
  	for (q = p; q != ctx->trees; q = q->next, n = 31) {
  		while (n--) {
  			audit_put_chunk(q->c[n]);
  			q->c[n] = NULL;
  		}
  	}
  	while (n-- > ctx->tree_count) {
  		audit_put_chunk(q->c[n]);
  		q->c[n] = NULL;
  	}
  	ctx->trees = p;
  	ctx->tree_count = count;
  #endif
  }
  
  static void free_tree_refs(struct audit_context *ctx)
  {
  	struct audit_tree_refs *p, *q;
  	for (p = ctx->first_trees; p; p = q) {
  		q = p->next;
  		kfree(p);
  	}
  }
  
  static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_tree_refs *p;
  	int n;
  	if (!tree)
  		return 0;
  	/* full ones */
  	for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
  		for (n = 0; n < 31; n++)
  			if (audit_tree_match(p->c[n], tree))
  				return 1;
  	}
  	/* partial */
  	if (p) {
  		for (n = ctx->tree_count; n < 31; n++)
  			if (audit_tree_match(p->c[n], tree))
  				return 1;
  	}
  #endif
  	return 0;
  }
f368c07d7   Amy Griffis   [PATCH] audit: pa...
425
  /* Determine if any context name data matches a rule's watch data */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
  /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
f56298835   Tony Jones   audit: acquire cr...
427
428
429
430
431
432
   * otherwise.
   *
   * If task_creation is true, this is an explicit indication that we are
   * filtering a task rule at task creation time.  This and tsk == current are
   * the only situations where tsk->cred may be accessed without an rcu read lock.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  static int audit_filter_rules(struct task_struct *tsk,
93315ed6d   Amy Griffis   [PATCH] audit str...
434
  			      struct audit_krule *rule,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  			      struct audit_context *ctx,
f368c07d7   Amy Griffis   [PATCH] audit: pa...
436
  			      struct audit_names *name,
f56298835   Tony Jones   audit: acquire cr...
437
438
  			      enum audit_state *state,
  			      bool task_creation)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  {
f56298835   Tony Jones   audit: acquire cr...
440
  	const struct cred *cred;
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
441
  	int i, j, need_sid = 1;
3dc7e3153   Darrel Goeddel   [PATCH] support f...
442
  	u32 sid;
f56298835   Tony Jones   audit: acquire cr...
443
  	cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
  	for (i = 0; i < rule->field_count; i++) {
93315ed6d   Amy Griffis   [PATCH] audit str...
445
  		struct audit_field *f = &rule->fields[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  		int result = 0;
93315ed6d   Amy Griffis   [PATCH] audit str...
447
  		switch (f->type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
  		case AUDIT_PID:
93315ed6d   Amy Griffis   [PATCH] audit str...
449
  			result = audit_comparator(tsk->pid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  			break;
3c66251e5   Al Viro   [PATCH] add filte...
451
  		case AUDIT_PPID:
419c58f11   Alexander Viro   [PATCH] PPID filt...
452
453
454
  			if (ctx) {
  				if (!ctx->ppid)
  					ctx->ppid = sys_getppid();
3c66251e5   Al Viro   [PATCH] add filte...
455
  				result = audit_comparator(ctx->ppid, f->op, f->val);
419c58f11   Alexander Viro   [PATCH] PPID filt...
456
  			}
3c66251e5   Al Viro   [PATCH] add filte...
457
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
  		case AUDIT_UID:
b6dff3ec5   David Howells   CRED: Separate ta...
459
  			result = audit_comparator(cred->uid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
461
  			break;
  		case AUDIT_EUID:
b6dff3ec5   David Howells   CRED: Separate ta...
462
  			result = audit_comparator(cred->euid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
  			break;
  		case AUDIT_SUID:
b6dff3ec5   David Howells   CRED: Separate ta...
465
  			result = audit_comparator(cred->suid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
467
  			break;
  		case AUDIT_FSUID:
b6dff3ec5   David Howells   CRED: Separate ta...
468
  			result = audit_comparator(cred->fsuid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
  			break;
  		case AUDIT_GID:
b6dff3ec5   David Howells   CRED: Separate ta...
471
  			result = audit_comparator(cred->gid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
  			break;
  		case AUDIT_EGID:
b6dff3ec5   David Howells   CRED: Separate ta...
474
  			result = audit_comparator(cred->egid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
  			break;
  		case AUDIT_SGID:
b6dff3ec5   David Howells   CRED: Separate ta...
477
  			result = audit_comparator(cred->sgid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
479
  			break;
  		case AUDIT_FSGID:
b6dff3ec5   David Howells   CRED: Separate ta...
480
  			result = audit_comparator(cred->fsgid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
482
  			break;
  		case AUDIT_PERS:
93315ed6d   Amy Griffis   [PATCH] audit str...
483
  			result = audit_comparator(tsk->personality, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  			break;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
485
  		case AUDIT_ARCH:
9f8dbe9c9   Daniel Walker   whitespace fixes:...
486
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
487
  				result = audit_comparator(ctx->arch, f->op, f->val);
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
488
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
  
  		case AUDIT_EXIT:
  			if (ctx && ctx->return_valid)
93315ed6d   Amy Griffis   [PATCH] audit str...
492
  				result = audit_comparator(ctx->return_code, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
  			break;
  		case AUDIT_SUCCESS:
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
495
  			if (ctx && ctx->return_valid) {
93315ed6d   Amy Griffis   [PATCH] audit str...
496
497
  				if (f->val)
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
498
  				else
93315ed6d   Amy Griffis   [PATCH] audit str...
499
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
500
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
  			break;
  		case AUDIT_DEVMAJOR:
f368c07d7   Amy Griffis   [PATCH] audit: pa...
503
504
505
506
  			if (name)
  				result = audit_comparator(MAJOR(name->dev),
  							  f->op, f->val);
  			else if (ctx) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  				for (j = 0; j < ctx->name_count; j++) {
93315ed6d   Amy Griffis   [PATCH] audit str...
508
  					if (audit_comparator(MAJOR(ctx->names[j].dev),	f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
511
512
513
514
515
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_DEVMINOR:
f368c07d7   Amy Griffis   [PATCH] audit: pa...
516
517
518
519
  			if (name)
  				result = audit_comparator(MINOR(name->dev),
  							  f->op, f->val);
  			else if (ctx) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
  				for (j = 0; j < ctx->name_count; j++) {
93315ed6d   Amy Griffis   [PATCH] audit str...
521
  					if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
524
525
526
527
528
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_INODE:
f368c07d7   Amy Griffis   [PATCH] audit: pa...
529
  			if (name)
9c937dcc7   Amy Griffis   [PATCH] log more ...
530
  				result = (name->ino == f->val);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
531
  			else if (ctx) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  				for (j = 0; j < ctx->name_count; j++) {
9c937dcc7   Amy Griffis   [PATCH] log more ...
533
  					if (audit_comparator(ctx->names[j].ino, f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
  						++result;
  						break;
  					}
  				}
  			}
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
540
  		case AUDIT_WATCH:
ae7b8f410   Eric Paris   Audit: clean up t...
541
542
  			if (name)
  				result = audit_watch_compare(rule->watch, name->ino, name->dev);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
543
  			break;
74c3cbe33   Al Viro   [PATCH] audit: wa...
544
545
546
547
  		case AUDIT_DIR:
  			if (ctx)
  				result = match_tree_refs(ctx, rule->tree);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
550
  		case AUDIT_LOGINUID:
  			result = 0;
  			if (ctx)
bfef93a5d   Al Viro   [PATCH] get rid o...
551
  				result = audit_comparator(tsk->loginuid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  			break;
3a6b9f85c   Darrel Goeddel   [PATCH] audit: re...
553
554
555
556
557
  		case AUDIT_SUBJ_USER:
  		case AUDIT_SUBJ_ROLE:
  		case AUDIT_SUBJ_TYPE:
  		case AUDIT_SUBJ_SEN:
  		case AUDIT_SUBJ_CLR:
3dc7e3153   Darrel Goeddel   [PATCH] support f...
558
559
560
561
562
  			/* NOTE: this may return negative values indicating
  			   a temporary error.  We simply treat this as a
  			   match for now to avoid losing information that
  			   may be wanted.   An error message will also be
  			   logged upon error */
04305e4af   Ahmed S. Darwish   Audit: Final rena...
563
  			if (f->lsm_rule) {
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
564
  				if (need_sid) {
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
565
  					security_task_getsecid(tsk, &sid);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
566
567
  					need_sid = 0;
  				}
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
568
  				result = security_audit_rule_match(sid, f->type,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
569
  				                                  f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
570
  				                                  f->lsm_rule,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
571
  				                                  ctx);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
572
  			}
3dc7e3153   Darrel Goeddel   [PATCH] support f...
573
  			break;
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
574
575
576
577
578
579
580
  		case AUDIT_OBJ_USER:
  		case AUDIT_OBJ_ROLE:
  		case AUDIT_OBJ_TYPE:
  		case AUDIT_OBJ_LEV_LOW:
  		case AUDIT_OBJ_LEV_HIGH:
  			/* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
  			   also applies here */
04305e4af   Ahmed S. Darwish   Audit: Final rena...
581
  			if (f->lsm_rule) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
582
583
  				/* Find files that match */
  				if (name) {
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
584
  					result = security_audit_rule_match(
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
585
  					           name->osid, f->type, f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
586
  					           f->lsm_rule, ctx);
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
587
588
  				} else if (ctx) {
  					for (j = 0; j < ctx->name_count; j++) {
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
589
  						if (security_audit_rule_match(
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
590
591
  						      ctx->names[j].osid,
  						      f->type, f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
592
  						      f->lsm_rule, ctx)) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
593
594
595
596
597
598
  							++result;
  							break;
  						}
  					}
  				}
  				/* Find ipc objects that match */
a33e67510   Al Viro   sanitize audit_ip...
599
600
601
602
603
604
  				if (!ctx || ctx->type != AUDIT_IPC)
  					break;
  				if (security_audit_rule_match(ctx->ipc.osid,
  							      f->type, f->op,
  							      f->lsm_rule, ctx))
  					++result;
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
605
606
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
610
611
  		case AUDIT_ARG0:
  		case AUDIT_ARG1:
  		case AUDIT_ARG2:
  		case AUDIT_ARG3:
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
612
  				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
  			break;
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
614
615
616
617
  		case AUDIT_FILTERKEY:
  			/* ignore this field for filtering */
  			result = 1;
  			break;
55669bfa1   Al Viro   [PATCH] audit: AU...
618
619
620
  		case AUDIT_PERM:
  			result = audit_match_perm(ctx, f->val);
  			break;
8b67dca94   Al Viro   [PATCH] new predi...
621
622
623
  		case AUDIT_FILETYPE:
  			result = audit_match_filetype(ctx, f->val);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  		}
f56298835   Tony Jones   audit: acquire cr...
625
  		if (!result)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
  			return 0;
  	}
0590b9335   Al Viro   fixing audit rule...
628
629
630
631
632
633
634
635
636
637
  
  	if (ctx) {
  		if (rule->prio <= ctx->prio)
  			return 0;
  		if (rule->filterkey) {
  			kfree(ctx->filterkey);
  			ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
  		}
  		ctx->prio = rule->prio;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
639
  	switch (rule->action) {
  	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
641
642
643
644
645
646
647
648
  	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
  	}
  	return 1;
  }
  
  /* At process creation time, we can determine if system-call auditing is
   * completely disabled for this task.  Since we only have the task
   * structure at this point, we can only check uid and gid.
   */
e048e02c8   Al Viro   make sure that fi...
649
  static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
652
653
654
  {
  	struct audit_entry *e;
  	enum audit_state   state;
  
  	rcu_read_lock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
655
  	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
f56298835   Tony Jones   audit: acquire cr...
656
657
  		if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
  				       &state, true)) {
e048e02c8   Al Viro   make sure that fi...
658
659
  			if (state == AUDIT_RECORD_CONTEXT)
  				*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
662
663
664
665
666
667
668
669
  			rcu_read_unlock();
  			return state;
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
  
  /* At syscall entry and exit time, this filter is called if the
   * audit_state is not low enough that auditing cannot take place, but is
23f32d18a   Steve Grubb   AUDIT: Fix some s...
670
   * also not high enough that we already know we have to write an audit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
671
   * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
674
675
676
677
   */
  static enum audit_state audit_filter_syscall(struct task_struct *tsk,
  					     struct audit_context *ctx,
  					     struct list_head *list)
  {
  	struct audit_entry *e;
c38964959   David Woodhouse   AUDIT: Speed up a...
678
  	enum audit_state state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679

351bb7225   David Woodhouse   AUDIT: Fix compil...
680
  	if (audit_pid && tsk->tgid == audit_pid)
f7056d64a   David Woodhouse   AUDIT: Really exe...
681
  		return AUDIT_DISABLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
  	rcu_read_lock();
c38964959   David Woodhouse   AUDIT: Speed up a...
683
  	if (!list_empty(list)) {
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
684
685
686
687
  		int word = AUDIT_WORD(ctx->major);
  		int bit  = AUDIT_BIT(ctx->major);
  
  		list_for_each_entry_rcu(e, list, list) {
f368c07d7   Amy Griffis   [PATCH] audit: pa...
688
689
  			if ((e->rule.mask[word] & bit) == bit &&
  			    audit_filter_rules(tsk, &e->rule, ctx, NULL,
f56298835   Tony Jones   audit: acquire cr...
690
  					       &state, false)) {
f368c07d7   Amy Griffis   [PATCH] audit: pa...
691
  				rcu_read_unlock();
0590b9335   Al Viro   fixing audit rule...
692
  				ctx->current_state = state;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
693
694
695
696
697
698
699
700
701
702
703
704
705
  				return state;
  			}
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
  
  /* At syscall exit time, this filter is called if any audit_names[] have been
   * collected during syscall processing.  We only check rules in sublists at hash
   * buckets applicable to the inode numbers in audit_names[].
   * Regarding audit_state, same rules apply as for audit_filter_syscall().
   */
0590b9335   Al Viro   fixing audit rule...
706
  void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
f368c07d7   Amy Griffis   [PATCH] audit: pa...
707
708
709
710
711
712
  {
  	int i;
  	struct audit_entry *e;
  	enum audit_state state;
  
  	if (audit_pid && tsk->tgid == audit_pid)
0590b9335   Al Viro   fixing audit rule...
713
  		return;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
  
  	rcu_read_lock();
  	for (i = 0; i < ctx->name_count; i++) {
  		int word = AUDIT_WORD(ctx->major);
  		int bit  = AUDIT_BIT(ctx->major);
  		struct audit_names *n = &ctx->names[i];
  		int h = audit_hash_ino((u32)n->ino);
  		struct list_head *list = &audit_inode_hash[h];
  
  		if (list_empty(list))
  			continue;
  
  		list_for_each_entry_rcu(e, list, list) {
  			if ((e->rule.mask[word] & bit) == bit &&
f56298835   Tony Jones   audit: acquire cr...
728
729
  			    audit_filter_rules(tsk, &e->rule, ctx, n,
  				    	       &state, false)) {
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
730
  				rcu_read_unlock();
0590b9335   Al Viro   fixing audit rule...
731
732
  				ctx->current_state = state;
  				return;
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
733
  			}
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
734
735
736
  		}
  	}
  	rcu_read_unlock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
737
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
739
  static inline struct audit_context *audit_get_context(struct task_struct *tsk,
  						      int return_valid,
6d208da89   Paul Moore   audit: Fix possib...
740
  						      long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
741
742
743
744
745
746
  {
  	struct audit_context *context = tsk->audit_context;
  
  	if (likely(!context))
  		return NULL;
  	context->return_valid = return_valid;
f701b75ed   Eric Paris   [AUDIT] return EI...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  
  	/*
  	 * we need to fix up the return code in the audit logs if the actual
  	 * return codes are later going to be fixed up by the arch specific
  	 * signal handlers
  	 *
  	 * This is actually a test for:
  	 * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) ||
  	 * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK)
  	 *
  	 * but is faster than a bunch of ||
  	 */
  	if (unlikely(return_code <= -ERESTARTSYS) &&
  	    (return_code >= -ERESTART_RESTARTBLOCK) &&
  	    (return_code != -ENOIOCTLCMD))
  		context->return_code = -EINTR;
  	else
  		context->return_code  = return_code;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765

0590b9335   Al Viro   fixing audit rule...
766
767
768
  	if (context->in_syscall && !context->dummy) {
  		audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
  		audit_filter_inodes(tsk, context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
771
772
773
774
775
776
777
778
  	tsk->audit_context = NULL;
  	return context;
  }
  
  static inline void audit_free_names(struct audit_context *context)
  {
  	int i;
  
  #if AUDIT_DEBUG == 2
0590b9335   Al Viro   fixing audit rule...
779
  	if (context->put_count + context->ino_count != context->name_count) {
73241ccca   Amy Griffis   [PATCH] Collect m...
780
  		printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
782
783
  		       " name_count=%d put_count=%d"
  		       " ino_count=%d [NOT freeing]
  ",
73241ccca   Amy Griffis   [PATCH] Collect m...
784
  		       __FILE__, __LINE__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
  		       context->serial, context->major, context->in_syscall,
  		       context->name_count, context->put_count,
  		       context->ino_count);
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
788
  		for (i = 0; i < context->name_count; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
791
  			printk(KERN_ERR "names[%d] = %p = %s
  ", i,
  			       context->names[i].name,
73241ccca   Amy Griffis   [PATCH] Collect m...
792
  			       context->names[i].name ?: "(null)");
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
793
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
795
796
797
798
799
800
801
  		dump_stack();
  		return;
  	}
  #endif
  #if AUDIT_DEBUG
  	context->put_count  = 0;
  	context->ino_count  = 0;
  #endif
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
802
  	for (i = 0; i < context->name_count; i++) {
9c937dcc7   Amy Griffis   [PATCH] log more ...
803
  		if (context->names[i].name && context->names[i].name_put)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
  			__putname(context->names[i].name);
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
805
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  	context->name_count = 0;
44707fdf5   Jan Blunck   d_path: Use struc...
807
808
809
  	path_put(&context->pwd);
  	context->pwd.dentry = NULL;
  	context->pwd.mnt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810
811
812
813
814
815
816
817
818
819
  }
  
  static inline void audit_free_aux(struct audit_context *context)
  {
  	struct audit_aux_data *aux;
  
  	while ((aux = context->aux)) {
  		context->aux = aux->next;
  		kfree(aux);
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
820
821
822
823
  	while ((aux = context->aux_pids)) {
  		context->aux_pids = aux->next;
  		kfree(aux);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
825
826
827
828
  }
  
  static inline void audit_zero_context(struct audit_context *context,
  				      enum audit_state state)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
  	memset(context, 0, sizeof(*context));
  	context->state      = state;
0590b9335   Al Viro   fixing audit rule...
831
  	context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
833
834
835
836
837
838
839
840
  }
  
  static inline struct audit_context *audit_alloc_context(enum audit_state state)
  {
  	struct audit_context *context;
  
  	if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
  		return NULL;
  	audit_zero_context(context, state);
916d75761   Al Viro   Fix rule eviction...
841
  	INIT_LIST_HEAD(&context->killed_trees);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
843
  	return context;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
844
845
846
847
848
  /**
   * audit_alloc - allocate an audit context block for a task
   * @tsk: task
   *
   * Filter on the task information and allocate a per-task audit context
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
850
   * if necessary.  Doing so turns on system call auditing for the
   * specified task.  This is called from copy_process, so no lock is
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
851
852
   * needed.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
855
856
  int audit_alloc(struct task_struct *tsk)
  {
  	struct audit_context *context;
  	enum audit_state     state;
e048e02c8   Al Viro   make sure that fi...
857
  	char *key = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858

b593d384e   Eric Paris   [AUDIT] create co...
859
  	if (likely(!audit_ever_enabled))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
  		return 0; /* Return if not auditing. */
e048e02c8   Al Viro   make sure that fi...
861
  	state = audit_filter_task(tsk, &key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
865
  	if (likely(state == AUDIT_DISABLED))
  		return 0;
  
  	if (!(context = audit_alloc_context(state))) {
e048e02c8   Al Viro   make sure that fi...
866
  		kfree(key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
869
  		audit_log_lost("out of memory in audit_alloc");
  		return -ENOMEM;
  	}
e048e02c8   Al Viro   make sure that fi...
870
  	context->filterkey = key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
  	tsk->audit_context  = context;
  	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
  	return 0;
  }
  
  static inline void audit_free_context(struct audit_context *context)
  {
  	struct audit_context *previous;
  	int		     count = 0;
  
  	do {
  		previous = context->previous;
  		if (previous || (count &&  count < 10)) {
  			++count;
  			printk(KERN_ERR "audit(:%d): major=%d name_count=%d:"
  			       " freeing multiple contexts (%d)
  ",
  			       context->serial, context->major,
  			       context->name_count, count);
  		}
  		audit_free_names(context);
74c3cbe33   Al Viro   [PATCH] audit: wa...
893
894
  		unroll_tree_refs(context, NULL, 0);
  		free_tree_refs(context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
  		audit_free_aux(context);
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
896
  		kfree(context->filterkey);
4f6b434fe   Al Viro   don't reallocate ...
897
  		kfree(context->sockaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
899
900
901
902
903
904
  		kfree(context);
  		context  = previous;
  	} while (context);
  	if (count >= 10)
  		printk(KERN_ERR "audit: freed %d contexts
  ", count);
  }
161a09e73   Joy Latten   audit: Add auditi...
905
  void audit_log_task_context(struct audit_buffer *ab)
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
906
907
  {
  	char *ctx = NULL;
c4823bce0   Al Viro   [PATCH] fix deadl...
908
909
910
  	unsigned len;
  	int error;
  	u32 sid;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
911
  	security_task_getsecid(current, &sid);
c4823bce0   Al Viro   [PATCH] fix deadl...
912
913
  	if (!sid)
  		return;
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
914

2a862b32f   Ahmed S. Darwish   Audit: use new LS...
915
  	error = security_secid_to_secctx(sid, &ctx, &len);
c4823bce0   Al Viro   [PATCH] fix deadl...
916
917
  	if (error) {
  		if (error != -EINVAL)
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
918
919
920
  			goto error_path;
  		return;
  	}
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
921
  	audit_log_format(ab, " subj=%s", ctx);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
922
  	security_release_secctx(ctx, len);
7306a0b9b   Dustin Kirkland   [PATCH] Miscellan...
923
  	return;
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
924
925
  
  error_path:
7306a0b9b   Dustin Kirkland   [PATCH] Miscellan...
926
  	audit_panic("error in audit_log_task_context");
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
927
928
  	return;
  }
161a09e73   Joy Latten   audit: Add auditi...
929
  EXPORT_SYMBOL(audit_log_task_context);
e495149b1   Al Viro   [PATCH] drop gfp_...
930
  static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
219f08170   Stephen Smalley   [PATCH] SELinux: ...
931
  {
45d9bb0e3   Al Viro   [PATCH] deal with...
932
933
  	char name[sizeof(tsk->comm)];
  	struct mm_struct *mm = tsk->mm;
219f08170   Stephen Smalley   [PATCH] SELinux: ...
934
  	struct vm_area_struct *vma;
e495149b1   Al Viro   [PATCH] drop gfp_...
935
  	/* tsk == current */
45d9bb0e3   Al Viro   [PATCH] deal with...
936
  	get_task_comm(name, tsk);
99e45eeac   David Woodhouse   AUDIT: Escape com...
937
938
  	audit_log_format(ab, " comm=");
  	audit_log_untrustedstring(ab, name);
219f08170   Stephen Smalley   [PATCH] SELinux: ...
939

e495149b1   Al Viro   [PATCH] drop gfp_...
940
941
942
943
944
945
946
  	if (mm) {
  		down_read(&mm->mmap_sem);
  		vma = mm->mmap;
  		while (vma) {
  			if ((vma->vm_flags & VM_EXECUTABLE) &&
  			    vma->vm_file) {
  				audit_log_d_path(ab, "exe=",
44707fdf5   Jan Blunck   d_path: Use struc...
947
  						 &vma->vm_file->f_path);
e495149b1   Al Viro   [PATCH] drop gfp_...
948
949
950
  				break;
  			}
  			vma = vma->vm_next;
219f08170   Stephen Smalley   [PATCH] SELinux: ...
951
  		}
e495149b1   Al Viro   [PATCH] drop gfp_...
952
  		up_read(&mm->mmap_sem);
219f08170   Stephen Smalley   [PATCH] SELinux: ...
953
  	}
e495149b1   Al Viro   [PATCH] drop gfp_...
954
  	audit_log_task_context(ab);
219f08170   Stephen Smalley   [PATCH] SELinux: ...
955
  }
e54dc2431   Amy Griffis   [PATCH] audit sig...
956
  static int audit_log_pid_context(struct audit_context *context, pid_t pid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
957
958
  				 uid_t auid, uid_t uid, unsigned int sessionid,
  				 u32 sid, char *comm)
e54dc2431   Amy Griffis   [PATCH] audit sig...
959
960
  {
  	struct audit_buffer *ab;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
961
  	char *ctx = NULL;
e54dc2431   Amy Griffis   [PATCH] audit sig...
962
963
964
965
966
  	u32 len;
  	int rc = 0;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
  	if (!ab)
6246ccab9   Eric Paris   [AUDIT] do not pa...
967
  		return rc;
e54dc2431   Amy Griffis   [PATCH] audit sig...
968

4746ec5b0   Eric Paris   [AUDIT] add sessi...
969
970
  	audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid,
  			 uid, sessionid);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
971
  	if (security_secid_to_secctx(sid, &ctx, &len)) {
c2a7780ef   Eric Paris   [AUDIT] collect u...
972
  		audit_log_format(ab, " obj=(none)");
e54dc2431   Amy Griffis   [PATCH] audit sig...
973
  		rc = 1;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
974
975
976
977
  	} else {
  		audit_log_format(ab, " obj=%s", ctx);
  		security_release_secctx(ctx, len);
  	}
c2a7780ef   Eric Paris   [AUDIT] collect u...
978
979
  	audit_log_format(ab, " ocomm=");
  	audit_log_untrustedstring(ab, comm);
e54dc2431   Amy Griffis   [PATCH] audit sig...
980
  	audit_log_end(ab);
e54dc2431   Amy Griffis   [PATCH] audit sig...
981
982
983
  
  	return rc;
  }
de6bbd1d3   Eric Paris   [AUDIT] break lar...
984
985
986
  /*
   * to_send and len_sent accounting are very loose estimates.  We aren't
   * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being
25985edce   Lucas De Marchi   Fix common misspe...
987
   * within about 500 bytes (next page boundary)
de6bbd1d3   Eric Paris   [AUDIT] break lar...
988
989
990
991
992
993
994
995
996
997
998
999
1000
   *
   * why snprintf?  an int is up to 12 digits long.  if we just assumed when
   * logging that a[%d]= was going to be 16 characters long we would be wasting
   * space in every audit message.  In one 7500 byte message we can log up to
   * about 1000 min size arguments.  That comes down to about 50% waste of space
   * if we didn't do the snprintf to find out how long arg_num_len was.
   */
  static int audit_log_single_execve_arg(struct audit_context *context,
  					struct audit_buffer **ab,
  					int arg_num,
  					size_t *len_sent,
  					const char __user *p,
  					char *buf)
bdf4c48af   Peter Zijlstra   audit: rework exe...
1001
  {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1002
1003
  	char arg_num_len_buf[12];
  	const char __user *tmp_p = p;
b87ce6e41   Eric Paris   Audit: better est...
1004
1005
  	/* how many digits are in arg_num? 5 is the length of ' a=""' */
  	size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1006
1007
1008
1009
1010
1011
1012
  	size_t len, len_left, to_send;
  	size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
  	unsigned int i, has_cntl = 0, too_long = 0;
  	int ret;
  
  	/* strnlen_user includes the null we don't want to send */
  	len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1013

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1014
1015
1016
1017
1018
1019
  	/*
  	 * We just created this mm, if we can't find the strings
  	 * we just copied into it something is _very_ wrong. Similar
  	 * for strings that are too long, we should not have created
  	 * any.
  	 */
b0abcfc14   Eric Paris   Audit: use == not...
1020
  	if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1021
1022
  		WARN_ON(1);
  		send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1023
  		return -1;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1024
  	}
040b3a2df   Peter Zijlstra   audit: fix two bu...
1025

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1026
1027
1028
1029
1030
1031
1032
  	/* walk the whole argument looking for non-ascii chars */
  	do {
  		if (len_left > MAX_EXECVE_AUDIT_LEN)
  			to_send = MAX_EXECVE_AUDIT_LEN;
  		else
  			to_send = len_left;
  		ret = copy_from_user(buf, tmp_p, to_send);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1033
  		/*
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1034
1035
1036
  		 * There is no reason for this copy to be short. We just
  		 * copied them here, and the mm hasn't been exposed to user-
  		 * space yet.
bdf4c48af   Peter Zijlstra   audit: rework exe...
1037
  		 */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1038
  		if (ret) {
bdf4c48af   Peter Zijlstra   audit: rework exe...
1039
1040
  			WARN_ON(1);
  			send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1041
  			return -1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1042
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1043
1044
1045
1046
1047
1048
1049
1050
  		buf[to_send] = '\0';
  		has_cntl = audit_string_contains_control(buf, to_send);
  		if (has_cntl) {
  			/*
  			 * hex messages get logged as 2 bytes, so we can only
  			 * send half as much in each message
  			 */
  			max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1051
1052
  			break;
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
  		len_left -= to_send;
  		tmp_p += to_send;
  	} while (len_left > 0);
  
  	len_left = len;
  
  	if (len > max_execve_audit_len)
  		too_long = 1;
  
  	/* rewalk the argument actually logging the message */
  	for (i = 0; len_left > 0; i++) {
  		int room_left;
  
  		if (len_left > max_execve_audit_len)
  			to_send = max_execve_audit_len;
  		else
  			to_send = len_left;
  
  		/* do we have space left to send this argument in this ab? */
  		room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent;
  		if (has_cntl)
  			room_left -= (to_send * 2);
  		else
  			room_left -= to_send;
  		if (room_left < 0) {
  			*len_sent = 0;
  			audit_log_end(*ab);
  			*ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE);
  			if (!*ab)
  				return 0;
  		}
bdf4c48af   Peter Zijlstra   audit: rework exe...
1084

bdf4c48af   Peter Zijlstra   audit: rework exe...
1085
  		/*
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1086
1087
1088
1089
  		 * first record needs to say how long the original string was
  		 * so we can be sure nothing was lost.
  		 */
  		if ((i == 0) && (too_long))
ca96a895a   Jiri Pirko   audit: EXECVE rec...
1090
  			audit_log_format(*ab, " a%d_len=%zu", arg_num,
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1091
1092
1093
1094
1095
1096
  					 has_cntl ? 2*len : len);
  
  		/*
  		 * normally arguments are small enough to fit and we already
  		 * filled buf above when we checked for control characters
  		 * so don't bother with another copy_from_user
bdf4c48af   Peter Zijlstra   audit: rework exe...
1097
  		 */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1098
1099
1100
1101
  		if (len >= max_execve_audit_len)
  			ret = copy_from_user(buf, p, to_send);
  		else
  			ret = 0;
040b3a2df   Peter Zijlstra   audit: fix two bu...
1102
  		if (ret) {
bdf4c48af   Peter Zijlstra   audit: rework exe...
1103
1104
  			WARN_ON(1);
  			send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1105
  			return -1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1106
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1107
1108
1109
  		buf[to_send] = '\0';
  
  		/* actually log it */
ca96a895a   Jiri Pirko   audit: EXECVE rec...
1110
  		audit_log_format(*ab, " a%d", arg_num);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1111
1112
1113
1114
  		if (too_long)
  			audit_log_format(*ab, "[%d]", i);
  		audit_log_format(*ab, "=");
  		if (has_cntl)
b556f8ad5   Eric Paris   Audit: standardiz...
1115
  			audit_log_n_hex(*ab, buf, to_send);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1116
  		else
9d9609851   Eric Paris   Audit: clean up a...
1117
  			audit_log_string(*ab, buf);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
  
  		p += to_send;
  		len_left -= to_send;
  		*len_sent += arg_num_len;
  		if (has_cntl)
  			*len_sent += to_send * 2;
  		else
  			*len_sent += to_send;
  	}
  	/* include the null we didn't log */
  	return len + 1;
  }
  
  static void audit_log_execve_info(struct audit_context *context,
  				  struct audit_buffer **ab,
  				  struct audit_aux_data_execve *axi)
  {
  	int i;
  	size_t len, len_sent = 0;
  	const char __user *p;
  	char *buf;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1139

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1140
1141
1142
1143
  	if (axi->mm != current->mm)
  		return; /* execve failed, no additional info */
  
  	p = (const char __user *)axi->mm->arg_start;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1144

ca96a895a   Jiri Pirko   audit: EXECVE rec...
1145
  	audit_log_format(*ab, "argc=%d", axi->argc);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
  
  	/*
  	 * we need some kernel buffer to hold the userspace args.  Just
  	 * allocate one big one rather than allocating one of the right size
  	 * for every single argument inside audit_log_single_execve_arg()
  	 * should be <8k allocation so should be pretty safe.
  	 */
  	buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
  	if (!buf) {
  		audit_panic("out of memory for argv string
  ");
  		return;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1158
  	}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1159
1160
1161
1162
1163
1164
1165
1166
1167
  
  	for (i = 0; i < axi->argc; i++) {
  		len = audit_log_single_execve_arg(context, ab, i,
  						  &len_sent, p, buf);
  		if (len <= 0)
  			break;
  		p += len;
  	}
  	kfree(buf);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1168
  }
851f7ff56   Eric Paris   This patch will p...
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap)
  {
  	int i;
  
  	audit_log_format(ab, " %s=", prefix);
  	CAP_FOR_EACH_U32(i) {
  		audit_log_format(ab, "%08x", cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]);
  	}
  }
  
  static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
  {
  	kernel_cap_t *perm = &name->fcap.permitted;
  	kernel_cap_t *inh = &name->fcap.inheritable;
  	int log = 0;
  
  	if (!cap_isclear(*perm)) {
  		audit_log_cap(ab, "cap_fp", perm);
  		log = 1;
  	}
  	if (!cap_isclear(*inh)) {
  		audit_log_cap(ab, "cap_fi", inh);
  		log = 1;
  	}
  
  	if (log)
  		audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver);
  }
a33e67510   Al Viro   sanitize audit_ip...
1197
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  {
  	struct audit_buffer *ab;
  	int i;
  
  	ab = audit_log_start(context, GFP_KERNEL, context->type);
  	if (!ab)
  		return;
  
  	switch (context->type) {
  	case AUDIT_SOCKETCALL: {
  		int nargs = context->socketcall.nargs;
  		audit_log_format(ab, "nargs=%d", nargs);
  		for (i = 0; i < nargs; i++)
  			audit_log_format(ab, " a%d=%lx", i,
  				context->socketcall.args[i]);
  		break; }
a33e67510   Al Viro   sanitize audit_ip...
1214
1215
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1216
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
a33e67510   Al Viro   sanitize audit_ip...
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
  			 context->ipc.uid, context->ipc.gid, context->ipc.mode);
  		if (osid) {
  			char *ctx = NULL;
  			u32 len;
  			if (security_secid_to_secctx(osid, &ctx, &len)) {
  				audit_log_format(ab, " osid=%u", osid);
  				*call_panic = 1;
  			} else {
  				audit_log_format(ab, " obj=%s", ctx);
  				security_release_secctx(ctx, len);
  			}
  		}
e816f370c   Al Viro   sanitize audit_ip...
1229
1230
1231
1232
1233
  		if (context->ipc.has_perm) {
  			audit_log_end(ab);
  			ab = audit_log_start(context, GFP_KERNEL,
  					     AUDIT_IPC_SET_PERM);
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1234
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1235
1236
1237
1238
1239
1240
1241
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
  			if (!ab)
  				return;
  		}
a33e67510   Al Viro   sanitize audit_ip...
1242
  		break; }
564f6993f   Al Viro   sanitize audit_mq...
1243
1244
  	case AUDIT_MQ_OPEN: {
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1245
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1246
1247
1248
1249
1250
1251
1252
  			"mq_msgsize=%ld mq_curmsgs=%ld",
  			context->mq_open.oflag, context->mq_open.mode,
  			context->mq_open.attr.mq_flags,
  			context->mq_open.attr.mq_maxmsg,
  			context->mq_open.attr.mq_msgsize,
  			context->mq_open.attr.mq_curmsgs);
  		break; }
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
  	case AUDIT_MQ_SENDRECV: {
  		audit_log_format(ab,
  			"mqdes=%d msg_len=%zd msg_prio=%u "
  			"abs_timeout_sec=%ld abs_timeout_nsec=%ld",
  			context->mq_sendrecv.mqdes,
  			context->mq_sendrecv.msg_len,
  			context->mq_sendrecv.msg_prio,
  			context->mq_sendrecv.abs_timeout.tv_sec,
  			context->mq_sendrecv.abs_timeout.tv_nsec);
  		break; }
20114f71b   Al Viro   sanitize audit_mq...
1263
1264
1265
1266
1267
  	case AUDIT_MQ_NOTIFY: {
  		audit_log_format(ab, "mqdes=%d sigev_signo=%d",
  				context->mq_notify.mqdes,
  				context->mq_notify.sigev_signo);
  		break; }
7392906ea   Al Viro   sanitize audit_mq...
1268
1269
1270
1271
1272
1273
1274
1275
1276
  	case AUDIT_MQ_GETSETATTR: {
  		struct mq_attr *attr = &context->mq_getsetattr.mqstat;
  		audit_log_format(ab,
  			"mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld "
  			"mq_curmsgs=%ld ",
  			context->mq_getsetattr.mqdes,
  			attr->mq_flags, attr->mq_maxmsg,
  			attr->mq_msgsize, attr->mq_curmsgs);
  		break; }
57f71a0af   Al Viro   sanitize audit_lo...
1277
1278
1279
1280
1281
1282
  	case AUDIT_CAPSET: {
  		audit_log_format(ab, "pid=%d", context->capset.pid);
  		audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable);
  		audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted);
  		audit_log_cap(ab, "cap_pe", &context->capset.cap.effective);
  		break; }
120a795da   Al Viro   audit mmap
1283
1284
1285
1286
  	case AUDIT_MMAP: {
  		audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
  				 context->mmap.flags);
  		break; }
f3298dc4f   Al Viro   sanitize audit_so...
1287
1288
1289
  	}
  	audit_log_end(ab);
  }
e495149b1   Al Viro   [PATCH] drop gfp_...
1290
  static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
  {
c69e8d9c0   David Howells   CRED: Use RCU to ...
1292
  	const struct cred *cred;
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1293
  	int i, call_panic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1294
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1295
  	struct audit_aux_data *aux;
a6c043a88   Steve Grubb   [PATCH] Add tty t...
1296
  	const char *tty;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297

e495149b1   Al Viro   [PATCH] drop gfp_...
1298
  	/* tsk == current */
3f2792ffb   Al Viro   [PATCH] take fill...
1299
  	context->pid = tsk->pid;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1300
1301
  	if (!context->ppid)
  		context->ppid = sys_getppid();
c69e8d9c0   David Howells   CRED: Use RCU to ...
1302
1303
1304
1305
1306
  	cred = current_cred();
  	context->uid   = cred->uid;
  	context->gid   = cred->gid;
  	context->euid  = cred->euid;
  	context->suid  = cred->suid;
b6dff3ec5   David Howells   CRED: Separate ta...
1307
  	context->fsuid = cred->fsuid;
c69e8d9c0   David Howells   CRED: Use RCU to ...
1308
1309
  	context->egid  = cred->egid;
  	context->sgid  = cred->sgid;
b6dff3ec5   David Howells   CRED: Separate ta...
1310
  	context->fsgid = cred->fsgid;
3f2792ffb   Al Viro   [PATCH] take fill...
1311
  	context->personality = tsk->personality;
e495149b1   Al Viro   [PATCH] drop gfp_...
1312
1313
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
1315
  	if (!ab)
  		return;		/* audit_panic has been called */
bccf6ae08   David Woodhouse   AUDIT: Unify auid...
1316
1317
  	audit_log_format(ab, "arch=%x syscall=%d",
  			 context->arch, context->major);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1318
1319
1320
  	if (context->personality != PER_LINUX)
  		audit_log_format(ab, " per=%lx", context->personality);
  	if (context->return_valid)
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1321
  		audit_log_format(ab, " success=%s exit=%ld",
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1322
1323
  				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
  				 context->return_code);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1324

dbda4c0b9   Alan Cox   tty: Fix abusers ...
1325
  	spin_lock_irq(&tsk->sighand->siglock);
45d9bb0e3   Al Viro   [PATCH] deal with...
1326
1327
  	if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
  		tty = tsk->signal->tty->name;
a6c043a88   Steve Grubb   [PATCH] Add tty t...
1328
1329
  	else
  		tty = "(none)";
dbda4c0b9   Alan Cox   tty: Fix abusers ...
1330
  	spin_unlock_irq(&tsk->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1331
1332
  	audit_log_format(ab,
  		  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
f46038ff7   Al Viro   [PATCH] log ppid
1333
  		  " ppid=%d pid=%d auid=%u uid=%u gid=%u"
326e9c8ba   Steve Grubb   AUDIT: Fix incons...
1334
  		  " euid=%u suid=%u fsuid=%u"
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1335
  		  " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
1337
1338
1339
1340
  		  context->argv[0],
  		  context->argv[1],
  		  context->argv[2],
  		  context->argv[3],
  		  context->name_count,
f46038ff7   Al Viro   [PATCH] log ppid
1341
  		  context->ppid,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1342
  		  context->pid,
bfef93a5d   Al Viro   [PATCH] get rid o...
1343
  		  tsk->loginuid,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344
1345
1346
  		  context->uid,
  		  context->gid,
  		  context->euid, context->suid, context->fsuid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1347
1348
  		  context->egid, context->sgid, context->fsgid, tty,
  		  tsk->sessionid);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1349

eb84a20e9   Alan Cox   [PATCH] audit/acc...
1350

e495149b1   Al Viro   [PATCH] drop gfp_...
1351
  	audit_log_task_info(ab, tsk);
9d9609851   Eric Paris   Audit: clean up a...
1352
  	audit_log_key(ab, context->filterkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  	audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354

7551ced33   David Woodhouse   AUDIT: Defer free...
1355
  	for (aux = context->aux; aux; aux = aux->next) {
c04049939   Steve Grubb   AUDIT: Add messag...
1356

e495149b1   Al Viro   [PATCH] drop gfp_...
1357
  		ab = audit_log_start(context, GFP_KERNEL, aux->type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358
1359
  		if (!ab)
  			continue; /* audit_panic has been called */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
  		switch (aux->type) {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1361

473ae30bc   Al Viro   [PATCH] execve ar...
1362
1363
  		case AUDIT_EXECVE: {
  			struct audit_aux_data_execve *axi = (void *)aux;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1364
  			audit_log_execve_info(context, &ab, axi);
473ae30bc   Al Viro   [PATCH] execve ar...
1365
  			break; }
073115d6b   Steve Grubb   [PATCH] Rework of...
1366

3fc689e96   Eric Paris   Any time fcaps or...
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
  		case AUDIT_BPRM_FCAPS: {
  			struct audit_aux_data_bprm_fcaps *axs = (void *)aux;
  			audit_log_format(ab, "fver=%x", axs->fcap_ver);
  			audit_log_cap(ab, "fp", &axs->fcap.permitted);
  			audit_log_cap(ab, "fi", &axs->fcap.inheritable);
  			audit_log_format(ab, " fe=%d", axs->fcap.fE);
  			audit_log_cap(ab, "old_pp", &axs->old_pcap.permitted);
  			audit_log_cap(ab, "old_pi", &axs->old_pcap.inheritable);
  			audit_log_cap(ab, "old_pe", &axs->old_pcap.effective);
  			audit_log_cap(ab, "new_pp", &axs->new_pcap.permitted);
  			audit_log_cap(ab, "new_pi", &axs->new_pcap.inheritable);
  			audit_log_cap(ab, "new_pe", &axs->new_pcap.effective);
  			break; }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1380
1381
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1383
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1384
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1385

157cf649a   Al Viro   sanitize audit_fd...
1386
1387
1388
1389
1390
1391
1392
1393
  	if (context->fds[0] >= 0) {
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_FD_PAIR);
  		if (ab) {
  			audit_log_format(ab, "fd0=%d fd1=%d",
  					context->fds[0], context->fds[1]);
  			audit_log_end(ab);
  		}
  	}
4f6b434fe   Al Viro   don't reallocate ...
1394
1395
1396
1397
1398
1399
1400
1401
1402
  	if (context->sockaddr_len) {
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
  		if (ab) {
  			audit_log_format(ab, "saddr=");
  			audit_log_n_hex(ab, (void *)context->sockaddr,
  					context->sockaddr_len);
  			audit_log_end(ab);
  		}
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1403
1404
  	for (aux = context->aux_pids; aux; aux = aux->next) {
  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1405
1406
1407
  
  		for (i = 0; i < axs->pid_count; i++)
  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1408
1409
  						  axs->target_auid[i],
  						  axs->target_uid[i],
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1410
  						  axs->target_sessionid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1411
1412
  						  axs->target_sid[i],
  						  axs->target_comm[i]))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1413
  				call_panic = 1;
a5cb013da   Al Viro   [PATCH] auditing ...
1414
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1415
1416
  	if (context->target_pid &&
  	    audit_log_pid_context(context, context->target_pid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1417
  				  context->target_auid, context->target_uid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1418
  				  context->target_sessionid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1419
  				  context->target_sid, context->target_comm))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1420
  			call_panic = 1;
44707fdf5   Jan Blunck   d_path: Use struc...
1421
  	if (context->pwd.dentry && context->pwd.mnt) {
e495149b1   Al Viro   [PATCH] drop gfp_...
1422
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1423
  		if (ab) {
44707fdf5   Jan Blunck   d_path: Use struc...
1424
  			audit_log_d_path(ab, "cwd=", &context->pwd);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1425
1426
1427
  			audit_log_end(ab);
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
  	for (i = 0; i < context->name_count; i++) {
9c937dcc7   Amy Griffis   [PATCH] log more ...
1429
  		struct audit_names *n = &context->names[i];
73241ccca   Amy Griffis   [PATCH] Collect m...
1430

e495149b1   Al Viro   [PATCH] drop gfp_...
1431
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
  		if (!ab)
  			continue; /* audit_panic has been called */
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1434

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
  		audit_log_format(ab, "item=%d", i);
73241ccca   Amy Griffis   [PATCH] Collect m...
1436

9c937dcc7   Amy Griffis   [PATCH] log more ...
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
  		if (n->name) {
  			switch(n->name_len) {
  			case AUDIT_NAME_FULL:
  				/* log the full path */
  				audit_log_format(ab, " name=");
  				audit_log_untrustedstring(ab, n->name);
  				break;
  			case 0:
  				/* name was specified as a relative path and the
  				 * directory component is the cwd */
def575434   Eric Paris   Audit: remove spa...
1447
  				audit_log_d_path(ab, "name=", &context->pwd);
9c937dcc7   Amy Griffis   [PATCH] log more ...
1448
1449
1450
1451
  				break;
  			default:
  				/* log the name's directory component */
  				audit_log_format(ab, " name=");
b556f8ad5   Eric Paris   Audit: standardiz...
1452
1453
  				audit_log_n_untrustedstring(ab, n->name,
  							    n->name_len);
9c937dcc7   Amy Griffis   [PATCH] log more ...
1454
1455
1456
1457
1458
1459
  			}
  		} else
  			audit_log_format(ab, " name=(null)");
  
  		if (n->ino != (unsigned long)-1) {
  			audit_log_format(ab, " inode=%lu"
93d3a10ef   Al Viro   auditsc: propage ...
1460
  					 " dev=%02x:%02x mode=%#ho"
9c937dcc7   Amy Griffis   [PATCH] log more ...
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
  					 " ouid=%u ogid=%u rdev=%02x:%02x",
  					 n->ino,
  					 MAJOR(n->dev),
  					 MINOR(n->dev),
  					 n->mode,
  					 n->uid,
  					 n->gid,
  					 MAJOR(n->rdev),
  					 MINOR(n->rdev));
  		}
  		if (n->osid != 0) {
1b50eed9c   Steve Grubb   [PATCH] audit ino...
1472
1473
  			char *ctx = NULL;
  			u32 len;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
1474
  			if (security_secid_to_secctx(
9c937dcc7   Amy Griffis   [PATCH] log more ...
1475
1476
  				n->osid, &ctx, &len)) {
  				audit_log_format(ab, " osid=%u", n->osid);
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1477
  				call_panic = 2;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
1478
  			} else {
1b50eed9c   Steve Grubb   [PATCH] audit ino...
1479
  				audit_log_format(ab, " obj=%s", ctx);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
1480
1481
  				security_release_secctx(ctx, len);
  			}
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
1482
  		}
851f7ff56   Eric Paris   This patch will p...
1483
  		audit_log_fcaps(ab, n);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
1485
  		audit_log_end(ab);
  	}
c0641f28d   Eric Paris   [AUDIT] Add End o...
1486
1487
1488
1489
1490
  
  	/* Send end of event record to help user space know we are finished */
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
  	if (ab)
  		audit_log_end(ab);
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1491
1492
  	if (call_panic)
  		audit_panic("error converting sid to string");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1493
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1494
1495
1496
1497
  /**
   * audit_free - free a per-task audit context
   * @tsk: task whose audit context block to free
   *
fa84cb935   Al Viro   [PATCH] move call...
1498
   * Called from copy_process and do_exit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1499
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
1501
1502
  void audit_free(struct task_struct *tsk)
  {
  	struct audit_context *context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  	context = audit_get_context(tsk, 0, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
1505
1506
1507
  	if (likely(!context))
  		return;
  
  	/* Check for system calls that do not go through the exit
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1508
1509
  	 * function (e.g., exit_group), then free context block.
  	 * We use GFP_ATOMIC here because we might be doing this
f55619642   David Woodhouse   AUDIT: Avoid sche...
1510
  	 * in the context of the idle thread */
e495149b1   Al Viro   [PATCH] drop gfp_...
1511
  	/* that can happen only if we are called from do_exit() */
0590b9335   Al Viro   fixing audit rule...
1512
  	if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
e495149b1   Al Viro   [PATCH] drop gfp_...
1513
  		audit_log_exit(context, tsk);
916d75761   Al Viro   Fix rule eviction...
1514
1515
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
1517
1518
  
  	audit_free_context(context);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1519
1520
  /**
   * audit_syscall_entry - fill in an audit record at syscall entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1521
1522
1523
1524
1525
1526
1527
1528
   * @arch: architecture type
   * @major: major syscall type (function)
   * @a1: additional syscall register 1
   * @a2: additional syscall register 2
   * @a3: additional syscall register 3
   * @a4: additional syscall register 4
   *
   * Fill in audit context at syscall entry.  This only happens if the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
1530
1531
1532
1533
   * audit context was created when the task was created and the state or
   * filters demand the audit context be built.  If the state from the
   * per-task filter or from the per-syscall filter is AUDIT_RECORD_CONTEXT,
   * then the record will be written at syscall exit time (otherwise, it
   * will only be written if another part of the kernel requests that it
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1534
1535
   * be written).
   */
5411be59d   Al Viro   [PATCH] drop task...
1536
  void audit_syscall_entry(int arch, int major,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
1538
1539
  			 unsigned long a1, unsigned long a2,
  			 unsigned long a3, unsigned long a4)
  {
5411be59d   Al Viro   [PATCH] drop task...
1540
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
1542
  	struct audit_context *context = tsk->audit_context;
  	enum audit_state     state;
86a1c34a9   Roland McGrath   x86_64 syscall au...
1543
1544
  	if (unlikely(!context))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1545

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1546
1547
  	/*
  	 * This happens only on certain architectures that make system
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1548
1549
1550
1551
1552
1553
1554
  	 * calls in kernel_thread via the entry.S interface, instead of
  	 * with direct calls.  (If you are porting to a new
  	 * architecture, hitting this condition can indicate that you
  	 * got the _exit/_leave calls backward in entry.S.)
  	 *
  	 * i386     no
  	 * x86_64   no
2ef9481e6   Jon Mason   [PATCH] powerpc: ...
1555
  	 * ppc64    yes (see arch/powerpc/platforms/iseries/misc.S)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
1557
1558
1559
1560
1561
  	 *
  	 * This also happens with vm86 emulation in a non-nested manner
  	 * (entries without exits), so this case must be caught.
  	 */
  	if (context->in_syscall) {
  		struct audit_context *newctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
  #if AUDIT_DEBUG
  		printk(KERN_ERR
  		       "audit(:%d) pid=%d in syscall=%d;"
  		       " entering syscall=%d
  ",
  		       context->serial, tsk->pid, context->major, major);
  #endif
  		newctx = audit_alloc_context(context->state);
  		if (newctx) {
  			newctx->previous   = context;
  			context		   = newctx;
  			tsk->audit_context = newctx;
  		} else	{
  			/* If we can't alloc a new context, the best we
  			 * can do is to leak memory (any pending putname
  			 * will be lost).  The only other alternative is
  			 * to abandon auditing. */
  			audit_zero_context(context, context->state);
  		}
  	}
  	BUG_ON(context->in_syscall || context->name_count);
  
  	if (!audit_enabled)
  		return;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1586
  	context->arch	    = arch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587
1588
1589
1590
1591
1592
1593
  	context->major      = major;
  	context->argv[0]    = a1;
  	context->argv[1]    = a2;
  	context->argv[2]    = a3;
  	context->argv[3]    = a4;
  
  	state = context->state;
d51374adf   Al Viro   [PATCH] mark cont...
1594
  	context->dummy = !audit_n_rules;
0590b9335   Al Viro   fixing audit rule...
1595
1596
  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
  		context->prio = 0;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1597
  		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
0590b9335   Al Viro   fixing audit rule...
1598
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1599
1600
  	if (likely(state == AUDIT_DISABLED))
  		return;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1601
  	context->serial     = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1602
1603
  	context->ctime      = CURRENT_TIME;
  	context->in_syscall = 1;
0590b9335   Al Viro   fixing audit rule...
1604
  	context->current_state  = state;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1605
  	context->ppid       = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1606
  }
a64e64944   Al Viro   [PATCH] return re...
1607
1608
1609
1610
  void audit_finish_fork(struct task_struct *child)
  {
  	struct audit_context *ctx = current->audit_context;
  	struct audit_context *p = child->audit_context;
0590b9335   Al Viro   fixing audit rule...
1611
1612
1613
  	if (!p || !ctx)
  		return;
  	if (!ctx->in_syscall || ctx->current_state != AUDIT_RECORD_CONTEXT)
a64e64944   Al Viro   [PATCH] return re...
1614
1615
1616
1617
1618
1619
  		return;
  	p->arch = ctx->arch;
  	p->major = ctx->major;
  	memcpy(p->argv, ctx->argv, sizeof(ctx->argv));
  	p->ctime = ctx->ctime;
  	p->dummy = ctx->dummy;
a64e64944   Al Viro   [PATCH] return re...
1620
1621
1622
  	p->in_syscall = ctx->in_syscall;
  	p->filterkey = kstrdup(ctx->filterkey, GFP_KERNEL);
  	p->ppid = current->pid;
0590b9335   Al Viro   fixing audit rule...
1623
1624
  	p->prio = ctx->prio;
  	p->current_state = ctx->current_state;
a64e64944   Al Viro   [PATCH] return re...
1625
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1626
1627
  /**
   * audit_syscall_exit - deallocate audit context after a system call
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1628
1629
1630
1631
   * @valid: success/failure flag
   * @return_code: syscall return value
   *
   * Tear down after system call.  If the audit context has been marked as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
1633
1634
   * auditable (either because of the AUDIT_RECORD_CONTEXT state from
   * filtering, or because some other part of the kernel write an audit
   * message), then write out the syscall information.  In call cases,
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1635
1636
   * free the names stored from getname().
   */
5411be59d   Al Viro   [PATCH] drop task...
1637
  void audit_syscall_exit(int valid, long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1638
  {
5411be59d   Al Viro   [PATCH] drop task...
1639
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1640
  	struct audit_context *context;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1641
  	context = audit_get_context(tsk, valid, return_code);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1642

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1643
  	if (likely(!context))
97e94c453   Al Viro   [PATCH] no need t...
1644
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1645

0590b9335   Al Viro   fixing audit rule...
1646
  	if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
e495149b1   Al Viro   [PATCH] drop gfp_...
1647
  		audit_log_exit(context, tsk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1648
1649
  
  	context->in_syscall = 0;
0590b9335   Al Viro   fixing audit rule...
1650
  	context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1651

916d75761   Al Viro   Fix rule eviction...
1652
1653
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
1655
1656
1657
1658
1659
1660
  	if (context->previous) {
  		struct audit_context *new_context = context->previous;
  		context->previous  = NULL;
  		audit_free_context(context);
  		tsk->audit_context = new_context;
  	} else {
  		audit_free_names(context);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1661
  		unroll_tree_refs(context, NULL, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
  		audit_free_aux(context);
e54dc2431   Amy Griffis   [PATCH] audit sig...
1663
1664
  		context->aux = NULL;
  		context->aux_pids = NULL;
a5cb013da   Al Viro   [PATCH] auditing ...
1665
  		context->target_pid = 0;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1666
  		context->target_sid = 0;
4f6b434fe   Al Viro   don't reallocate ...
1667
  		context->sockaddr_len = 0;
f3298dc4f   Al Viro   sanitize audit_so...
1668
  		context->type = 0;
157cf649a   Al Viro   sanitize audit_fd...
1669
  		context->fds[0] = -1;
e048e02c8   Al Viro   make sure that fi...
1670
1671
1672
1673
  		if (context->state != AUDIT_RECORD_CONTEXT) {
  			kfree(context->filterkey);
  			context->filterkey = NULL;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
1675
  		tsk->audit_context = context;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1677
1678
1679
1680
1681
1682
1683
  static inline void handle_one(const struct inode *inode)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_context *context;
  	struct audit_tree_refs *p;
  	struct audit_chunk *chunk;
  	int count;
e61ce8673   Eric Paris   fsnotify: rename ...
1684
  	if (likely(hlist_empty(&inode->i_fsnotify_marks)))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
  		return;
  	context = current->audit_context;
  	p = context->trees;
  	count = context->tree_count;
  	rcu_read_lock();
  	chunk = audit_tree_lookup(inode);
  	rcu_read_unlock();
  	if (!chunk)
  		return;
  	if (likely(put_tree_ref(context, chunk)))
  		return;
  	if (unlikely(!grow_tree_refs(context))) {
436c405c7   Eric Paris   Audit: end printk...
1697
1698
  		printk(KERN_WARNING "out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
  		audit_set_auditable(context);
  		audit_put_chunk(chunk);
  		unroll_tree_refs(context, p, count);
  		return;
  	}
  	put_tree_ref(context, chunk);
  #endif
  }
  
  static void handle_path(const struct dentry *dentry)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_context *context;
  	struct audit_tree_refs *p;
  	const struct dentry *d, *parent;
  	struct audit_chunk *drop;
  	unsigned long seq;
  	int count;
  
  	context = current->audit_context;
  	p = context->trees;
  	count = context->tree_count;
  retry:
  	drop = NULL;
  	d = dentry;
  	rcu_read_lock();
  	seq = read_seqbegin(&rename_lock);
  	for(;;) {
  		struct inode *inode = d->d_inode;
e61ce8673   Eric Paris   fsnotify: rename ...
1728
  		if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_marks))) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
  			struct audit_chunk *chunk;
  			chunk = audit_tree_lookup(inode);
  			if (chunk) {
  				if (unlikely(!put_tree_ref(context, chunk))) {
  					drop = chunk;
  					break;
  				}
  			}
  		}
  		parent = d->d_parent;
  		if (parent == d)
  			break;
  		d = parent;
  	}
  	if (unlikely(read_seqretry(&rename_lock, seq) || drop)) {  /* in this order */
  		rcu_read_unlock();
  		if (!drop) {
  			/* just a race with rename */
  			unroll_tree_refs(context, p, count);
  			goto retry;
  		}
  		audit_put_chunk(drop);
  		if (grow_tree_refs(context)) {
  			/* OK, got more space */
  			unroll_tree_refs(context, p, count);
  			goto retry;
  		}
  		/* too bad */
  		printk(KERN_WARNING
436c405c7   Eric Paris   Audit: end printk...
1758
1759
  			"out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1760
1761
1762
1763
1764
1765
1766
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
  #endif
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1767
1768
1769
1770
1771
1772
1773
  /**
   * audit_getname - add a name to the list
   * @name: name to add
   *
   * Add a name to the list of audit names for this context.
   * Called from fs/namei.c:getname().
   */
d8945bb51   Al Viro   [PATCH] inline mo...
1774
  void __audit_getname(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1775
1776
  {
  	struct audit_context *context = current->audit_context;
d8945bb51   Al Viro   [PATCH] inline mo...
1777
  	if (IS_ERR(name) || !name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
  		return;
  
  	if (!context->in_syscall) {
  #if AUDIT_DEBUG == 2
  		printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)
  ",
  		       __FILE__, __LINE__, context->serial, name);
  		dump_stack();
  #endif
  		return;
  	}
  	BUG_ON(context->name_count >= AUDIT_NAMES);
  	context->names[context->name_count].name = name;
9c937dcc7   Amy Griffis   [PATCH] log more ...
1791
1792
  	context->names[context->name_count].name_len = AUDIT_NAME_FULL;
  	context->names[context->name_count].name_put = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
  	context->names[context->name_count].ino  = (unsigned long)-1;
e41e8bde4   Amy Griffis   [PATCH] initializ...
1794
  	context->names[context->name_count].osid = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1795
  	++context->name_count;
f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1796
1797
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1798
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1799
1800
1801
1802
1803
1804
1805
  /* audit_putname - intercept a putname request
   * @name: name to intercept and delay for putname
   *
   * If we have stored the name from getname in the audit context,
   * then we delay the putname until syscall exit.
   * Called from include/linux/fs.h:putname().
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
  void audit_putname(const char *name)
  {
  	struct audit_context *context = current->audit_context;
  
  	BUG_ON(!context);
  	if (!context->in_syscall) {
  #if AUDIT_DEBUG == 2
  		printk(KERN_ERR "%s:%d(:%d): __putname(%p)
  ",
  		       __FILE__, __LINE__, context->serial, name);
  		if (context->name_count) {
  			int i;
  			for (i = 0; i < context->name_count; i++)
  				printk(KERN_ERR "name[%d] = %p = %s
  ", i,
  				       context->names[i].name,
73241ccca   Amy Griffis   [PATCH] Collect m...
1822
  				       context->names[i].name ?: "(null)");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
  		}
  #endif
  		__putname(name);
  	}
  #if AUDIT_DEBUG
  	else {
  		++context->put_count;
  		if (context->put_count > context->name_count) {
  			printk(KERN_ERR "%s:%d(:%d): major=%d"
  			       " in_syscall=%d putname(%p) name_count=%d"
  			       " put_count=%d
  ",
  			       __FILE__, __LINE__,
  			       context->serial, context->major,
  			       context->in_syscall, name, context->name_count,
  			       context->put_count);
  			dump_stack();
  		}
  	}
  #endif
  }
5712e88f2   Amy Griffis   [PATCH] match aud...
1844
1845
1846
1847
1848
  static int audit_inc_name_count(struct audit_context *context,
  				const struct inode *inode)
  {
  	if (context->name_count >= AUDIT_NAMES) {
  		if (inode)
449cedf09   Eric Paris   audit: preface au...
1849
  			printk(KERN_DEBUG "audit: name_count maxed, losing inode data: "
436c405c7   Eric Paris   Audit: end printk...
1850
1851
  			       "dev=%02x:%02x, inode=%lu
  ",
5712e88f2   Amy Griffis   [PATCH] match aud...
1852
1853
1854
1855
1856
  			       MAJOR(inode->i_sb->s_dev),
  			       MINOR(inode->i_sb->s_dev),
  			       inode->i_ino);
  
  		else
436c405c7   Eric Paris   Audit: end printk...
1857
1858
  			printk(KERN_DEBUG "name_count maxed, losing inode data
  ");
5712e88f2   Amy Griffis   [PATCH] match aud...
1859
1860
1861
1862
1863
1864
1865
1866
  		return 1;
  	}
  	context->name_count++;
  #if AUDIT_DEBUG
  	context->ino_count++;
  #endif
  	return 0;
  }
851f7ff56   Eric Paris   This patch will p...
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
  
  static inline int audit_copy_fcaps(struct audit_names *name, const struct dentry *dentry)
  {
  	struct cpu_vfs_cap_data caps;
  	int rc;
  
  	memset(&name->fcap.permitted, 0, sizeof(kernel_cap_t));
  	memset(&name->fcap.inheritable, 0, sizeof(kernel_cap_t));
  	name->fcap.fE = 0;
  	name->fcap_ver = 0;
  
  	if (!dentry)
  		return 0;
  
  	rc = get_vfs_caps_from_disk(dentry, &caps);
  	if (rc)
  		return rc;
  
  	name->fcap.permitted = caps.permitted;
  	name->fcap.inheritable = caps.inheritable;
  	name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
  	name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
  
  	return 0;
  }
3e2efce06   Amy Griffis   [PATCH] fix fault...
1892
  /* Copy inode data into an audit_names. */
851f7ff56   Eric Paris   This patch will p...
1893
1894
  static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
  			     const struct inode *inode)
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
1895
  {
3e2efce06   Amy Griffis   [PATCH] fix fault...
1896
1897
1898
1899
1900
1901
  	name->ino   = inode->i_ino;
  	name->dev   = inode->i_sb->s_dev;
  	name->mode  = inode->i_mode;
  	name->uid   = inode->i_uid;
  	name->gid   = inode->i_gid;
  	name->rdev  = inode->i_rdev;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
1902
  	security_inode_getsecid(inode, &name->osid);
851f7ff56   Eric Paris   This patch will p...
1903
  	audit_copy_fcaps(name, dentry);
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
1904
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1905
1906
1907
  /**
   * audit_inode - store the inode and device from a lookup
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1908
   * @dentry: dentry being audited
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1909
1910
1911
   *
   * Called from fs/namei.c:path_lookup().
   */
5a190ae69   Al Viro   [PATCH] pass dent...
1912
  void __audit_inode(const char *name, const struct dentry *dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913
1914
1915
  {
  	int idx;
  	struct audit_context *context = current->audit_context;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1916
  	const struct inode *inode = dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
  
  	if (!context->in_syscall)
  		return;
  	if (context->name_count
  	    && context->names[context->name_count-1].name
  	    && context->names[context->name_count-1].name == name)
  		idx = context->name_count - 1;
  	else if (context->name_count > 1
  		 && context->names[context->name_count-2].name
  		 && context->names[context->name_count-2].name == name)
  		idx = context->name_count - 2;
  	else {
  		/* FIXME: how much do we care about inodes that have no
  		 * associated name? */
5712e88f2   Amy Griffis   [PATCH] match aud...
1931
  		if (audit_inc_name_count(context, inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1932
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
1933
  		idx = context->name_count - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1934
  		context->names[idx].name = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1935
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1936
  	handle_path(dentry);
851f7ff56   Eric Paris   This patch will p...
1937
  	audit_copy_inode(&context->names[idx], dentry, inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1938
1939
1940
1941
  }
  
  /**
   * audit_inode_child - collect inode info for created/removed objects
481968f44   Randy Dunlap   auditsc: fix kern...
1942
   * @dentry: dentry being audited
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1943
   * @parent: inode of dentry parent
73241ccca   Amy Griffis   [PATCH] Collect m...
1944
1945
1946
1947
1948
1949
1950
1951
1952
   *
   * For syscalls that create or remove filesystem objects, audit_inode
   * can only collect information for the filesystem object's parent.
   * This call updates the audit context with the child's information.
   * Syscalls that create a new filesystem object must be hooked after
   * the object is created.  Syscalls that remove a filesystem object
   * must be hooked prior, in order to capture the target inode during
   * unsuccessful attempts.
   */
cccc6bba3   Al Viro   Lose the first ar...
1953
  void __audit_inode_child(const struct dentry *dentry,
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1954
  			 const struct inode *parent)
73241ccca   Amy Griffis   [PATCH] Collect m...
1955
1956
1957
  {
  	int idx;
  	struct audit_context *context = current->audit_context;
5712e88f2   Amy Griffis   [PATCH] match aud...
1958
  	const char *found_parent = NULL, *found_child = NULL;
5a190ae69   Al Viro   [PATCH] pass dent...
1959
  	const struct inode *inode = dentry->d_inode;
cccc6bba3   Al Viro   Lose the first ar...
1960
  	const char *dname = dentry->d_name.name;
9c937dcc7   Amy Griffis   [PATCH] log more ...
1961
  	int dirlen = 0;
73241ccca   Amy Griffis   [PATCH] Collect m...
1962
1963
1964
  
  	if (!context->in_syscall)
  		return;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1965
1966
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1967

5712e88f2   Amy Griffis   [PATCH] match aud...
1968
1969
1970
  	/* parent is more likely, look for it first */
  	for (idx = 0; idx < context->name_count; idx++) {
  		struct audit_names *n = &context->names[idx];
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1971

5712e88f2   Amy Griffis   [PATCH] match aud...
1972
1973
1974
1975
1976
1977
1978
1979
  		if (!n->name)
  			continue;
  
  		if (n->ino == parent->i_ino &&
  		    !audit_compare_dname_path(dname, n->name, &dirlen)) {
  			n->name_len = dirlen; /* update parent data in place */
  			found_parent = n->name;
  			goto add_names;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1980
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1981
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1982

5712e88f2   Amy Griffis   [PATCH] match aud...
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
  	/* no matching parent, look for matching child */
  	for (idx = 0; idx < context->name_count; idx++) {
  		struct audit_names *n = &context->names[idx];
  
  		if (!n->name)
  			continue;
  
  		/* strcmp() is the more likely scenario */
  		if (!strcmp(dname, n->name) ||
  		     !audit_compare_dname_path(dname, n->name, &dirlen)) {
  			if (inode)
851f7ff56   Eric Paris   This patch will p...
1994
  				audit_copy_inode(n, NULL, inode);
5712e88f2   Amy Griffis   [PATCH] match aud...
1995
1996
1997
1998
1999
  			else
  				n->ino = (unsigned long)-1;
  			found_child = n->name;
  			goto add_names;
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
2000
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
2001
2002
2003
2004
  
  add_names:
  	if (!found_parent) {
  		if (audit_inc_name_count(context, parent))
ac9910ce0   Steve Grubb   [PATCH] name_coun...
2005
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
2006
2007
  		idx = context->name_count - 1;
  		context->names[idx].name = NULL;
851f7ff56   Eric Paris   This patch will p...
2008
  		audit_copy_inode(&context->names[idx], NULL, parent);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
2009
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
  
  	if (!found_child) {
  		if (audit_inc_name_count(context, inode))
  			return;
  		idx = context->name_count - 1;
  
  		/* Re-use the name belonging to the slot for a matching parent
  		 * directory. All names for this context are relinquished in
  		 * audit_free_names() */
  		if (found_parent) {
  			context->names[idx].name = found_parent;
  			context->names[idx].name_len = AUDIT_NAME_FULL;
  			/* don't call __putname() */
  			context->names[idx].name_put = 0;
  		} else {
  			context->names[idx].name = NULL;
  		}
  
  		if (inode)
851f7ff56   Eric Paris   This patch will p...
2029
  			audit_copy_inode(&context->names[idx], NULL, inode);
5712e88f2   Amy Griffis   [PATCH] match aud...
2030
2031
2032
  		else
  			context->names[idx].ino = (unsigned long)-1;
  	}
3e2efce06   Amy Griffis   [PATCH] fix fault...
2033
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
2034
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
2035
2036
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2037
2038
2039
2040
2041
2042
2043
   * auditsc_get_stamp - get local copies of audit_context values
   * @ctx: audit_context for the task
   * @t: timespec to store time recorded in the audit_context
   * @serial: serial value that is recorded in the audit_context
   *
   * Also sets the context as auditable.
   */
48887e63d   Al Viro   [PATCH] fix broke...
2044
  int auditsc_get_stamp(struct audit_context *ctx,
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
2045
  		       struct timespec *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2046
  {
48887e63d   Al Viro   [PATCH] fix broke...
2047
2048
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
2049
2050
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
2051
2052
2053
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
2054
2055
2056
2057
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
2058
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2059
  }
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2060
2061
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2062
2063
2064
2065
2066
2067
2068
2069
2070
  /**
   * audit_set_loginuid - set a task's audit_context loginuid
   * @task: task whose audit context is being modified
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
456be6cd9   Steve Grubb   [AUDIT] LOGIN mes...
2071
  int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2072
  {
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2073
  	unsigned int sessionid = atomic_inc_return(&session_id);
41757106b   Steve Grubb   [PATCH] make set_...
2074
  	struct audit_context *context = task->audit_context;
bfef93a5d   Al Viro   [PATCH] get rid o...
2075
2076
2077
2078
2079
2080
  	if (context && context->in_syscall) {
  		struct audit_buffer *ab;
  
  		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
  		if (ab) {
  			audit_log_format(ab, "login pid=%d uid=%u "
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2081
2082
  				"old auid=%u new auid=%u"
  				" old ses=%u new ses=%u",
c69e8d9c0   David Howells   CRED: Use RCU to ...
2083
  				task->pid, task_uid(task),
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2084
2085
  				task->loginuid, loginuid,
  				task->sessionid, sessionid);
bfef93a5d   Al Viro   [PATCH] get rid o...
2086
  			audit_log_end(ab);
c04049939   Steve Grubb   AUDIT: Add messag...
2087
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2088
  	}
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2089
  	task->sessionid = sessionid;
bfef93a5d   Al Viro   [PATCH] get rid o...
2090
  	task->loginuid = loginuid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2091
2092
  	return 0;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2093
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2094
2095
2096
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
2097
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2098
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2099
   */
df0a42837   Al Viro   switch mq_open() ...
2100
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2101
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2102
  	struct audit_context *context = current->audit_context;
564f6993f   Al Viro   sanitize audit_mq...
2103
2104
2105
2106
  	if (attr)
  		memcpy(&context->mq_open.attr, attr, sizeof(struct mq_attr));
  	else
  		memset(&context->mq_open.attr, 0, sizeof(struct mq_attr));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2107

564f6993f   Al Viro   sanitize audit_mq...
2108
2109
  	context->mq_open.oflag = oflag;
  	context->mq_open.mode = mode;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2110

564f6993f   Al Viro   sanitize audit_mq...
2111
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2112
2113
2114
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2115
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2116
2117
2118
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2119
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2120
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2121
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2122
2123
  void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
  			const struct timespec *abs_timeout)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2124
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2125
  	struct audit_context *context = current->audit_context;
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2126
  	struct timespec *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2127

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2128
2129
2130
2131
  	if (abs_timeout)
  		memcpy(p, abs_timeout, sizeof(struct timespec));
  	else
  		memset(p, 0, sizeof(struct timespec));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2132

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2133
2134
2135
  	context->mq_sendrecv.mqdes = mqdes;
  	context->mq_sendrecv.msg_len = msg_len;
  	context->mq_sendrecv.msg_prio = msg_prio;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2136

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2137
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2138
2139
2140
2141
2142
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
2143
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2144
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2145
   */
20114f71b   Al Viro   sanitize audit_mq...
2146
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2147
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2148
  	struct audit_context *context = current->audit_context;
20114f71b   Al Viro   sanitize audit_mq...
2149
2150
2151
2152
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2153

20114f71b   Al Viro   sanitize audit_mq...
2154
2155
  	context->mq_notify.mqdes = mqdes;
  	context->type = AUDIT_MQ_NOTIFY;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2156
2157
2158
2159
2160
2161
2162
  }
  
  /**
   * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
   * @mqdes: MQ descriptor
   * @mqstat: MQ flags
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2163
   */
7392906ea   Al Viro   sanitize audit_mq...
2164
  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2165
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2166
  	struct audit_context *context = current->audit_context;
7392906ea   Al Viro   sanitize audit_mq...
2167
2168
2169
  	context->mq_getsetattr.mqdes = mqdes;
  	context->mq_getsetattr.mqstat = *mqstat;
  	context->type = AUDIT_MQ_GETSETATTR;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2170
2171
2172
  }
  
  /**
073115d6b   Steve Grubb   [PATCH] Rework of...
2173
2174
2175
   * audit_ipc_obj - record audit data for ipc object
   * @ipcp: ipc permissions
   *
073115d6b   Steve Grubb   [PATCH] Rework of...
2176
   */
a33e67510   Al Viro   sanitize audit_ip...
2177
  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
073115d6b   Steve Grubb   [PATCH] Rework of...
2178
  {
073115d6b   Steve Grubb   [PATCH] Rework of...
2179
  	struct audit_context *context = current->audit_context;
a33e67510   Al Viro   sanitize audit_ip...
2180
2181
2182
  	context->ipc.uid = ipcp->uid;
  	context->ipc.gid = ipcp->gid;
  	context->ipc.mode = ipcp->mode;
e816f370c   Al Viro   sanitize audit_ip...
2183
  	context->ipc.has_perm = 0;
a33e67510   Al Viro   sanitize audit_ip...
2184
2185
  	security_ipc_getsecid(ipcp, &context->ipc.osid);
  	context->type = AUDIT_IPC;
073115d6b   Steve Grubb   [PATCH] Rework of...
2186
2187
2188
2189
  }
  
  /**
   * audit_ipc_set_perm - record audit data for new ipc permissions
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2190
2191
2192
2193
2194
   * @qbytes: msgq bytes
   * @uid: msgq user id
   * @gid: msgq group id
   * @mode: msgq mode (permissions)
   *
e816f370c   Al Viro   sanitize audit_ip...
2195
   * Called only after audit_ipc_obj().
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2196
   */
2570ebbd1   Al Viro   switch kern_ipc_p...
2197
  void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2198
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2199
  	struct audit_context *context = current->audit_context;
e816f370c   Al Viro   sanitize audit_ip...
2200
2201
2202
2203
2204
  	context->ipc.qbytes = qbytes;
  	context->ipc.perm_uid = uid;
  	context->ipc.perm_gid = gid;
  	context->ipc.perm_mode = mode;
  	context->ipc.has_perm = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2205
  }
c2f0c7c35   Steve Grubb   The attached patc...
2206

473ae30bc   Al Viro   [PATCH] execve ar...
2207
2208
2209
2210
  int audit_bprm(struct linux_binprm *bprm)
  {
  	struct audit_aux_data_execve *ax;
  	struct audit_context *context = current->audit_context;
473ae30bc   Al Viro   [PATCH] execve ar...
2211

5ac3a9c26   Al Viro   [PATCH] don't bot...
2212
  	if (likely(!audit_enabled || !context || context->dummy))
473ae30bc   Al Viro   [PATCH] execve ar...
2213
  		return 0;
bdf4c48af   Peter Zijlstra   audit: rework exe...
2214
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
473ae30bc   Al Viro   [PATCH] execve ar...
2215
2216
2217
2218
2219
  	if (!ax)
  		return -ENOMEM;
  
  	ax->argc = bprm->argc;
  	ax->envc = bprm->envc;
bdf4c48af   Peter Zijlstra   audit: rework exe...
2220
  	ax->mm = bprm->mm;
473ae30bc   Al Viro   [PATCH] execve ar...
2221
2222
2223
2224
2225
  	ax->d.type = AUDIT_EXECVE;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
  	return 0;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2226
2227
2228
2229
2230
  /**
   * audit_socketcall - record audit data for sys_socketcall
   * @nargs: number of args
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2231
   */
f3298dc4f   Al Viro   sanitize audit_so...
2232
  void audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2233
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2234
  	struct audit_context *context = current->audit_context;
5ac3a9c26   Al Viro   [PATCH] don't bot...
2235
  	if (likely(!context || context->dummy))
f3298dc4f   Al Viro   sanitize audit_so...
2236
  		return;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2237

f3298dc4f   Al Viro   sanitize audit_so...
2238
2239
2240
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2241
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2242
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2243
2244
2245
2246
   * __audit_fd_pair - record audit data for pipe and socketpair
   * @fd1: the first file descriptor
   * @fd2: the second file descriptor
   *
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2247
   */
157cf649a   Al Viro   sanitize audit_fd...
2248
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2249
2250
  {
  	struct audit_context *context = current->audit_context;
157cf649a   Al Viro   sanitize audit_fd...
2251
2252
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2253
2254
2255
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2256
2257
2258
2259
2260
2261
   * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
   * @len: data length in user space
   * @a: data address in kernel space
   *
   * Returns 0 for success or NULL context or < 0 on error.
   */
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2262
2263
  int audit_sockaddr(int len, void *a)
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2264
  	struct audit_context *context = current->audit_context;
5ac3a9c26   Al Viro   [PATCH] don't bot...
2265
  	if (likely(!context || context->dummy))
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2266
  		return 0;
4f6b434fe   Al Viro   don't reallocate ...
2267
2268
2269
2270
2271
2272
  	if (!context->sockaddr) {
  		void *p = kmalloc(sizeof(struct sockaddr_storage), GFP_KERNEL);
  		if (!p)
  			return -ENOMEM;
  		context->sockaddr = p;
  	}
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2273

4f6b434fe   Al Viro   don't reallocate ...
2274
2275
  	context->sockaddr_len = len;
  	memcpy(context->sockaddr, a, len);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2276
2277
  	return 0;
  }
a5cb013da   Al Viro   [PATCH] auditing ...
2278
2279
2280
2281
2282
  void __audit_ptrace(struct task_struct *t)
  {
  	struct audit_context *context = current->audit_context;
  
  	context->target_pid = t->pid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
2283
  	context->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2284
  	context->target_uid = task_uid(t);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2285
  	context->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2286
  	security_task_getsecid(t, &context->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2287
  	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
a5cb013da   Al Viro   [PATCH] auditing ...
2288
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2289
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2290
2291
2292
2293
2294
2295
2296
   * audit_signal_info - record signal info for shutting down audit subsystem
   * @sig: signal value
   * @t: task being signaled
   *
   * If the audit subsystem is being terminated, record the task (pid)
   * and uid that is doing that.
   */
e54dc2431   Amy Griffis   [PATCH] audit sig...
2297
  int __audit_signal_info(int sig, struct task_struct *t)
c2f0c7c35   Steve Grubb   The attached patc...
2298
  {
e54dc2431   Amy Griffis   [PATCH] audit sig...
2299
2300
2301
  	struct audit_aux_data_pids *axp;
  	struct task_struct *tsk = current;
  	struct audit_context *ctx = tsk->audit_context;
c69e8d9c0   David Howells   CRED: Use RCU to ...
2302
  	uid_t uid = current_uid(), t_uid = task_uid(t);
e1396065e   Al Viro   [PATCH] collect s...
2303

175fc4842   Al Viro   fix oops in __aud...
2304
  	if (audit_pid && t->tgid == audit_pid) {
ee1d31566   Eric Paris   [PATCH] Audit: Co...
2305
  		if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
175fc4842   Al Viro   fix oops in __aud...
2306
  			audit_sig_pid = tsk->pid;
bfef93a5d   Al Viro   [PATCH] get rid o...
2307
2308
  			if (tsk->loginuid != -1)
  				audit_sig_uid = tsk->loginuid;
175fc4842   Al Viro   fix oops in __aud...
2309
  			else
c69e8d9c0   David Howells   CRED: Use RCU to ...
2310
  				audit_sig_uid = uid;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2311
  			security_task_getsecid(tsk, &audit_sig_sid);
175fc4842   Al Viro   fix oops in __aud...
2312
2313
2314
  		}
  		if (!audit_signals || audit_dummy_context())
  			return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2315
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
2316

e54dc2431   Amy Griffis   [PATCH] audit sig...
2317
2318
2319
2320
  	/* optimize the common case by putting first signal recipient directly
  	 * in audit_context */
  	if (!ctx->target_pid) {
  		ctx->target_pid = t->tgid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
2321
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2322
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2323
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2324
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2325
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
  		return 0;
  	}
  
  	axp = (void *)ctx->aux_pids;
  	if (!axp || axp->pid_count == AUDIT_AUX_PIDS) {
  		axp = kzalloc(sizeof(*axp), GFP_ATOMIC);
  		if (!axp)
  			return -ENOMEM;
  
  		axp->d.type = AUDIT_OBJ_PID;
  		axp->d.next = ctx->aux_pids;
  		ctx->aux_pids = (void *)axp;
  	}
88ae704c2   Adrian Bunk   kernel/auditsc.c:...
2339
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2340
2341
  
  	axp->target_pid[axp->pid_count] = t->tgid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
2342
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2343
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2344
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2345
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2346
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2347
2348
2349
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2350
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2351
2352
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2353
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2354
2355
2356
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2357
2358
2359
2360
   *
   * Simply check if the proc already has the caps given by the file and if not
   * store the priv escalation info for later auditing at the end of the syscall
   *
3fc689e96   Eric Paris   Any time fcaps or...
2361
2362
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2363
2364
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2365
2366
2367
2368
2369
2370
2371
2372
  {
  	struct audit_aux_data_bprm_fcaps *ax;
  	struct audit_context *context = current->audit_context;
  	struct cpu_vfs_cap_data vcaps;
  	struct dentry *dentry;
  
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
  	if (!ax)
d84f4f992   David Howells   CRED: Inaugurate ...
2373
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
  
  	ax->d.type = AUDIT_BPRM_FCAPS;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
  
  	dentry = dget(bprm->file->f_dentry);
  	get_vfs_caps_from_disk(dentry, &vcaps);
  	dput(dentry);
  
  	ax->fcap.permitted = vcaps.permitted;
  	ax->fcap.inheritable = vcaps.inheritable;
  	ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
  	ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
d84f4f992   David Howells   CRED: Inaugurate ...
2387
2388
2389
  	ax->old_pcap.permitted   = old->cap_permitted;
  	ax->old_pcap.inheritable = old->cap_inheritable;
  	ax->old_pcap.effective   = old->cap_effective;
3fc689e96   Eric Paris   Any time fcaps or...
2390

d84f4f992   David Howells   CRED: Inaugurate ...
2391
2392
2393
2394
  	ax->new_pcap.permitted   = new->cap_permitted;
  	ax->new_pcap.inheritable = new->cap_inheritable;
  	ax->new_pcap.effective   = new->cap_effective;
  	return 0;
3fc689e96   Eric Paris   Any time fcaps or...
2395
2396
2397
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2398
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2399
2400
2401
   * @pid: target pid of the capset call
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2402
2403
2404
2405
   *
   * Record the aguments userspace sent to sys_capset for later printing by the
   * audit system if applicable
   */
57f71a0af   Al Viro   sanitize audit_lo...
2406
  void __audit_log_capset(pid_t pid,
d84f4f992   David Howells   CRED: Inaugurate ...
2407
  		       const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2408
  {
e68b75a02   Eric Paris   When the capset s...
2409
  	struct audit_context *context = current->audit_context;
57f71a0af   Al Viro   sanitize audit_lo...
2410
2411
2412
2413
2414
  	context->capset.pid = pid;
  	context->capset.cap.effective   = new->cap_effective;
  	context->capset.cap.inheritable = new->cap_effective;
  	context->capset.cap.permitted   = new->cap_permitted;
  	context->type = AUDIT_CAPSET;
e68b75a02   Eric Paris   When the capset s...
2415
  }
120a795da   Al Viro   audit mmap
2416
2417
2418
2419
2420
2421
2422
  void __audit_mmap_fd(int fd, int flags)
  {
  	struct audit_context *context = current->audit_context;
  	context->mmap.fd = fd;
  	context->mmap.flags = flags;
  	context->type = AUDIT_MMAP;
  }
e68b75a02   Eric Paris   When the capset s...
2423
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2424
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2425
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2426
2427
2428
2429
2430
2431
2432
2433
   *
   * If a process ends with a core dump, something fishy is going on and we
   * should record the event for investigation.
   */
  void audit_core_dumps(long signr)
  {
  	struct audit_buffer *ab;
  	u32 sid;
76aac0e9a   David Howells   CRED: Wrap task c...
2434
2435
  	uid_t auid = audit_get_loginuid(current), uid;
  	gid_t gid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2436
  	unsigned int sessionid = audit_get_sessionid(current);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2437
2438
2439
2440
2441
2442
2443
2444
  
  	if (!audit_enabled)
  		return;
  
  	if (signr == SIGQUIT)	/* don't care for those */
  		return;
  
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
76aac0e9a   David Howells   CRED: Wrap task c...
2445
  	current_uid_gid(&uid, &gid);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2446
  	audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
76aac0e9a   David Howells   CRED: Wrap task c...
2447
  			 auid, uid, gid, sessionid);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2448
  	security_task_getsecid(current, &sid);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2449
2450
2451
  	if (sid) {
  		char *ctx = NULL;
  		u32 len;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2452
  		if (security_secid_to_secctx(sid, &ctx, &len))
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2453
  			audit_log_format(ab, " ssid=%u", sid);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2454
  		else {
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2455
  			audit_log_format(ab, " subj=%s", ctx);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2456
2457
  			security_release_secctx(ctx, len);
  		}
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2458
2459
2460
2461
2462
2463
  	}
  	audit_log_format(ab, " pid=%d comm=", current->pid);
  	audit_log_untrustedstring(ab, current->comm);
  	audit_log_format(ab, " sig=%ld", signr);
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2464
2465
2466
2467
2468
2469
2470
2471
  
  struct list_head *audit_killed_trees(void)
  {
  	struct audit_context *ctx = current->audit_context;
  	if (likely(!ctx || !ctx->in_syscall))
  		return NULL;
  	return &ctx->killed_trees;
  }