Blame view

kernel/auditsc.c 63.7 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>
3dc1c1b2d   Kees Cook   seccomp: remove d...
70
  #include <linux/compat.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

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

d7e7528bc   Eric Paris   Audit: push audit...
74
75
76
77
  /* flags stating the success for a syscall */
  #define AUDITSC_INVALID 0
  #define AUDITSC_SUCCESS 1
  #define AUDITSC_FAILURE 2
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;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
89
  struct audit_aux_data {
  	struct audit_aux_data	*next;
  	int			type;
  };
  
  #define AUDIT_AUX_IPCPERM	0
e54dc2431   Amy Griffis   [PATCH] audit sig...
90
91
  /* Number of target pids per aux struct. */
  #define AUDIT_AUX_PIDS	16
473ae30bc   Al Viro   [PATCH] execve ar...
92
93
94
95
  struct audit_aux_data_execve {
  	struct audit_aux_data	d;
  	int argc;
  	int envc;
bdf4c48af   Peter Zijlstra   audit: rework exe...
96
  	struct mm_struct *mm;
473ae30bc   Al Viro   [PATCH] execve ar...
97
  };
e54dc2431   Amy Griffis   [PATCH] audit sig...
98
99
100
  struct audit_aux_data_pids {
  	struct audit_aux_data	d;
  	pid_t			target_pid[AUDIT_AUX_PIDS];
e1760bd5f   Eric W. Biederman   userns: Convert t...
101
  	kuid_t			target_auid[AUDIT_AUX_PIDS];
cca080d9b   Eric W. Biederman   userns: Convert a...
102
  	kuid_t			target_uid[AUDIT_AUX_PIDS];
4746ec5b0   Eric Paris   [AUDIT] add sessi...
103
  	unsigned int		target_sessionid[AUDIT_AUX_PIDS];
e54dc2431   Amy Griffis   [PATCH] audit sig...
104
  	u32			target_sid[AUDIT_AUX_PIDS];
c2a7780ef   Eric Paris   [AUDIT] collect u...
105
  	char 			target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
e54dc2431   Amy Griffis   [PATCH] audit sig...
106
107
  	int			pid_count;
  };
3fc689e96   Eric Paris   Any time fcaps or...
108
109
110
111
112
113
114
  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...
115
116
117
118
119
  struct audit_aux_data_capset {
  	struct audit_aux_data	d;
  	pid_t			pid;
  	struct audit_cap_data	cap;
  };
74c3cbe33   Al Viro   [PATCH] audit: wa...
120
121
122
123
  struct audit_tree_refs {
  	struct audit_tree_refs *next;
  	struct audit_chunk *c[31];
  };
55669bfa1   Al Viro   [PATCH] audit: AU...
124
125
126
127
128
129
130
131
132
133
  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...
134
  	unsigned n;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
135
136
  	if (unlikely(!ctx))
  		return 0;
c4bacefb7   Cordelia   [PATCH] audit: Mo...
137
  	n = ctx->major;
dbda4c0b9   Alan Cox   tty: Fix abusers ...
138

55669bfa1   Al Viro   [PATCH] audit: AU...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  	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;
  	}
  }
5ef30ee53   Eric Paris   audit: make filet...
174
  static int audit_match_filetype(struct audit_context *ctx, int val)
8b67dca94   Al Viro   [PATCH] new predi...
175
  {
5195d8e21   Eric Paris   audit: dynamicall...
176
  	struct audit_names *n;
5ef30ee53   Eric Paris   audit: make filet...
177
  	umode_t mode = (umode_t)val;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
178
179
180
  
  	if (unlikely(!ctx))
  		return 0;
5195d8e21   Eric Paris   audit: dynamicall...
181
182
183
  	list_for_each_entry(n, &ctx->names_list, list) {
  		if ((n->ino != -1) &&
  		    ((n->mode & S_IFMT) == mode))
5ef30ee53   Eric Paris   audit: make filet...
184
185
  			return 1;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
186

5ef30ee53   Eric Paris   audit: make filet...
187
  	return 0;
8b67dca94   Al Viro   [PATCH] new predi...
188
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
189
190
191
192
193
194
195
196
197
198
199
  /*
   * 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_...
200
201
202
203
204
205
206
  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...
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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
293
294
295
296
297
298
299
300
301
302
303
304
305
  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;
  }
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
306
307
308
309
  static int audit_compare_uid(kuid_t uid,
  			     struct audit_names *name,
  			     struct audit_field *f,
  			     struct audit_context *ctx)
b34b03932   Eric Paris   audit: complex in...
310
311
  {
  	struct audit_names *n;
b34b03932   Eric Paris   audit: complex in...
312
  	int rc;
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
313
   
b34b03932   Eric Paris   audit: complex in...
314
  	if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
315
  		rc = audit_uid_comparator(uid, f->op, name->uid);
b34b03932   Eric Paris   audit: complex in...
316
317
318
  		if (rc)
  			return rc;
  	}
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
319
   
b34b03932   Eric Paris   audit: complex in...
320
321
  	if (ctx) {
  		list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
322
323
324
325
326
327
328
  			rc = audit_uid_comparator(uid, f->op, n->uid);
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
b34b03932   Eric Paris   audit: complex in...
329

ca57ec0f0   Eric W. Biederman   audit: Add typesp...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  static int audit_compare_gid(kgid_t gid,
  			     struct audit_names *name,
  			     struct audit_field *f,
  			     struct audit_context *ctx)
  {
  	struct audit_names *n;
  	int rc;
   
  	if (name) {
  		rc = audit_gid_comparator(gid, f->op, name->gid);
  		if (rc)
  			return rc;
  	}
   
  	if (ctx) {
  		list_for_each_entry(n, &ctx->names_list, list) {
  			rc = audit_gid_comparator(gid, f->op, n->gid);
b34b03932   Eric Paris   audit: complex in...
347
348
349
350
351
352
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
02d86a568   Eric Paris   audit: allow inte...
353
354
355
356
357
358
  static int audit_field_compare(struct task_struct *tsk,
  			       const struct cred *cred,
  			       struct audit_field *f,
  			       struct audit_context *ctx,
  			       struct audit_names *name)
  {
02d86a568   Eric Paris   audit: allow inte...
359
  	switch (f->val) {
4a6633ed0   Peter Moody   audit: implement ...
360
  	/* process to file object comparisons */
02d86a568   Eric Paris   audit: allow inte...
361
  	case AUDIT_COMPARE_UID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
362
  		return audit_compare_uid(cred->uid, name, f, ctx);
c9fe685f7   Eric Paris   audit: allow inte...
363
  	case AUDIT_COMPARE_GID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
364
  		return audit_compare_gid(cred->gid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
365
  	case AUDIT_COMPARE_EUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
366
  		return audit_compare_uid(cred->euid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
367
  	case AUDIT_COMPARE_EGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
368
  		return audit_compare_gid(cred->egid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
369
  	case AUDIT_COMPARE_AUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
370
  		return audit_compare_uid(tsk->loginuid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
371
  	case AUDIT_COMPARE_SUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
372
  		return audit_compare_uid(cred->suid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
373
  	case AUDIT_COMPARE_SGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
374
  		return audit_compare_gid(cred->sgid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
375
  	case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
376
  		return audit_compare_uid(cred->fsuid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
377
  	case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
378
  		return audit_compare_gid(cred->fsgid, name, f, ctx);
10d683608   Peter Moody   audit: comparison...
379
380
  	/* uid comparisons */
  	case AUDIT_COMPARE_UID_TO_AUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
381
  		return audit_uid_comparator(cred->uid, f->op, tsk->loginuid);
10d683608   Peter Moody   audit: comparison...
382
  	case AUDIT_COMPARE_UID_TO_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
383
  		return audit_uid_comparator(cred->uid, f->op, cred->euid);
10d683608   Peter Moody   audit: comparison...
384
  	case AUDIT_COMPARE_UID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
385
  		return audit_uid_comparator(cred->uid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
386
  	case AUDIT_COMPARE_UID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
387
  		return audit_uid_comparator(cred->uid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
388
389
  	/* auid comparisons */
  	case AUDIT_COMPARE_AUID_TO_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
390
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->euid);
10d683608   Peter Moody   audit: comparison...
391
  	case AUDIT_COMPARE_AUID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
392
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
393
  	case AUDIT_COMPARE_AUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
394
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
395
396
  	/* euid comparisons */
  	case AUDIT_COMPARE_EUID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
397
  		return audit_uid_comparator(cred->euid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
398
  	case AUDIT_COMPARE_EUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
399
  		return audit_uid_comparator(cred->euid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
400
401
  	/* suid comparisons */
  	case AUDIT_COMPARE_SUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
402
  		return audit_uid_comparator(cred->suid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
403
404
  	/* gid comparisons */
  	case AUDIT_COMPARE_GID_TO_EGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
405
  		return audit_gid_comparator(cred->gid, f->op, cred->egid);
10d683608   Peter Moody   audit: comparison...
406
  	case AUDIT_COMPARE_GID_TO_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
407
  		return audit_gid_comparator(cred->gid, f->op, cred->sgid);
10d683608   Peter Moody   audit: comparison...
408
  	case AUDIT_COMPARE_GID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
409
  		return audit_gid_comparator(cred->gid, f->op, cred->fsgid);
10d683608   Peter Moody   audit: comparison...
410
411
  	/* egid comparisons */
  	case AUDIT_COMPARE_EGID_TO_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
412
  		return audit_gid_comparator(cred->egid, f->op, cred->sgid);
10d683608   Peter Moody   audit: comparison...
413
  	case AUDIT_COMPARE_EGID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
414
  		return audit_gid_comparator(cred->egid, f->op, cred->fsgid);
10d683608   Peter Moody   audit: comparison...
415
416
  	/* sgid comparison */
  	case AUDIT_COMPARE_SGID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
417
  		return audit_gid_comparator(cred->sgid, f->op, cred->fsgid);
02d86a568   Eric Paris   audit: allow inte...
418
419
420
421
422
423
424
  	default:
  		WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug
  ");
  		return 0;
  	}
  	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;
5195d8e21   Eric Paris   audit: dynamicall...
441
  	int i, 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];
5195d8e21   Eric Paris   audit: dynamicall...
446
  		struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  		int result = 0;
93315ed6d   Amy Griffis   [PATCH] audit str...
448
  		switch (f->type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  		case AUDIT_PID:
93315ed6d   Amy Griffis   [PATCH] audit str...
450
  			result = audit_comparator(tsk->pid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
  			break;
3c66251e5   Al Viro   [PATCH] add filte...
452
  		case AUDIT_PPID:
419c58f11   Alexander Viro   [PATCH] PPID filt...
453
454
455
  			if (ctx) {
  				if (!ctx->ppid)
  					ctx->ppid = sys_getppid();
3c66251e5   Al Viro   [PATCH] add filte...
456
  				result = audit_comparator(ctx->ppid, f->op, f->val);
419c58f11   Alexander Viro   [PATCH] PPID filt...
457
  			}
3c66251e5   Al Viro   [PATCH] add filte...
458
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  		case AUDIT_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
460
  			result = audit_uid_comparator(cred->uid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
  			break;
  		case AUDIT_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
463
  			result = audit_uid_comparator(cred->euid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
  			break;
  		case AUDIT_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
466
  			result = audit_uid_comparator(cred->suid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
  			break;
  		case AUDIT_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
469
  			result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
  			break;
  		case AUDIT_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
472
  			result = audit_gid_comparator(cred->gid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
473
474
475
476
477
478
479
  			if (f->op == Audit_equal) {
  				if (!result)
  					result = in_group_p(f->gid);
  			} else if (f->op == Audit_not_equal) {
  				if (result)
  					result = !in_group_p(f->gid);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
  			break;
  		case AUDIT_EGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
482
  			result = audit_gid_comparator(cred->egid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
483
484
485
486
487
488
489
  			if (f->op == Audit_equal) {
  				if (!result)
  					result = in_egroup_p(f->gid);
  			} else if (f->op == Audit_not_equal) {
  				if (result)
  					result = !in_egroup_p(f->gid);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
  			break;
  		case AUDIT_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
492
  			result = audit_gid_comparator(cred->sgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
  			break;
  		case AUDIT_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
495
  			result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
497
  			break;
  		case AUDIT_PERS:
93315ed6d   Amy Griffis   [PATCH] audit str...
498
  			result = audit_comparator(tsk->personality, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  			break;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
500
  		case AUDIT_ARCH:
9f8dbe9c9   Daniel Walker   whitespace fixes:...
501
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
502
  				result = audit_comparator(ctx->arch, f->op, f->val);
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
503
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
506
  
  		case AUDIT_EXIT:
  			if (ctx && ctx->return_valid)
93315ed6d   Amy Griffis   [PATCH] audit str...
507
  				result = audit_comparator(ctx->return_code, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
509
  			break;
  		case AUDIT_SUCCESS:
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
510
  			if (ctx && ctx->return_valid) {
93315ed6d   Amy Griffis   [PATCH] audit str...
511
512
  				if (f->val)
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
513
  				else
93315ed6d   Amy Griffis   [PATCH] audit str...
514
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
515
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
  			break;
  		case AUDIT_DEVMAJOR:
16c174bd9   Eric Paris   audit: check curr...
518
519
520
521
522
  			if (name) {
  				if (audit_comparator(MAJOR(name->dev), f->op, f->val) ||
  				    audit_comparator(MAJOR(name->rdev), f->op, f->val))
  					++result;
  			} else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
523
  				list_for_each_entry(n, &ctx->names_list, list) {
16c174bd9   Eric Paris   audit: check curr...
524
525
  					if (audit_comparator(MAJOR(n->dev), f->op, f->val) ||
  					    audit_comparator(MAJOR(n->rdev), f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
531
532
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_DEVMINOR:
16c174bd9   Eric Paris   audit: check curr...
533
534
535
536
537
  			if (name) {
  				if (audit_comparator(MINOR(name->dev), f->op, f->val) ||
  				    audit_comparator(MINOR(name->rdev), f->op, f->val))
  					++result;
  			} else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
538
  				list_for_each_entry(n, &ctx->names_list, list) {
16c174bd9   Eric Paris   audit: check curr...
539
540
  					if (audit_comparator(MINOR(n->dev), f->op, f->val) ||
  					    audit_comparator(MINOR(n->rdev), f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
542
543
544
545
546
547
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_INODE:
f368c07d7   Amy Griffis   [PATCH] audit: pa...
548
  			if (name)
9c937dcc7   Amy Griffis   [PATCH] log more ...
549
  				result = (name->ino == f->val);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
550
  			else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
551
552
  				list_for_each_entry(n, &ctx->names_list, list) {
  					if (audit_comparator(n->ino, f->op, f->val)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
555
556
557
558
  						++result;
  						break;
  					}
  				}
  			}
  			break;
efaffd6e4   Eric Paris   audit: allow matc...
559
560
  		case AUDIT_OBJ_UID:
  			if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
561
  				result = audit_uid_comparator(name->uid, f->op, f->uid);
efaffd6e4   Eric Paris   audit: allow matc...
562
563
  			} else if (ctx) {
  				list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
564
  					if (audit_uid_comparator(n->uid, f->op, f->uid)) {
efaffd6e4   Eric Paris   audit: allow matc...
565
566
567
568
569
570
  						++result;
  						break;
  					}
  				}
  			}
  			break;
54d3218b3   Eric Paris   audit: allow audi...
571
572
  		case AUDIT_OBJ_GID:
  			if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
573
  				result = audit_gid_comparator(name->gid, f->op, f->gid);
54d3218b3   Eric Paris   audit: allow audi...
574
575
  			} else if (ctx) {
  				list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
576
  					if (audit_gid_comparator(n->gid, f->op, f->gid)) {
54d3218b3   Eric Paris   audit: allow audi...
577
578
579
580
581
582
  						++result;
  						break;
  					}
  				}
  			}
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
583
  		case AUDIT_WATCH:
ae7b8f410   Eric Paris   Audit: clean up t...
584
585
  			if (name)
  				result = audit_watch_compare(rule->watch, name->ino, name->dev);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
586
  			break;
74c3cbe33   Al Viro   [PATCH] audit: wa...
587
588
589
590
  		case AUDIT_DIR:
  			if (ctx)
  				result = match_tree_refs(ctx, rule->tree);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
  		case AUDIT_LOGINUID:
  			result = 0;
  			if (ctx)
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
594
  				result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  			break;
780a7654c   Eric W. Biederman   audit: Make testi...
596
597
598
  		case AUDIT_LOGINUID_SET:
  			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
  			break;
3a6b9f85c   Darrel Goeddel   [PATCH] audit: re...
599
600
601
602
603
  		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...
604
605
606
607
608
  			/* 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...
609
  			if (f->lsm_rule) {
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
610
  				if (need_sid) {
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
611
  					security_task_getsecid(tsk, &sid);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
612
613
  					need_sid = 0;
  				}
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
614
  				result = security_audit_rule_match(sid, f->type,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
615
  				                                  f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
616
  				                                  f->lsm_rule,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
617
  				                                  ctx);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
618
  			}
3dc7e3153   Darrel Goeddel   [PATCH] support f...
619
  			break;
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
620
621
622
623
624
625
626
  		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...
627
  			if (f->lsm_rule) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
628
629
  				/* Find files that match */
  				if (name) {
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
630
  					result = security_audit_rule_match(
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
631
  					           name->osid, f->type, f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
632
  					           f->lsm_rule, ctx);
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
633
  				} else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
634
635
636
637
  					list_for_each_entry(n, &ctx->names_list, list) {
  						if (security_audit_rule_match(n->osid, f->type,
  									      f->op, f->lsm_rule,
  									      ctx)) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
638
639
640
641
642
643
  							++result;
  							break;
  						}
  					}
  				}
  				/* Find ipc objects that match */
a33e67510   Al Viro   sanitize audit_ip...
644
645
646
647
648
649
  				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...
650
651
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
654
655
656
  		case AUDIT_ARG0:
  		case AUDIT_ARG1:
  		case AUDIT_ARG2:
  		case AUDIT_ARG3:
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
657
  				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
  			break;
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
659
660
661
662
  		case AUDIT_FILTERKEY:
  			/* ignore this field for filtering */
  			result = 1;
  			break;
55669bfa1   Al Viro   [PATCH] audit: AU...
663
664
665
  		case AUDIT_PERM:
  			result = audit_match_perm(ctx, f->val);
  			break;
8b67dca94   Al Viro   [PATCH] new predi...
666
667
668
  		case AUDIT_FILETYPE:
  			result = audit_match_filetype(ctx, f->val);
  			break;
02d86a568   Eric Paris   audit: allow inte...
669
670
671
  		case AUDIT_FIELD_COMPARE:
  			result = audit_field_compare(tsk, cred, f, ctx, name);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
  		}
f56298835   Tony Jones   audit: acquire cr...
673
  		if (!result)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
  			return 0;
  	}
0590b9335   Al Viro   fixing audit rule...
676
677
678
679
680
681
682
683
684
685
  
  	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
686
687
  	switch (rule->action) {
  	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
690
691
692
693
694
695
696
  	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...
697
  static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
699
700
701
702
  {
  	struct audit_entry *e;
  	enum audit_state   state;
  
  	rcu_read_lock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
703
  	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
f56298835   Tony Jones   audit: acquire cr...
704
705
  		if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
  				       &state, true)) {
e048e02c8   Al Viro   make sure that fi...
706
707
  			if (state == AUDIT_RECORD_CONTEXT)
  				*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
709
710
711
712
713
714
715
716
717
  			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...
718
   * also not high enough that we already know we have to write an audit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
719
   * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
722
723
724
725
   */
  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...
726
  	enum audit_state state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727

351bb7225   David Woodhouse   AUDIT: Fix compil...
728
  	if (audit_pid && tsk->tgid == audit_pid)
f7056d64a   David Woodhouse   AUDIT: Really exe...
729
  		return AUDIT_DISABLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
  	rcu_read_lock();
c38964959   David Woodhouse   AUDIT: Speed up a...
731
  	if (!list_empty(list)) {
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
732
733
734
735
  		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...
736
737
  			if ((e->rule.mask[word] & bit) == bit &&
  			    audit_filter_rules(tsk, &e->rule, ctx, NULL,
f56298835   Tony Jones   audit: acquire cr...
738
  					       &state, false)) {
f368c07d7   Amy Griffis   [PATCH] audit: pa...
739
  				rcu_read_unlock();
0590b9335   Al Viro   fixing audit rule...
740
  				ctx->current_state = state;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
741
742
743
744
745
746
747
  				return state;
  			}
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
5195d8e21   Eric Paris   audit: dynamicall...
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
  /*
   * Given an audit_name check the inode hash table to see if they match.
   * Called holding the rcu read lock to protect the use of audit_inode_hash
   */
  static int audit_filter_inode_name(struct task_struct *tsk,
  				   struct audit_names *n,
  				   struct audit_context *ctx) {
  	int word, bit;
  	int h = audit_hash_ino((u32)n->ino);
  	struct list_head *list = &audit_inode_hash[h];
  	struct audit_entry *e;
  	enum audit_state state;
  
  	word = AUDIT_WORD(ctx->major);
  	bit  = AUDIT_BIT(ctx->major);
  
  	if (list_empty(list))
  		return 0;
  
  	list_for_each_entry_rcu(e, list, list) {
  		if ((e->rule.mask[word] & bit) == bit &&
  		    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
  			ctx->current_state = state;
  			return 1;
  		}
  	}
  
  	return 0;
  }
  
  /* At syscall exit time, this filter is called if any audit_names have been
f368c07d7   Amy Griffis   [PATCH] audit: pa...
779
   * collected during syscall processing.  We only check rules in sublists at hash
5195d8e21   Eric Paris   audit: dynamicall...
780
   * buckets applicable to the inode numbers in audit_names.
f368c07d7   Amy Griffis   [PATCH] audit: pa...
781
782
   * Regarding audit_state, same rules apply as for audit_filter_syscall().
   */
0590b9335   Al Viro   fixing audit rule...
783
  void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
f368c07d7   Amy Griffis   [PATCH] audit: pa...
784
  {
5195d8e21   Eric Paris   audit: dynamicall...
785
  	struct audit_names *n;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
786
787
  
  	if (audit_pid && tsk->tgid == audit_pid)
0590b9335   Al Viro   fixing audit rule...
788
  		return;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
789
790
  
  	rcu_read_lock();
f368c07d7   Amy Griffis   [PATCH] audit: pa...
791

5195d8e21   Eric Paris   audit: dynamicall...
792
793
794
  	list_for_each_entry(n, &ctx->names_list, list) {
  		if (audit_filter_inode_name(tsk, n, ctx))
  			break;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
795
796
  	}
  	rcu_read_unlock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
797
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
799
  static inline struct audit_context *audit_get_context(struct task_struct *tsk,
  						      int return_valid,
6d208da89   Paul Moore   audit: Fix possib...
800
  						      long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
  {
  	struct audit_context *context = tsk->audit_context;
56179a6ec   Eric Paris   audit: drop some ...
803
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
805
  		return NULL;
  	context->return_valid = return_valid;
f701b75ed   Eric Paris   [AUDIT] return EI...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
  
  	/*
  	 * 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
824

0590b9335   Al Viro   fixing audit rule...
825
826
827
  	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
828
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
831
832
833
834
  	tsk->audit_context = NULL;
  	return context;
  }
  
  static inline void audit_free_names(struct audit_context *context)
  {
5195d8e21   Eric Paris   audit: dynamicall...
835
  	struct audit_names *n, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
  
  #if AUDIT_DEBUG == 2
0590b9335   Al Viro   fixing audit rule...
838
  	if (context->put_count + context->ino_count != context->name_count) {
34c474de7   Eric Paris   audit: fix build ...
839
  		int i = 0;
73241ccca   Amy Griffis   [PATCH] Collect m...
840
  		printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
  		       " name_count=%d put_count=%d"
  		       " ino_count=%d [NOT freeing]
  ",
73241ccca   Amy Griffis   [PATCH] Collect m...
844
  		       __FILE__, __LINE__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
  		       context->serial, context->major, context->in_syscall,
  		       context->name_count, context->put_count,
  		       context->ino_count);
5195d8e21   Eric Paris   audit: dynamicall...
848
  		list_for_each_entry(n, &context->names_list, list) {
34c474de7   Eric Paris   audit: fix build ...
849
850
  			printk(KERN_ERR "names[%d] = %p = %s
  ", i++,
91a27b2a7   Jeff Layton   vfs: define struc...
851
  			       n->name, n->name->name ?: "(null)");
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
852
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
855
856
857
858
859
860
  		dump_stack();
  		return;
  	}
  #endif
  #if AUDIT_DEBUG
  	context->put_count  = 0;
  	context->ino_count  = 0;
  #endif
5195d8e21   Eric Paris   audit: dynamicall...
861
862
863
  	list_for_each_entry_safe(n, next, &context->names_list, list) {
  		list_del(&n->list);
  		if (n->name && n->name_put)
65ada7bc0   Dmitry Monakhov   audit: destroy lo...
864
  			final_putname(n->name);
5195d8e21   Eric Paris   audit: dynamicall...
865
866
  		if (n->should_free)
  			kfree(n);
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
867
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
  	context->name_count = 0;
44707fdf5   Jan Blunck   d_path: Use struc...
869
870
871
  	path_put(&context->pwd);
  	context->pwd.dentry = NULL;
  	context->pwd.mnt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
876
877
878
879
880
881
  }
  
  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...
882
883
884
885
  	while ((aux = context->aux_pids)) {
  		context->aux_pids = aux->next;
  		kfree(aux);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
888
889
  static inline struct audit_context *audit_alloc_context(enum audit_state state)
  {
  	struct audit_context *context;
17c6ee707   Rakib Mullick   auditsc: Use kzal...
890
891
  	context = kzalloc(sizeof(*context), GFP_KERNEL);
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
892
  		return NULL;
e2c5adc88   Andrew Morton   auditsc: remove a...
893
894
  	context->state = state;
  	context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
916d75761   Al Viro   Fix rule eviction...
895
  	INIT_LIST_HEAD(&context->killed_trees);
5195d8e21   Eric Paris   audit: dynamicall...
896
  	INIT_LIST_HEAD(&context->names_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
  	return context;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
899
900
901
902
903
  /**
   * 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
904
905
   * 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...
906
907
   * needed.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
909
910
911
  int audit_alloc(struct task_struct *tsk)
  {
  	struct audit_context *context;
  	enum audit_state     state;
e048e02c8   Al Viro   make sure that fi...
912
  	char *key = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913

b593d384e   Eric Paris   [AUDIT] create co...
914
  	if (likely(!audit_ever_enabled))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
  		return 0; /* Return if not auditing. */
e048e02c8   Al Viro   make sure that fi...
916
  	state = audit_filter_task(tsk, &key);
56179a6ec   Eric Paris   audit: drop some ...
917
  	if (state == AUDIT_DISABLED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
919
920
  		return 0;
  
  	if (!(context = audit_alloc_context(state))) {
e048e02c8   Al Viro   make sure that fi...
921
  		kfree(key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
923
924
  		audit_log_lost("out of memory in audit_alloc");
  		return -ENOMEM;
  	}
e048e02c8   Al Viro   make sure that fi...
925
  	context->filterkey = key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
928
929
930
931
932
933
  	tsk->audit_context  = context;
  	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
  	return 0;
  }
  
  static inline void audit_free_context(struct audit_context *context)
  {
c62d773a3   Al Viro   audit: no nested ...
934
935
936
937
938
939
940
  	audit_free_names(context);
  	unroll_tree_refs(context, NULL, 0);
  	free_tree_refs(context);
  	audit_free_aux(context);
  	kfree(context->filterkey);
  	kfree(context->sockaddr);
  	kfree(context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
  }
e54dc2431   Amy Griffis   [PATCH] audit sig...
942
  static int audit_log_pid_context(struct audit_context *context, pid_t pid,
cca080d9b   Eric W. Biederman   userns: Convert a...
943
  				 kuid_t auid, kuid_t uid, unsigned int sessionid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
944
  				 u32 sid, char *comm)
e54dc2431   Amy Griffis   [PATCH] audit sig...
945
946
  {
  	struct audit_buffer *ab;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
947
  	char *ctx = NULL;
e54dc2431   Amy Griffis   [PATCH] audit sig...
948
949
950
951
952
  	u32 len;
  	int rc = 0;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
  	if (!ab)
6246ccab9   Eric Paris   [AUDIT] do not pa...
953
  		return rc;
e54dc2431   Amy Griffis   [PATCH] audit sig...
954

e1760bd5f   Eric W. Biederman   userns: Convert t...
955
956
  	audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
  			 from_kuid(&init_user_ns, auid),
cca080d9b   Eric W. Biederman   userns: Convert a...
957
  			 from_kuid(&init_user_ns, uid), sessionid);
ad395abec   Eric Paris   Audit: do not pri...
958
959
960
961
962
963
964
965
  	if (sid) {
  		if (security_secid_to_secctx(sid, &ctx, &len)) {
  			audit_log_format(ab, " obj=(none)");
  			rc = 1;
  		} else {
  			audit_log_format(ab, " obj=%s", ctx);
  			security_release_secctx(ctx, len);
  		}
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
966
  	}
c2a7780ef   Eric Paris   [AUDIT] collect u...
967
968
  	audit_log_format(ab, " ocomm=");
  	audit_log_untrustedstring(ab, comm);
e54dc2431   Amy Griffis   [PATCH] audit sig...
969
  	audit_log_end(ab);
e54dc2431   Amy Griffis   [PATCH] audit sig...
970
971
972
  
  	return rc;
  }
de6bbd1d3   Eric Paris   [AUDIT] break lar...
973
974
975
  /*
   * 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...
976
   * within about 500 bytes (next page boundary)
de6bbd1d3   Eric Paris   [AUDIT] break lar...
977
978
979
980
981
982
983
984
985
986
987
988
989
   *
   * 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...
990
  {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
991
992
  	char arg_num_len_buf[12];
  	const char __user *tmp_p = p;
b87ce6e41   Eric Paris   Audit: better est...
993
994
  	/* 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...
995
996
997
998
999
1000
1001
  	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...
1002

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1003
1004
1005
1006
1007
1008
  	/*
  	 * 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...
1009
  	if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1010
1011
  		WARN_ON(1);
  		send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1012
  		return -1;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1013
  	}
040b3a2df   Peter Zijlstra   audit: fix two bu...
1014

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1015
1016
1017
1018
1019
1020
1021
  	/* 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...
1022
  		/*
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1023
1024
1025
  		 * 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...
1026
  		 */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1027
  		if (ret) {
bdf4c48af   Peter Zijlstra   audit: rework exe...
1028
1029
  			WARN_ON(1);
  			send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1030
  			return -1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1031
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1032
1033
1034
1035
1036
1037
1038
1039
  		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...
1040
1041
  			break;
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
  		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...
1073

bdf4c48af   Peter Zijlstra   audit: rework exe...
1074
  		/*
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1075
1076
1077
1078
  		 * 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...
1079
  			audit_log_format(*ab, " a%d_len=%zu", arg_num,
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1080
1081
1082
1083
1084
1085
  					 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...
1086
  		 */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1087
1088
1089
1090
  		if (len >= max_execve_audit_len)
  			ret = copy_from_user(buf, p, to_send);
  		else
  			ret = 0;
040b3a2df   Peter Zijlstra   audit: fix two bu...
1091
  		if (ret) {
bdf4c48af   Peter Zijlstra   audit: rework exe...
1092
1093
  			WARN_ON(1);
  			send_sig(SIGKILL, current, 0);
b0abcfc14   Eric Paris   Audit: use == not...
1094
  			return -1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1095
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1096
1097
1098
  		buf[to_send] = '\0';
  
  		/* actually log it */
ca96a895a   Jiri Pirko   audit: EXECVE rec...
1099
  		audit_log_format(*ab, " a%d", arg_num);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1100
1101
1102
1103
  		if (too_long)
  			audit_log_format(*ab, "[%d]", i);
  		audit_log_format(*ab, "=");
  		if (has_cntl)
b556f8ad5   Eric Paris   Audit: standardiz...
1104
  			audit_log_n_hex(*ab, buf, to_send);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1105
  		else
9d9609851   Eric Paris   Audit: clean up a...
1106
  			audit_log_string(*ab, buf);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
  
  		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)
  {
5afb8a3f9   Xi Wang   audit: fix signed...
1124
1125
  	int i, len;
  	size_t len_sent = 0;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1126
1127
  	const char __user *p;
  	char *buf;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1128

de6bbd1d3   Eric Paris   [AUDIT] break lar...
1129
1130
1131
1132
  	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...
1133

ca96a895a   Jiri Pirko   audit: EXECVE rec...
1134
  	audit_log_format(*ab, "argc=%d", axi->argc);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
  
  	/*
  	 * 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...
1147
  	}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1148
1149
1150
1151
1152
1153
1154
1155
1156
  
  	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...
1157
  }
a33e67510   Al Viro   sanitize audit_ip...
1158
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
  {
  	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...
1175
1176
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1177
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
cca080d9b   Eric W. Biederman   userns: Convert a...
1178
1179
1180
  				 from_kuid(&init_user_ns, context->ipc.uid),
  				 from_kgid(&init_user_ns, context->ipc.gid),
  				 context->ipc.mode);
a33e67510   Al Viro   sanitize audit_ip...
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
  		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...
1192
1193
1194
1195
  		if (context->ipc.has_perm) {
  			audit_log_end(ab);
  			ab = audit_log_start(context, GFP_KERNEL,
  					     AUDIT_IPC_SET_PERM);
0644ec0cc   Kees Cook   audit: catch poss...
1196
1197
  			if (unlikely(!ab))
  				return;
e816f370c   Al Viro   sanitize audit_ip...
1198
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1199
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1200
1201
1202
1203
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
e816f370c   Al Viro   sanitize audit_ip...
1204
  		}
a33e67510   Al Viro   sanitize audit_ip...
1205
  		break; }
564f6993f   Al Viro   sanitize audit_mq...
1206
1207
  	case AUDIT_MQ_OPEN: {
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1208
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1209
1210
1211
1212
1213
1214
1215
  			"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...
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
  	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...
1226
1227
1228
1229
1230
  	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...
1231
1232
1233
1234
1235
1236
1237
1238
1239
  	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...
1240
1241
1242
1243
1244
1245
  	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
1246
1247
1248
1249
  	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...
1250
1251
1252
  	}
  	audit_log_end(ab);
  }
e495149b1   Al Viro   [PATCH] drop gfp_...
1253
  static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
  {
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1255
  	int i, call_panic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1256
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1257
  	struct audit_aux_data *aux;
5195d8e21   Eric Paris   audit: dynamicall...
1258
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259

e495149b1   Al Viro   [PATCH] drop gfp_...
1260
  	/* tsk == current */
3f2792ffb   Al Viro   [PATCH] take fill...
1261
  	context->personality = tsk->personality;
e495149b1   Al Viro   [PATCH] drop gfp_...
1262
1263
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
1265
  	if (!ab)
  		return;		/* audit_panic has been called */
bccf6ae08   David Woodhouse   AUDIT: Unify auid...
1266
1267
  	audit_log_format(ab, "arch=%x syscall=%d",
  			 context->arch, context->major);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
1269
1270
  	if (context->personality != PER_LINUX)
  		audit_log_format(ab, " per=%lx", context->personality);
  	if (context->return_valid)
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1271
  		audit_log_format(ab, " success=%s exit=%ld",
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1272
1273
  				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
  				 context->return_code);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1274

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1276
1277
1278
1279
1280
1281
  			 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d",
  			 context->argv[0],
  			 context->argv[1],
  			 context->argv[2],
  			 context->argv[3],
  			 context->name_count);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1282

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

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

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

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

3fc689e96   Eric Paris   Any time fcaps or...
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
  		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
1312
1313
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1315
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1316
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1317

157cf649a   Al Viro   sanitize audit_fd...
1318
1319
1320
1321
1322
1323
1324
1325
  	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 ...
1326
1327
1328
1329
1330
1331
1332
1333
1334
  	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...
1335
1336
  	for (aux = context->aux_pids; aux; aux = aux->next) {
  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1337
1338
1339
  
  		for (i = 0; i < axs->pid_count; i++)
  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1340
1341
  						  axs->target_auid[i],
  						  axs->target_uid[i],
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1342
  						  axs->target_sessionid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1343
1344
  						  axs->target_sid[i],
  						  axs->target_comm[i]))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1345
  				call_panic = 1;
a5cb013da   Al Viro   [PATCH] auditing ...
1346
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1347
1348
  	if (context->target_pid &&
  	    audit_log_pid_context(context, context->target_pid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1349
  				  context->target_auid, context->target_uid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1350
  				  context->target_sessionid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1351
  				  context->target_sid, context->target_comm))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1352
  			call_panic = 1;
44707fdf5   Jan Blunck   d_path: Use struc...
1353
  	if (context->pwd.dentry && context->pwd.mnt) {
e495149b1   Al Viro   [PATCH] drop gfp_...
1354
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1355
  		if (ab) {
c158a35c8   Kees Cook   audit: no leading...
1356
  			audit_log_d_path(ab, " cwd=", &context->pwd);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1357
1358
1359
  			audit_log_end(ab);
  		}
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1360

5195d8e21   Eric Paris   audit: dynamicall...
1361
1362
  	i = 0;
  	list_for_each_entry(n, &context->names_list, list)
b24a30a73   Eric Paris   audit: fix event ...
1363
  		audit_log_name(context, n, NULL, i++, &call_panic);
c0641f28d   Eric Paris   [AUDIT] Add End o...
1364
1365
1366
1367
1368
  
  	/* 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...
1369
1370
  	if (call_panic)
  		audit_panic("error converting sid to string");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1372
1373
1374
1375
  /**
   * audit_free - free a per-task audit context
   * @tsk: task whose audit context block to free
   *
fa84cb935   Al Viro   [PATCH] move call...
1376
   * Called from copy_process and do_exit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1377
   */
a4ff8dba7   Eric Paris   audit: inline aud...
1378
  void __audit_free(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1379
1380
  {
  	struct audit_context *context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381
  	context = audit_get_context(tsk, 0, 0);
56179a6ec   Eric Paris   audit: drop some ...
1382
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1383
1384
1385
  		return;
  
  	/* Check for system calls that do not go through the exit
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1386
1387
  	 * 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...
1388
  	 * in the context of the idle thread */
e495149b1   Al Viro   [PATCH] drop gfp_...
1389
  	/* that can happen only if we are called from do_exit() */
0590b9335   Al Viro   fixing audit rule...
1390
  	if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
e495149b1   Al Viro   [PATCH] drop gfp_...
1391
  		audit_log_exit(context, tsk);
916d75761   Al Viro   Fix rule eviction...
1392
1393
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
1395
1396
  
  	audit_free_context(context);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1397
1398
  /**
   * audit_syscall_entry - fill in an audit record at syscall entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1399
1400
1401
1402
1403
1404
1405
1406
   * @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
1407
1408
1409
1410
1411
   * 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...
1412
1413
   * be written).
   */
b05d8447e   Eric Paris   audit: inline aud...
1414
  void __audit_syscall_entry(int arch, int major,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1415
1416
1417
  			 unsigned long a1, unsigned long a2,
  			 unsigned long a3, unsigned long a4)
  {
5411be59d   Al Viro   [PATCH] drop task...
1418
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
1420
  	struct audit_context *context = tsk->audit_context;
  	enum audit_state     state;
56179a6ec   Eric Paris   audit: drop some ...
1421
  	if (!context)
86a1c34a9   Roland McGrath   x86_64 syscall au...
1422
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1423

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
1425
1426
1427
  	BUG_ON(context->in_syscall || context->name_count);
  
  	if (!audit_enabled)
  		return;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1428
  	context->arch	    = arch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
1431
1432
1433
1434
1435
  	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...
1436
  	context->dummy = !audit_n_rules;
0590b9335   Al Viro   fixing audit rule...
1437
1438
  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
  		context->prio = 0;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1439
  		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
0590b9335   Al Viro   fixing audit rule...
1440
  	}
56179a6ec   Eric Paris   audit: drop some ...
1441
  	if (state == AUDIT_DISABLED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1442
  		return;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1443
  	context->serial     = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
1445
  	context->ctime      = CURRENT_TIME;
  	context->in_syscall = 1;
0590b9335   Al Viro   fixing audit rule...
1446
  	context->current_state  = state;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1447
  	context->ppid       = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1449
1450
  /**
   * audit_syscall_exit - deallocate audit context after a system call
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1451
1452
   * @success: success value of the syscall
   * @return_code: return value of the syscall
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1453
1454
   *
   * Tear down after system call.  If the audit context has been marked as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1455
   * auditable (either because of the AUDIT_RECORD_CONTEXT state from
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1456
   * filtering, or because some other part of the kernel wrote an audit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1457
   * message), then write out the syscall information.  In call cases,
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1458
1459
   * free the names stored from getname().
   */
d7e7528bc   Eric Paris   Audit: push audit...
1460
  void __audit_syscall_exit(int success, long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1461
  {
5411be59d   Al Viro   [PATCH] drop task...
1462
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463
  	struct audit_context *context;
d7e7528bc   Eric Paris   Audit: push audit...
1464
1465
1466
1467
  	if (success)
  		success = AUDITSC_SUCCESS;
  	else
  		success = AUDITSC_FAILURE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1468

d7e7528bc   Eric Paris   Audit: push audit...
1469
  	context = audit_get_context(tsk, success, return_code);
56179a6ec   Eric Paris   audit: drop some ...
1470
  	if (!context)
97e94c453   Al Viro   [PATCH] no need t...
1471
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472

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

916d75761   Al Viro   Fix rule eviction...
1479
1480
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
c62d773a3   Al Viro   audit: no nested ...
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
  	audit_free_names(context);
  	unroll_tree_refs(context, NULL, 0);
  	audit_free_aux(context);
  	context->aux = NULL;
  	context->aux_pids = NULL;
  	context->target_pid = 0;
  	context->target_sid = 0;
  	context->sockaddr_len = 0;
  	context->type = 0;
  	context->fds[0] = -1;
  	if (context->state != AUDIT_RECORD_CONTEXT) {
  		kfree(context->filterkey);
  		context->filterkey = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
  	}
c62d773a3   Al Viro   audit: no nested ...
1495
  	tsk->audit_context = context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1497
1498
1499
1500
1501
1502
1503
  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 ...
1504
  	if (likely(hlist_empty(&inode->i_fsnotify_marks)))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
  		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...
1517
1518
  		printk(KERN_WARNING "out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
  		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 ...
1548
  		if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_marks))) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
  			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...
1578
1579
  			"out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1580
1581
1582
1583
1584
1585
1586
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
  #endif
  }
78e2e802a   Jeff Layton   audit: add a new ...
1587
1588
  static struct audit_names *audit_alloc_name(struct audit_context *context,
  						unsigned char type)
5195d8e21   Eric Paris   audit: dynamicall...
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
  {
  	struct audit_names *aname;
  
  	if (context->name_count < AUDIT_NAMES) {
  		aname = &context->preallocated_names[context->name_count];
  		memset(aname, 0, sizeof(*aname));
  	} else {
  		aname = kzalloc(sizeof(*aname), GFP_NOFS);
  		if (!aname)
  			return NULL;
  		aname->should_free = true;
  	}
  
  	aname->ino = (unsigned long)-1;
78e2e802a   Jeff Layton   audit: add a new ...
1603
  	aname->type = type;
5195d8e21   Eric Paris   audit: dynamicall...
1604
1605
1606
1607
1608
1609
1610
1611
  	list_add_tail(&aname->list, &context->names_list);
  
  	context->name_count++;
  #if AUDIT_DEBUG
  	context->ino_count++;
  #endif
  	return aname;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1612
  /**
7ac86265d   Jeff Layton   audit: allow audi...
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
   * audit_reusename - fill out filename with info from existing entry
   * @uptr: userland ptr to pathname
   *
   * Search the audit_names list for the current audit context. If there is an
   * existing entry with a matching "uptr" then return the filename
   * associated with that audit_name. If not, return NULL.
   */
  struct filename *
  __audit_reusename(const __user char *uptr)
  {
  	struct audit_context *context = current->audit_context;
  	struct audit_names *n;
  
  	list_for_each_entry(n, &context->names_list, list) {
  		if (!n->name)
  			continue;
  		if (n->name->uptr == uptr)
  			return n->name;
  	}
  	return NULL;
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1636
1637
1638
1639
1640
1641
   * 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().
   */
91a27b2a7   Jeff Layton   vfs: define struc...
1642
  void __audit_getname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1643
1644
  {
  	struct audit_context *context = current->audit_context;
5195d8e21   Eric Paris   audit: dynamicall...
1645
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1646

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
1648
1649
1650
1651
1652
1653
1654
1655
  	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;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1656

91a27b2a7   Jeff Layton   vfs: define struc...
1657
1658
1659
1660
  #if AUDIT_DEBUG
  	/* The filename _must_ have a populated ->name */
  	BUG_ON(!name->name);
  #endif
78e2e802a   Jeff Layton   audit: add a new ...
1661
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1662
1663
1664
1665
1666
1667
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
  	n->name_put = true;
adb5c2473   Jeff Layton   audit: make audit...
1668
  	name->aname = n;
5195d8e21   Eric Paris   audit: dynamicall...
1669

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1670
1671
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1673
1674
1675
1676
1677
1678
1679
  /* 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().
   */
91a27b2a7   Jeff Layton   vfs: define struc...
1680
  void audit_putname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1681
1682
1683
1684
1685
1686
  {
  	struct audit_context *context = current->audit_context;
  
  	BUG_ON(!context);
  	if (!context->in_syscall) {
  #if AUDIT_DEBUG == 2
65ada7bc0   Dmitry Monakhov   audit: destroy lo...
1687
1688
  		printk(KERN_ERR "%s:%d(:%d): final_putname(%p)
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
1690
  		       __FILE__, __LINE__, context->serial, name);
  		if (context->name_count) {
5195d8e21   Eric Paris   audit: dynamicall...
1691
  			struct audit_names *n;
34c474de7   Eric Paris   audit: fix build ...
1692
  			int i = 0;
5195d8e21   Eric Paris   audit: dynamicall...
1693
1694
  
  			list_for_each_entry(n, &context->names_list, list)
34c474de7   Eric Paris   audit: fix build ...
1695
1696
  				printk(KERN_ERR "name[%d] = %p = %s
  ", i++,
91a27b2a7   Jeff Layton   vfs: define struc...
1697
  				       n->name, n->name->name ?: "(null)");
5195d8e21   Eric Paris   audit: dynamicall...
1698
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1699
  #endif
65ada7bc0   Dmitry Monakhov   audit: destroy lo...
1700
  		final_putname(name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
  	}
  #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,
91a27b2a7   Jeff Layton   vfs: define struc...
1712
1713
  			       context->in_syscall, name->name,
  			       context->name_count, context->put_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714
1715
1716
1717
1718
  			dump_stack();
  		}
  	}
  #endif
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1719
  /**
bfcec7087   Jeff Layton   audit: set the na...
1720
   * __audit_inode - store the inode and device from a lookup
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1721
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1722
   * @dentry: dentry being audited
bfcec7087   Jeff Layton   audit: set the na...
1723
   * @parent: does this dentry represent the parent?
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1724
   */
adb5c2473   Jeff Layton   audit: make audit...
1725
  void __audit_inode(struct filename *name, const struct dentry *dentry,
bfcec7087   Jeff Layton   audit: set the na...
1726
  		   unsigned int parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1727
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1728
  	struct audit_context *context = current->audit_context;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1729
  	const struct inode *inode = dentry->d_inode;
5195d8e21   Eric Paris   audit: dynamicall...
1730
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
1732
1733
  
  	if (!context->in_syscall)
  		return;
5195d8e21   Eric Paris   audit: dynamicall...
1734

9cec9d68a   Jeff Layton   audit: no need to...
1735
1736
  	if (!name)
  		goto out_alloc;
adb5c2473   Jeff Layton   audit: make audit...
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
  #if AUDIT_DEBUG
  	/* The struct filename _must_ have a populated ->name */
  	BUG_ON(!name->name);
  #endif
  	/*
  	 * If we have a pointer to an audit_names entry already, then we can
  	 * just use it directly if the type is correct.
  	 */
  	n = name->aname;
  	if (n) {
  		if (parent) {
  			if (n->type == AUDIT_TYPE_PARENT ||
  			    n->type == AUDIT_TYPE_UNKNOWN)
  				goto out;
  		} else {
  			if (n->type != AUDIT_TYPE_PARENT)
  				goto out;
  		}
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1756
  	list_for_each_entry_reverse(n, &context->names_list, list) {
bfcec7087   Jeff Layton   audit: set the na...
1757
  		/* does the name pointer match? */
adb5c2473   Jeff Layton   audit: make audit...
1758
  		if (!n->name || n->name->name != name->name)
bfcec7087   Jeff Layton   audit: set the na...
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
  			continue;
  
  		/* match the correct record type */
  		if (parent) {
  			if (n->type == AUDIT_TYPE_PARENT ||
  			    n->type == AUDIT_TYPE_UNKNOWN)
  				goto out;
  		} else {
  			if (n->type != AUDIT_TYPE_PARENT)
  				goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1770
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1771

9cec9d68a   Jeff Layton   audit: no need to...
1772
  out_alloc:
bfcec7087   Jeff Layton   audit: set the na...
1773
1774
1775
  	/* unable to find the name from a previous getname(). Allocate a new
  	 * anonymous entry.
  	 */
78e2e802a   Jeff Layton   audit: add a new ...
1776
  	n = audit_alloc_name(context, AUDIT_TYPE_NORMAL);
5195d8e21   Eric Paris   audit: dynamicall...
1777
1778
1779
  	if (!n)
  		return;
  out:
bfcec7087   Jeff Layton   audit: set the na...
1780
  	if (parent) {
91a27b2a7   Jeff Layton   vfs: define struc...
1781
  		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
bfcec7087   Jeff Layton   audit: set the na...
1782
1783
1784
1785
1786
  		n->type = AUDIT_TYPE_PARENT;
  	} else {
  		n->name_len = AUDIT_NAME_FULL;
  		n->type = AUDIT_TYPE_NORMAL;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1787
  	handle_path(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1788
  	audit_copy_inode(n, dentry, inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1789
1790
1791
  }
  
  /**
c43a25abb   Jeff Layton   audit: reverse ar...
1792
   * __audit_inode_child - collect inode info for created/removed objects
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1793
   * @parent: inode of dentry parent
c43a25abb   Jeff Layton   audit: reverse ar...
1794
   * @dentry: dentry being audited
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1795
   * @type:   AUDIT_TYPE_* value that we're looking for
73241ccca   Amy Griffis   [PATCH] Collect m...
1796
1797
1798
1799
1800
1801
1802
1803
1804
   *
   * 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.
   */
c43a25abb   Jeff Layton   audit: reverse ar...
1805
  void __audit_inode_child(const struct inode *parent,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1806
1807
  			 const struct dentry *dentry,
  			 const unsigned char type)
73241ccca   Amy Griffis   [PATCH] Collect m...
1808
  {
73241ccca   Amy Griffis   [PATCH] Collect m...
1809
  	struct audit_context *context = current->audit_context;
5a190ae69   Al Viro   [PATCH] pass dent...
1810
  	const struct inode *inode = dentry->d_inode;
cccc6bba3   Al Viro   Lose the first ar...
1811
  	const char *dname = dentry->d_name.name;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1812
  	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
73241ccca   Amy Griffis   [PATCH] Collect m...
1813
1814
1815
  
  	if (!context->in_syscall)
  		return;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1816
1817
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1818

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1819
  	/* look for a parent entry first */
5195d8e21   Eric Paris   audit: dynamicall...
1820
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1821
  		if (!n->name || n->type != AUDIT_TYPE_PARENT)
5712e88f2   Amy Griffis   [PATCH] match aud...
1822
1823
1824
  			continue;
  
  		if (n->ino == parent->i_ino &&
91a27b2a7   Jeff Layton   vfs: define struc...
1825
  		    !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1826
1827
  			found_parent = n;
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1828
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1829
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1830

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1831
  	/* is there a matching child entry? */
5195d8e21   Eric Paris   audit: dynamicall...
1832
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1833
1834
1835
1836
1837
1838
  		/* can only match entries that have a name */
  		if (!n->name || n->type != type)
  			continue;
  
  		/* if we found a parent, make sure this one is a child of it */
  		if (found_parent && (n->name != found_parent->name))
5712e88f2   Amy Griffis   [PATCH] match aud...
1839
  			continue;
91a27b2a7   Jeff Layton   vfs: define struc...
1840
1841
  		if (!strcmp(dname, n->name->name) ||
  		    !audit_compare_dname_path(dname, n->name->name,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1842
1843
  						found_parent ?
  						found_parent->name_len :
e3d6b07b8   Jeff Layton   audit: optimize a...
1844
  						AUDIT_NAME_FULL)) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1845
1846
  			found_child = n;
  			break;
5712e88f2   Amy Griffis   [PATCH] match aud...
1847
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1848
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1849

5712e88f2   Amy Griffis   [PATCH] match aud...
1850
  	if (!found_parent) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1851
1852
  		/* create a new, "anonymous" parent record */
  		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
5195d8e21   Eric Paris   audit: dynamicall...
1853
  		if (!n)
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1854
  			return;
5195d8e21   Eric Paris   audit: dynamicall...
1855
  		audit_copy_inode(n, NULL, parent);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1856
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1857
1858
  
  	if (!found_child) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1859
1860
  		found_child = audit_alloc_name(context, type);
  		if (!found_child)
5712e88f2   Amy Griffis   [PATCH] match aud...
1861
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
1862
1863
1864
1865
1866
  
  		/* 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) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1867
1868
  			found_child->name = found_parent->name;
  			found_child->name_len = AUDIT_NAME_FULL;
5712e88f2   Amy Griffis   [PATCH] match aud...
1869
  			/* don't call __putname() */
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1870
  			found_child->name_put = false;
5712e88f2   Amy Griffis   [PATCH] match aud...
1871
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1872
  	}
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1873
1874
1875
1876
  	if (inode)
  		audit_copy_inode(found_child, dentry, inode);
  	else
  		found_child->ino = (unsigned long)-1;
3e2efce06   Amy Griffis   [PATCH] fix fault...
1877
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
1878
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
1879
1880
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1881
1882
1883
1884
1885
1886
1887
   * 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...
1888
  int auditsc_get_stamp(struct audit_context *ctx,
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1889
  		       struct timespec *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
  {
48887e63d   Al Viro   [PATCH] fix broke...
1891
1892
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1893
1894
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1895
1896
1897
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
1898
1899
1900
1901
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
1902
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
  }
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1904
1905
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1906
  /**
0a300be6d   Eric Paris   audit: remove tas...
1907
   * audit_set_loginuid - set current task's audit_context loginuid
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1908
1909
1910
1911
1912
1913
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
e1760bd5f   Eric W. Biederman   userns: Convert t...
1914
  int audit_set_loginuid(kuid_t loginuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
  {
0a300be6d   Eric Paris   audit: remove tas...
1916
  	struct task_struct *task = current;
41757106b   Steve Grubb   [PATCH] make set_...
1917
  	struct audit_context *context = task->audit_context;
633b45454   Eric Paris   audit: only allow...
1918
  	unsigned int sessionid;
41757106b   Steve Grubb   [PATCH] make set_...
1919

633b45454   Eric Paris   audit: only allow...
1920
  #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE
780a7654c   Eric W. Biederman   audit: Make testi...
1921
  	if (audit_loginuid_set(task))
633b45454   Eric Paris   audit: only allow...
1922
1923
1924
1925
1926
1927
1928
  		return -EPERM;
  #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
  	if (!capable(CAP_AUDIT_CONTROL))
  		return -EPERM;
  #endif  /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
  
  	sessionid = atomic_inc_return(&session_id);
bfef93a5d   Al Viro   [PATCH] get rid o...
1929
1930
1931
1932
1933
1934
  	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...
1935
1936
  				"old auid=%u new auid=%u"
  				" old ses=%u new ses=%u",
cca080d9b   Eric W. Biederman   userns: Convert a...
1937
1938
  				task->pid,
  				from_kuid(&init_user_ns, task_uid(task)),
e1760bd5f   Eric W. Biederman   userns: Convert t...
1939
1940
  				from_kuid(&init_user_ns, task->loginuid),
  				from_kuid(&init_user_ns, loginuid),
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1941
  				task->sessionid, sessionid);
bfef93a5d   Al Viro   [PATCH] get rid o...
1942
  			audit_log_end(ab);
c04049939   Steve Grubb   AUDIT: Add messag...
1943
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1944
  	}
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1945
  	task->sessionid = sessionid;
bfef93a5d   Al Viro   [PATCH] get rid o...
1946
  	task->loginuid = loginuid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
1948
  	return 0;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1949
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1950
1951
1952
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
1953
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1954
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1955
   */
df0a42837   Al Viro   switch mq_open() ...
1956
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1957
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1958
  	struct audit_context *context = current->audit_context;
564f6993f   Al Viro   sanitize audit_mq...
1959
1960
1961
1962
  	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 ...
1963

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

564f6993f   Al Viro   sanitize audit_mq...
1967
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1968
1969
1970
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1971
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1972
1973
1974
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1975
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1976
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1977
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1978
1979
  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 ...
1980
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1981
  	struct audit_context *context = current->audit_context;
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1982
  	struct timespec *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1983

c32c8af43   Al Viro   sanitize AUDIT_MQ...
1984
1985
1986
1987
  	if (abs_timeout)
  		memcpy(p, abs_timeout, sizeof(struct timespec));
  	else
  		memset(p, 0, sizeof(struct timespec));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1988

c32c8af43   Al Viro   sanitize AUDIT_MQ...
1989
1990
1991
  	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 ...
1992

c32c8af43   Al Viro   sanitize AUDIT_MQ...
1993
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1994
1995
1996
1997
1998
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
1999
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2000
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2001
   */
20114f71b   Al Viro   sanitize audit_mq...
2002
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2003
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2004
  	struct audit_context *context = current->audit_context;
20114f71b   Al Viro   sanitize audit_mq...
2005
2006
2007
2008
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2009

20114f71b   Al Viro   sanitize audit_mq...
2010
2011
  	context->mq_notify.mqdes = mqdes;
  	context->type = AUDIT_MQ_NOTIFY;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2012
2013
2014
2015
2016
2017
2018
  }
  
  /**
   * __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 ...
2019
   */
7392906ea   Al Viro   sanitize audit_mq...
2020
  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2021
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2022
  	struct audit_context *context = current->audit_context;
7392906ea   Al Viro   sanitize audit_mq...
2023
2024
2025
  	context->mq_getsetattr.mqdes = mqdes;
  	context->mq_getsetattr.mqstat = *mqstat;
  	context->type = AUDIT_MQ_GETSETATTR;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2026
2027
2028
  }
  
  /**
073115d6b   Steve Grubb   [PATCH] Rework of...
2029
2030
2031
   * audit_ipc_obj - record audit data for ipc object
   * @ipcp: ipc permissions
   *
073115d6b   Steve Grubb   [PATCH] Rework of...
2032
   */
a33e67510   Al Viro   sanitize audit_ip...
2033
  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
073115d6b   Steve Grubb   [PATCH] Rework of...
2034
  {
073115d6b   Steve Grubb   [PATCH] Rework of...
2035
  	struct audit_context *context = current->audit_context;
a33e67510   Al Viro   sanitize audit_ip...
2036
2037
2038
  	context->ipc.uid = ipcp->uid;
  	context->ipc.gid = ipcp->gid;
  	context->ipc.mode = ipcp->mode;
e816f370c   Al Viro   sanitize audit_ip...
2039
  	context->ipc.has_perm = 0;
a33e67510   Al Viro   sanitize audit_ip...
2040
2041
  	security_ipc_getsecid(ipcp, &context->ipc.osid);
  	context->type = AUDIT_IPC;
073115d6b   Steve Grubb   [PATCH] Rework of...
2042
2043
2044
2045
  }
  
  /**
   * audit_ipc_set_perm - record audit data for new ipc permissions
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2046
2047
2048
2049
2050
   * @qbytes: msgq bytes
   * @uid: msgq user id
   * @gid: msgq group id
   * @mode: msgq mode (permissions)
   *
e816f370c   Al Viro   sanitize audit_ip...
2051
   * Called only after audit_ipc_obj().
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2052
   */
2570ebbd1   Al Viro   switch kern_ipc_p...
2053
  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
2054
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055
  	struct audit_context *context = current->audit_context;
e816f370c   Al Viro   sanitize audit_ip...
2056
2057
2058
2059
2060
  	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
2061
  }
c2f0c7c35   Steve Grubb   The attached patc...
2062

07c494178   Eric Paris   audit: inline che...
2063
  int __audit_bprm(struct linux_binprm *bprm)
473ae30bc   Al Viro   [PATCH] execve ar...
2064
2065
2066
  {
  	struct audit_aux_data_execve *ax;
  	struct audit_context *context = current->audit_context;
473ae30bc   Al Viro   [PATCH] execve ar...
2067

bdf4c48af   Peter Zijlstra   audit: rework exe...
2068
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
473ae30bc   Al Viro   [PATCH] execve ar...
2069
2070
2071
2072
2073
  	if (!ax)
  		return -ENOMEM;
  
  	ax->argc = bprm->argc;
  	ax->envc = bprm->envc;
bdf4c48af   Peter Zijlstra   audit: rework exe...
2074
  	ax->mm = bprm->mm;
473ae30bc   Al Viro   [PATCH] execve ar...
2075
2076
2077
2078
2079
  	ax->d.type = AUDIT_EXECVE;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
  	return 0;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2080
2081
  /**
   * audit_socketcall - record audit data for sys_socketcall
2950fa9d3   Chen Gang   kernel: audit: be...
2082
   * @nargs: number of args, which should not be more than AUDITSC_ARGS.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2083
2084
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2085
   */
2950fa9d3   Chen Gang   kernel: audit: be...
2086
  int __audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2087
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2088
  	struct audit_context *context = current->audit_context;
2950fa9d3   Chen Gang   kernel: audit: be...
2089
2090
  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
  		return -EINVAL;
f3298dc4f   Al Viro   sanitize audit_so...
2091
2092
2093
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
2950fa9d3   Chen Gang   kernel: audit: be...
2094
  	return 0;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2095
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2096
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2097
2098
2099
2100
   * __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_...
2101
   */
157cf649a   Al Viro   sanitize audit_fd...
2102
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2103
2104
  {
  	struct audit_context *context = current->audit_context;
157cf649a   Al Viro   sanitize audit_fd...
2105
2106
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2107
2108
2109
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2110
2111
2112
2113
2114
2115
   * 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.
   */
07c494178   Eric Paris   audit: inline che...
2116
  int __audit_sockaddr(int len, void *a)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2117
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2118
  	struct audit_context *context = current->audit_context;
4f6b434fe   Al Viro   don't reallocate ...
2119
2120
2121
2122
2123
2124
  	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...
2125

4f6b434fe   Al Viro   don't reallocate ...
2126
2127
  	context->sockaddr_len = len;
  	memcpy(context->sockaddr, a, len);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2128
2129
  	return 0;
  }
a5cb013da   Al Viro   [PATCH] auditing ...
2130
2131
2132
2133
2134
  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...
2135
  	context->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2136
  	context->target_uid = task_uid(t);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2137
  	context->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2138
  	security_task_getsecid(t, &context->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2139
  	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
a5cb013da   Al Viro   [PATCH] auditing ...
2140
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2141
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2142
2143
2144
2145
2146
2147
2148
   * 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...
2149
  int __audit_signal_info(int sig, struct task_struct *t)
c2f0c7c35   Steve Grubb   The attached patc...
2150
  {
e54dc2431   Amy Griffis   [PATCH] audit sig...
2151
2152
2153
  	struct audit_aux_data_pids *axp;
  	struct task_struct *tsk = current;
  	struct audit_context *ctx = tsk->audit_context;
cca080d9b   Eric W. Biederman   userns: Convert a...
2154
  	kuid_t uid = current_uid(), t_uid = task_uid(t);
e1396065e   Al Viro   [PATCH] collect s...
2155

175fc4842   Al Viro   fix oops in __aud...
2156
  	if (audit_pid && t->tgid == audit_pid) {
ee1d31566   Eric Paris   [PATCH] Audit: Co...
2157
  		if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
175fc4842   Al Viro   fix oops in __aud...
2158
  			audit_sig_pid = tsk->pid;
e1760bd5f   Eric W. Biederman   userns: Convert t...
2159
  			if (uid_valid(tsk->loginuid))
bfef93a5d   Al Viro   [PATCH] get rid o...
2160
  				audit_sig_uid = tsk->loginuid;
175fc4842   Al Viro   fix oops in __aud...
2161
  			else
c69e8d9c0   David Howells   CRED: Use RCU to ...
2162
  				audit_sig_uid = uid;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2163
  			security_task_getsecid(tsk, &audit_sig_sid);
175fc4842   Al Viro   fix oops in __aud...
2164
2165
2166
  		}
  		if (!audit_signals || audit_dummy_context())
  			return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2167
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
2168

e54dc2431   Amy Griffis   [PATCH] audit sig...
2169
2170
2171
2172
  	/* 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...
2173
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2174
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2175
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2176
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2177
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
  		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:...
2191
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2192
2193
  
  	axp->target_pid[axp->pid_count] = t->tgid;
c2a7780ef   Eric Paris   [AUDIT] collect u...
2194
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2195
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2196
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2197
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2198
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2199
2200
2201
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2202
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2203
2204
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2205
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2206
2207
2208
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2209
2210
2211
2212
   *
   * 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...
2213
2214
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2215
2216
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2217
2218
2219
2220
2221
2222
2223
2224
  {
  	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 ...
2225
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
  
  	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 ...
2239
2240
2241
  	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...
2242

d84f4f992   David Howells   CRED: Inaugurate ...
2243
2244
2245
2246
  	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...
2247
2248
2249
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2250
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2251
2252
2253
   * @pid: target pid of the capset call
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2254
2255
2256
2257
   *
   * Record the aguments userspace sent to sys_capset for later printing by the
   * audit system if applicable
   */
57f71a0af   Al Viro   sanitize audit_lo...
2258
  void __audit_log_capset(pid_t pid,
d84f4f992   David Howells   CRED: Inaugurate ...
2259
  		       const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2260
  {
e68b75a02   Eric Paris   When the capset s...
2261
  	struct audit_context *context = current->audit_context;
57f71a0af   Al Viro   sanitize audit_lo...
2262
2263
2264
2265
2266
  	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...
2267
  }
120a795da   Al Viro   audit mmap
2268
2269
2270
2271
2272
2273
2274
  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;
  }
7b9205bd7   Kees Cook   audit: create exp...
2275
  static void audit_log_task(struct audit_buffer *ab)
85e7bac33   Eric Paris   seccomp: audit ab...
2276
  {
cca080d9b   Eric W. Biederman   userns: Convert a...
2277
2278
  	kuid_t auid, uid;
  	kgid_t gid;
85e7bac33   Eric Paris   seccomp: audit ab...
2279
2280
2281
2282
2283
2284
2285
  	unsigned int sessionid;
  
  	auid = audit_get_loginuid(current);
  	sessionid = audit_get_sessionid(current);
  	current_uid_gid(&uid, &gid);
  
  	audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
cca080d9b   Eric W. Biederman   userns: Convert a...
2286
2287
2288
2289
  			 from_kuid(&init_user_ns, auid),
  			 from_kuid(&init_user_ns, uid),
  			 from_kgid(&init_user_ns, gid),
  			 sessionid);
85e7bac33   Eric Paris   seccomp: audit ab...
2290
2291
2292
  	audit_log_task_context(ab);
  	audit_log_format(ab, " pid=%d comm=", current->pid);
  	audit_log_untrustedstring(ab, current->comm);
7b9205bd7   Kees Cook   audit: create exp...
2293
2294
2295
2296
2297
  }
  
  static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
  {
  	audit_log_task(ab);
85e7bac33   Eric Paris   seccomp: audit ab...
2298
2299
2300
2301
  	audit_log_format(ab, " reason=");
  	audit_log_string(ab, reason);
  	audit_log_format(ab, " sig=%ld", signr);
  }
e68b75a02   Eric Paris   When the capset s...
2302
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2303
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2304
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2305
2306
2307
2308
2309
2310
2311
   *
   * 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;
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2312
2313
2314
2315
2316
2317
2318
2319
  
  	if (!audit_enabled)
  		return;
  
  	if (signr == SIGQUIT)	/* don't care for those */
  		return;
  
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
0644ec0cc   Kees Cook   audit: catch poss...
2320
2321
  	if (unlikely(!ab))
  		return;
85e7bac33   Eric Paris   seccomp: audit ab...
2322
2323
2324
  	audit_log_abend(ab, "memory violation", signr);
  	audit_log_end(ab);
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2325

3dc1c1b2d   Kees Cook   seccomp: remove d...
2326
  void __audit_seccomp(unsigned long syscall, long signr, int code)
85e7bac33   Eric Paris   seccomp: audit ab...
2327
2328
  {
  	struct audit_buffer *ab;
7b9205bd7   Kees Cook   audit: create exp...
2329
2330
2331
2332
2333
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
  	if (unlikely(!ab))
  		return;
  	audit_log_task(ab);
  	audit_log_format(ab, " sig=%ld", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2334
  	audit_log_format(ab, " syscall=%ld", syscall);
3dc1c1b2d   Kees Cook   seccomp: remove d...
2335
2336
2337
  	audit_log_format(ab, " compat=%d", is_compat_task());
  	audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
  	audit_log_format(ab, " code=0x%x", code);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2338
2339
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2340
2341
2342
2343
2344
2345
2346
2347
  
  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;
  }