Blame view

kernel/auditsc.c 64.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
   */
f952d10ff   Richard Guy Briggs   audit: Use more c...
44
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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>
473ae30bc   Al Viro   [PATCH] execve ar...
64
  #include <linux/binfmts.h>
a1f8e7f7f   Al Viro   [PATCH] severing ...
65
  #include <linux/highmem.h>
f46038ff7   Al Viro   [PATCH] log ppid
66
  #include <linux/syscalls.h>
84db564aa   Richard Guy Briggs   audit: add arch f...
67
  #include <asm/syscall.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>
3f1c82502   William Roberts   audit: Audit proc...
71
  #include <linux/ctype.h>
fcf22d826   Paul Moore   audit: create pri...
72
  #include <linux/string.h>
43761473c   Paul Moore   audit: fix a doub...
73
  #include <linux/uaccess.h>
fcf22d826   Paul Moore   audit: create pri...
74
  #include <uapi/linux/limits.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

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

d7e7528bc   Eric Paris   Audit: push audit...
78
79
80
81
  /* flags stating the success for a syscall */
  #define AUDITSC_INVALID 0
  #define AUDITSC_SUCCESS 1
  #define AUDITSC_FAILURE 2
43761473c   Paul Moore   audit: fix a doub...
82
83
  /* no execve audit message should be longer than this (userspace limits),
   * see the note near the top of audit_log_execve_info() about this value */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
84
  #define MAX_EXECVE_AUDIT_LEN 7500
3f1c82502   William Roberts   audit: Audit proc...
85
86
  /* max length to print of cmdline/proctitle value during audit */
  #define MAX_PROCTITLE_AUDIT_LEN 128
471a5c7c8   Al Viro   [PATCH] introduce...
87
88
  /* number of audit rules */
  int audit_n_rules;
e54dc2431   Amy Griffis   [PATCH] audit sig...
89
90
  /* determines whether we collect data for signals sent */
  int audit_signals;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
95
96
  struct audit_aux_data {
  	struct audit_aux_data	*next;
  	int			type;
  };
  
  #define AUDIT_AUX_IPCPERM	0
e54dc2431   Amy Griffis   [PATCH] audit sig...
97
98
  /* Number of target pids per aux struct. */
  #define AUDIT_AUX_PIDS	16
e54dc2431   Amy Griffis   [PATCH] audit sig...
99
100
101
  struct audit_aux_data_pids {
  	struct audit_aux_data	d;
  	pid_t			target_pid[AUDIT_AUX_PIDS];
e1760bd5f   Eric W. Biederman   userns: Convert t...
102
  	kuid_t			target_auid[AUDIT_AUX_PIDS];
cca080d9b   Eric W. Biederman   userns: Convert a...
103
  	kuid_t			target_uid[AUDIT_AUX_PIDS];
4746ec5b0   Eric Paris   [AUDIT] add sessi...
104
  	unsigned int		target_sessionid[AUDIT_AUX_PIDS];
e54dc2431   Amy Griffis   [PATCH] audit sig...
105
  	u32			target_sid[AUDIT_AUX_PIDS];
c2a7780ef   Eric Paris   [AUDIT] collect u...
106
  	char 			target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
e54dc2431   Amy Griffis   [PATCH] audit sig...
107
108
  	int			pid_count;
  };
3fc689e96   Eric Paris   Any time fcaps or...
109
110
111
112
113
114
115
  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;
  };
74c3cbe33   Al Viro   [PATCH] audit: wa...
116
117
118
119
  struct audit_tree_refs {
  	struct audit_tree_refs *next;
  	struct audit_chunk *c[31];
  };
55669bfa1   Al Viro   [PATCH] audit: AU...
120
121
  static int audit_match_perm(struct audit_context *ctx, int mask)
  {
c4bacefb7   Cordelia   [PATCH] audit: Mo...
122
  	unsigned n;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
123
124
  	if (unlikely(!ctx))
  		return 0;
c4bacefb7   Cordelia   [PATCH] audit: Mo...
125
  	n = ctx->major;
dbda4c0b9   Alan Cox   tty: Fix abusers ...
126

55669bfa1   Al Viro   [PATCH] audit: AU...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  	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...
162
  static int audit_match_filetype(struct audit_context *ctx, int val)
8b67dca94   Al Viro   [PATCH] new predi...
163
  {
5195d8e21   Eric Paris   audit: dynamicall...
164
  	struct audit_names *n;
5ef30ee53   Eric Paris   audit: make filet...
165
  	umode_t mode = (umode_t)val;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
166
167
168
  
  	if (unlikely(!ctx))
  		return 0;
5195d8e21   Eric Paris   audit: dynamicall...
169
  	list_for_each_entry(n, &ctx->names_list, list) {
84cb777e6   Richard Guy Briggs   audit: use macros...
170
  		if ((n->ino != AUDIT_INO_UNSET) &&
5195d8e21   Eric Paris   audit: dynamicall...
171
  		    ((n->mode & S_IFMT) == mode))
5ef30ee53   Eric Paris   audit: make filet...
172
173
  			return 1;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
174

5ef30ee53   Eric Paris   audit: make filet...
175
  	return 0;
8b67dca94   Al Viro   [PATCH] new predi...
176
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
177
178
179
180
181
182
183
184
185
186
187
  /*
   * 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_...
188
189
190
191
192
193
194
  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...
195
196
197
198
199
200
201
202
203
204
205
206
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
  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...
294
295
296
297
  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...
298
299
  {
  	struct audit_names *n;
b34b03932   Eric Paris   audit: complex in...
300
  	int rc;
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
301
   
b34b03932   Eric Paris   audit: complex in...
302
  	if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
303
  		rc = audit_uid_comparator(uid, f->op, name->uid);
b34b03932   Eric Paris   audit: complex in...
304
305
306
  		if (rc)
  			return rc;
  	}
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
307
   
b34b03932   Eric Paris   audit: complex in...
308
309
  	if (ctx) {
  		list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
310
311
312
313
314
315
316
  			rc = audit_uid_comparator(uid, f->op, n->uid);
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
b34b03932   Eric Paris   audit: complex in...
317

ca57ec0f0   Eric W. Biederman   audit: Add typesp...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  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...
335
336
337
338
339
340
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
02d86a568   Eric Paris   audit: allow inte...
341
342
343
344
345
346
  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...
347
  	switch (f->val) {
4a6633ed0   Peter Moody   audit: implement ...
348
  	/* process to file object comparisons */
02d86a568   Eric Paris   audit: allow inte...
349
  	case AUDIT_COMPARE_UID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
350
  		return audit_compare_uid(cred->uid, name, f, ctx);
c9fe685f7   Eric Paris   audit: allow inte...
351
  	case AUDIT_COMPARE_GID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
352
  		return audit_compare_gid(cred->gid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
353
  	case AUDIT_COMPARE_EUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
354
  		return audit_compare_uid(cred->euid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
355
  	case AUDIT_COMPARE_EGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
356
  		return audit_compare_gid(cred->egid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
357
  	case AUDIT_COMPARE_AUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
358
  		return audit_compare_uid(tsk->loginuid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
359
  	case AUDIT_COMPARE_SUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
360
  		return audit_compare_uid(cred->suid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
361
  	case AUDIT_COMPARE_SGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
362
  		return audit_compare_gid(cred->sgid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
363
  	case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
364
  		return audit_compare_uid(cred->fsuid, name, f, ctx);
4a6633ed0   Peter Moody   audit: implement ...
365
  	case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
366
  		return audit_compare_gid(cred->fsgid, name, f, ctx);
10d683608   Peter Moody   audit: comparison...
367
368
  	/* uid comparisons */
  	case AUDIT_COMPARE_UID_TO_AUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
369
  		return audit_uid_comparator(cred->uid, f->op, tsk->loginuid);
10d683608   Peter Moody   audit: comparison...
370
  	case AUDIT_COMPARE_UID_TO_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
371
  		return audit_uid_comparator(cred->uid, f->op, cred->euid);
10d683608   Peter Moody   audit: comparison...
372
  	case AUDIT_COMPARE_UID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
373
  		return audit_uid_comparator(cred->uid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
374
  	case AUDIT_COMPARE_UID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
375
  		return audit_uid_comparator(cred->uid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
376
377
  	/* auid comparisons */
  	case AUDIT_COMPARE_AUID_TO_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
378
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->euid);
10d683608   Peter Moody   audit: comparison...
379
  	case AUDIT_COMPARE_AUID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
380
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
381
  	case AUDIT_COMPARE_AUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
382
  		return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
383
384
  	/* euid comparisons */
  	case AUDIT_COMPARE_EUID_TO_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
385
  		return audit_uid_comparator(cred->euid, f->op, cred->suid);
10d683608   Peter Moody   audit: comparison...
386
  	case AUDIT_COMPARE_EUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
387
  		return audit_uid_comparator(cred->euid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
388
389
  	/* suid comparisons */
  	case AUDIT_COMPARE_SUID_TO_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
390
  		return audit_uid_comparator(cred->suid, f->op, cred->fsuid);
10d683608   Peter Moody   audit: comparison...
391
392
  	/* gid comparisons */
  	case AUDIT_COMPARE_GID_TO_EGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
393
  		return audit_gid_comparator(cred->gid, f->op, cred->egid);
10d683608   Peter Moody   audit: comparison...
394
  	case AUDIT_COMPARE_GID_TO_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
395
  		return audit_gid_comparator(cred->gid, f->op, cred->sgid);
10d683608   Peter Moody   audit: comparison...
396
  	case AUDIT_COMPARE_GID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
397
  		return audit_gid_comparator(cred->gid, f->op, cred->fsgid);
10d683608   Peter Moody   audit: comparison...
398
399
  	/* egid comparisons */
  	case AUDIT_COMPARE_EGID_TO_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
400
  		return audit_gid_comparator(cred->egid, f->op, cred->sgid);
10d683608   Peter Moody   audit: comparison...
401
  	case AUDIT_COMPARE_EGID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
402
  		return audit_gid_comparator(cred->egid, f->op, cred->fsgid);
10d683608   Peter Moody   audit: comparison...
403
404
  	/* sgid comparison */
  	case AUDIT_COMPARE_SGID_TO_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
405
  		return audit_gid_comparator(cred->sgid, f->op, cred->fsgid);
02d86a568   Eric Paris   audit: allow inte...
406
407
408
409
410
411
412
  	default:
  		WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug
  ");
  		return 0;
  	}
  	return 0;
  }
f368c07d7   Amy Griffis   [PATCH] audit: pa...
413
  /* Determine if any context name data matches a rule's watch data */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
f56298835   Tony Jones   audit: acquire cr...
415
416
417
418
419
420
   * 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
421
  static int audit_filter_rules(struct task_struct *tsk,
93315ed6d   Amy Griffis   [PATCH] audit str...
422
  			      struct audit_krule *rule,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  			      struct audit_context *ctx,
f368c07d7   Amy Griffis   [PATCH] audit: pa...
424
  			      struct audit_names *name,
f56298835   Tony Jones   audit: acquire cr...
425
426
  			      enum audit_state *state,
  			      bool task_creation)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  {
f56298835   Tony Jones   audit: acquire cr...
428
  	const struct cred *cred;
5195d8e21   Eric Paris   audit: dynamicall...
429
  	int i, need_sid = 1;
3dc7e3153   Darrel Goeddel   [PATCH] support f...
430
  	u32 sid;
8fae47705   Richard Guy Briggs   audit: add suppor...
431
  	unsigned int sessionid;
3dc7e3153   Darrel Goeddel   [PATCH] support f...
432

f56298835   Tony Jones   audit: acquire cr...
433
  	cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	for (i = 0; i < rule->field_count; i++) {
93315ed6d   Amy Griffis   [PATCH] audit str...
435
  		struct audit_field *f = &rule->fields[i];
5195d8e21   Eric Paris   audit: dynamicall...
436
  		struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
  		int result = 0;
f1dc4867f   Richard Guy Briggs   audit: anchor all...
438
  		pid_t pid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439

93315ed6d   Amy Griffis   [PATCH] audit str...
440
  		switch (f->type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
  		case AUDIT_PID:
fa2bea2f5   Paul Moore   audit: consistent...
442
  			pid = task_tgid_nr(tsk);
f1dc4867f   Richard Guy Briggs   audit: anchor all...
443
  			result = audit_comparator(pid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
  			break;
3c66251e5   Al Viro   [PATCH] add filte...
445
  		case AUDIT_PPID:
419c58f11   Alexander Viro   [PATCH] PPID filt...
446
447
  			if (ctx) {
  				if (!ctx->ppid)
c92cdeb45   Richard Guy Briggs   audit: convert PP...
448
  					ctx->ppid = task_ppid_nr(tsk);
3c66251e5   Al Viro   [PATCH] add filte...
449
  				result = audit_comparator(ctx->ppid, f->op, f->val);
419c58f11   Alexander Viro   [PATCH] PPID filt...
450
  			}
3c66251e5   Al Viro   [PATCH] add filte...
451
  			break;
34d99af52   Richard Guy Briggs   audit: implement ...
452
453
454
  		case AUDIT_EXE:
  			result = audit_exe_compare(tsk, rule->exe);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  		case AUDIT_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
456
  			result = audit_uid_comparator(cred->uid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
  			break;
  		case AUDIT_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
459
  			result = audit_uid_comparator(cred->euid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
461
  			break;
  		case AUDIT_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
462
  			result = audit_uid_comparator(cred->suid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
  			break;
  		case AUDIT_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
465
  			result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
467
  			break;
  		case AUDIT_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
468
  			result = audit_gid_comparator(cred->gid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
469
470
471
472
473
474
475
  			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
476
477
  			break;
  		case AUDIT_EGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
478
  			result = audit_gid_comparator(cred->egid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
479
480
481
482
483
484
485
  			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
486
487
  			break;
  		case AUDIT_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
488
  			result = audit_gid_comparator(cred->sgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
  			break;
  		case AUDIT_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
491
  			result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  			break;
8fae47705   Richard Guy Briggs   audit: add suppor...
493
494
495
496
  		case AUDIT_SESSIONID:
  			sessionid = audit_get_sessionid(current);
  			result = audit_comparator(sessionid, f->op, f->val);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
  		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)
db510fc5c   Richard Guy Briggs   audit: update AUD...
549
  				result = audit_comparator(name->ino, f->op, 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
  		case AUDIT_LOGINUID:
5c1390c9f   Mikhail Klementyev   audit: obsolete a...
592
  			result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
  			break;
780a7654c   Eric W. Biederman   audit: Make testi...
594
595
596
  		case AUDIT_LOGINUID_SET:
  			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
  			break;
3a6b9f85c   Darrel Goeddel   [PATCH] audit: re...
597
598
599
600
601
  		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...
602
603
604
605
606
  			/* 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...
607
  			if (f->lsm_rule) {
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
608
  				if (need_sid) {
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
609
  					security_task_getsecid(tsk, &sid);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
610
611
  					need_sid = 0;
  				}
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
612
  				result = security_audit_rule_match(sid, f->type,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
613
  				                                  f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
614
  				                                  f->lsm_rule,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
615
  				                                  ctx);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
616
  			}
3dc7e3153   Darrel Goeddel   [PATCH] support f...
617
  			break;
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
618
619
620
621
622
623
624
  		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...
625
  			if (f->lsm_rule) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
626
627
  				/* Find files that match */
  				if (name) {
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
628
  					result = security_audit_rule_match(
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
629
  					           name->osid, f->type, f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
630
  					           f->lsm_rule, ctx);
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
631
  				} else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
632
633
634
635
  					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...
636
637
638
639
640
641
  							++result;
  							break;
  						}
  					}
  				}
  				/* Find ipc objects that match */
a33e67510   Al Viro   sanitize audit_ip...
642
643
644
645
646
647
  				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...
648
649
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
652
653
654
  		case AUDIT_ARG0:
  		case AUDIT_ARG1:
  		case AUDIT_ARG2:
  		case AUDIT_ARG3:
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
655
  				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  			break;
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
657
658
659
660
  		case AUDIT_FILTERKEY:
  			/* ignore this field for filtering */
  			result = 1;
  			break;
55669bfa1   Al Viro   [PATCH] audit: AU...
661
662
663
  		case AUDIT_PERM:
  			result = audit_match_perm(ctx, f->val);
  			break;
8b67dca94   Al Viro   [PATCH] new predi...
664
665
666
  		case AUDIT_FILETYPE:
  			result = audit_match_filetype(ctx, f->val);
  			break;
02d86a568   Eric Paris   audit: allow inte...
667
668
669
  		case AUDIT_FIELD_COMPARE:
  			result = audit_field_compare(tsk, cred, f, ctx, name);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  		}
f56298835   Tony Jones   audit: acquire cr...
671
  		if (!result)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
  			return 0;
  	}
0590b9335   Al Viro   fixing audit rule...
674
675
676
677
678
679
680
681
682
683
  
  	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
684
  	switch (rule->action) {
66b12abc8   Paul Moore   audit: fix some h...
685
686
687
688
689
690
  	case AUDIT_NEVER:
  		*state = AUDIT_DISABLED;
  		break;
  	case AUDIT_ALWAYS:
  		*state = AUDIT_RECORD_CONTEXT;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
694
695
696
697
698
  	}
  	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...
699
  static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
701
702
703
704
  {
  	struct audit_entry *e;
  	enum audit_state   state;
  
  	rcu_read_lock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
705
  	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
f56298835   Tony Jones   audit: acquire cr...
706
707
  		if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
  				       &state, true)) {
e048e02c8   Al Viro   make sure that fi...
708
709
  			if (state == AUDIT_RECORD_CONTEXT)
  				*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
712
713
714
715
716
  			rcu_read_unlock();
  			return state;
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
a3c549311   Andy Lutomirski   auditsc: audit_kr...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
  static int audit_in_mask(const struct audit_krule *rule, unsigned long val)
  {
  	int word, bit;
  
  	if (val > 0xffffffff)
  		return false;
  
  	word = AUDIT_WORD(val);
  	if (word >= AUDIT_BITMASK_SIZE)
  		return false;
  
  	bit = AUDIT_BIT(val);
  
  	return rule->mask[word] & bit;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
  /* 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...
734
   * also not high enough that we already know we have to write an audit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
735
   * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
737
738
739
740
741
   */
  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...
742
  	enum audit_state state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743

351bb7225   David Woodhouse   AUDIT: Fix compil...
744
  	if (audit_pid && tsk->tgid == audit_pid)
f7056d64a   David Woodhouse   AUDIT: Really exe...
745
  		return AUDIT_DISABLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
746
  	rcu_read_lock();
c38964959   David Woodhouse   AUDIT: Speed up a...
747
  	if (!list_empty(list)) {
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
748
  		list_for_each_entry_rcu(e, list, list) {
a3c549311   Andy Lutomirski   auditsc: audit_kr...
749
  			if (audit_in_mask(&e->rule, ctx->major) &&
f368c07d7   Amy Griffis   [PATCH] audit: pa...
750
  			    audit_filter_rules(tsk, &e->rule, ctx, NULL,
f56298835   Tony Jones   audit: acquire cr...
751
  					       &state, false)) {
f368c07d7   Amy Griffis   [PATCH] audit: pa...
752
  				rcu_read_unlock();
0590b9335   Al Viro   fixing audit rule...
753
  				ctx->current_state = state;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
754
755
756
757
758
759
760
  				return state;
  			}
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
5195d8e21   Eric Paris   audit: dynamicall...
761
762
763
764
765
766
767
  /*
   * 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) {
5195d8e21   Eric Paris   audit: dynamicall...
768
769
770
771
  	int h = audit_hash_ino((u32)n->ino);
  	struct list_head *list = &audit_inode_hash[h];
  	struct audit_entry *e;
  	enum audit_state state;
5195d8e21   Eric Paris   audit: dynamicall...
772
773
774
775
  	if (list_empty(list))
  		return 0;
  
  	list_for_each_entry_rcu(e, list, list) {
a3c549311   Andy Lutomirski   auditsc: audit_kr...
776
  		if (audit_in_mask(&e->rule, ctx->major) &&
5195d8e21   Eric Paris   audit: dynamicall...
777
778
779
780
781
782
783
784
785
786
  		    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...
787
   * collected during syscall processing.  We only check rules in sublists at hash
5195d8e21   Eric Paris   audit: dynamicall...
788
   * buckets applicable to the inode numbers in audit_names.
f368c07d7   Amy Griffis   [PATCH] audit: pa...
789
790
   * Regarding audit_state, same rules apply as for audit_filter_syscall().
   */
0590b9335   Al Viro   fixing audit rule...
791
  void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
f368c07d7   Amy Griffis   [PATCH] audit: pa...
792
  {
5195d8e21   Eric Paris   audit: dynamicall...
793
  	struct audit_names *n;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
794
795
  
  	if (audit_pid && tsk->tgid == audit_pid)
0590b9335   Al Viro   fixing audit rule...
796
  		return;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
797
798
  
  	rcu_read_lock();
f368c07d7   Amy Griffis   [PATCH] audit: pa...
799

5195d8e21   Eric Paris   audit: dynamicall...
800
801
802
  	list_for_each_entry(n, &ctx->names_list, list) {
  		if (audit_filter_inode_name(tsk, n, ctx))
  			break;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
803
804
  	}
  	rcu_read_unlock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
805
  }
4a3eb726d   Richard Guy Briggs   audit: rename the...
806
807
  /* Transfer the audit context pointer to the caller, clearing it in the tsk's struct */
  static inline struct audit_context *audit_take_context(struct task_struct *tsk,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
  						      int return_valid,
6d208da89   Paul Moore   audit: Fix possib...
809
  						      long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810
811
  {
  	struct audit_context *context = tsk->audit_context;
56179a6ec   Eric Paris   audit: drop some ...
812
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
814
  		return NULL;
  	context->return_valid = return_valid;
f701b75ed   Eric Paris   [AUDIT] return EI...
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
  
  	/*
  	 * 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
833

0590b9335   Al Viro   fixing audit rule...
834
835
836
  	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
837
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
839
840
  	tsk->audit_context = NULL;
  	return context;
  }
3f1c82502   William Roberts   audit: Audit proc...
841
842
843
844
845
846
  static inline void audit_proctitle_free(struct audit_context *context)
  {
  	kfree(context->proctitle.value);
  	context->proctitle.value = NULL;
  	context->proctitle.len = 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
  static inline void audit_free_names(struct audit_context *context)
  {
5195d8e21   Eric Paris   audit: dynamicall...
849
  	struct audit_names *n, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850

5195d8e21   Eric Paris   audit: dynamicall...
851
852
  	list_for_each_entry_safe(n, next, &context->names_list, list) {
  		list_del(&n->list);
55422d0bd   Paul Moore   audit: replace ge...
853
854
  		if (n->name)
  			putname(n->name);
5195d8e21   Eric Paris   audit: dynamicall...
855
856
  		if (n->should_free)
  			kfree(n);
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
857
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
  	context->name_count = 0;
44707fdf5   Jan Blunck   d_path: Use struc...
859
860
861
  	path_put(&context->pwd);
  	context->pwd.dentry = NULL;
  	context->pwd.mnt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
865
866
867
868
869
870
871
  }
  
  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...
872
873
874
875
  	while ((aux = context->aux_pids)) {
  		context->aux_pids = aux->next;
  		kfree(aux);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
878
879
  static inline struct audit_context *audit_alloc_context(enum audit_state state)
  {
  	struct audit_context *context;
17c6ee707   Rakib Mullick   auditsc: Use kzal...
880
881
  	context = kzalloc(sizeof(*context), GFP_KERNEL);
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  		return NULL;
e2c5adc88   Andrew Morton   auditsc: remove a...
883
884
  	context->state = state;
  	context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
916d75761   Al Viro   Fix rule eviction...
885
  	INIT_LIST_HEAD(&context->killed_trees);
5195d8e21   Eric Paris   audit: dynamicall...
886
  	INIT_LIST_HEAD(&context->names_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
888
  	return context;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
889
890
891
892
893
  /**
   * 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
894
895
   * 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...
896
897
   * needed.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
899
900
901
  int audit_alloc(struct task_struct *tsk)
  {
  	struct audit_context *context;
  	enum audit_state     state;
e048e02c8   Al Viro   make sure that fi...
902
  	char *key = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903

b593d384e   Eric Paris   [AUDIT] create co...
904
  	if (likely(!audit_ever_enabled))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
  		return 0; /* Return if not auditing. */
e048e02c8   Al Viro   make sure that fi...
906
  	state = audit_filter_task(tsk, &key);
d48d80512   Oleg Nesterov   audit_alloc: clea...
907
908
  	if (state == AUDIT_DISABLED) {
  		clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
  		return 0;
d48d80512   Oleg Nesterov   audit_alloc: clea...
910
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
911
912
  
  	if (!(context = audit_alloc_context(state))) {
e048e02c8   Al Viro   make sure that fi...
913
  		kfree(key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
915
916
  		audit_log_lost("out of memory in audit_alloc");
  		return -ENOMEM;
  	}
e048e02c8   Al Viro   make sure that fi...
917
  	context->filterkey = key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
920
921
922
923
924
925
  	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 ...
926
927
928
929
930
931
  	audit_free_names(context);
  	unroll_tree_refs(context, NULL, 0);
  	free_tree_refs(context);
  	audit_free_aux(context);
  	kfree(context->filterkey);
  	kfree(context->sockaddr);
3f1c82502   William Roberts   audit: Audit proc...
932
  	audit_proctitle_free(context);
c62d773a3   Al Viro   audit: no nested ...
933
  	kfree(context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
  }
e54dc2431   Amy Griffis   [PATCH] audit sig...
935
  static int audit_log_pid_context(struct audit_context *context, pid_t pid,
cca080d9b   Eric W. Biederman   userns: Convert a...
936
  				 kuid_t auid, kuid_t uid, unsigned int sessionid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
937
  				 u32 sid, char *comm)
e54dc2431   Amy Griffis   [PATCH] audit sig...
938
939
  {
  	struct audit_buffer *ab;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
940
  	char *ctx = NULL;
e54dc2431   Amy Griffis   [PATCH] audit sig...
941
942
943
944
945
  	u32 len;
  	int rc = 0;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
  	if (!ab)
6246ccab9   Eric Paris   [AUDIT] do not pa...
946
  		return rc;
e54dc2431   Amy Griffis   [PATCH] audit sig...
947

e1760bd5f   Eric W. Biederman   userns: Convert t...
948
949
  	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...
950
  			 from_kuid(&init_user_ns, uid), sessionid);
ad395abec   Eric Paris   Audit: do not pri...
951
952
953
954
955
956
957
958
  	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...
959
  	}
c2a7780ef   Eric Paris   [AUDIT] collect u...
960
961
  	audit_log_format(ab, " ocomm=");
  	audit_log_untrustedstring(ab, comm);
e54dc2431   Amy Griffis   [PATCH] audit sig...
962
  	audit_log_end(ab);
e54dc2431   Amy Griffis   [PATCH] audit sig...
963
964
965
  
  	return rc;
  }
43761473c   Paul Moore   audit: fix a doub...
966
967
  static void audit_log_execve_info(struct audit_context *context,
  				  struct audit_buffer **ab)
bdf4c48af   Peter Zijlstra   audit: rework exe...
968
  {
43761473c   Paul Moore   audit: fix a doub...
969
970
971
972
  	long len_max;
  	long len_rem;
  	long len_full;
  	long len_buf;
8443075ea   Richard Guy Briggs   audit: tame initi...
973
  	long len_abuf = 0;
43761473c   Paul Moore   audit: fix a doub...
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  	long len_tmp;
  	bool require_data;
  	bool encode;
  	unsigned int iter;
  	unsigned int arg;
  	char *buf_head;
  	char *buf;
  	const char __user *p = (const char __user *)current->mm->arg_start;
  
  	/* NOTE: this buffer needs to be large enough to hold all the non-arg
  	 *       data we put in the audit record for this argument (see the
  	 *       code below) ... at this point in time 96 is plenty */
  	char abuf[96];
  
  	/* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the
  	 *       current value of 7500 is not as important as the fact that it
  	 *       is less than 8k, a setting of 7500 gives us plenty of wiggle
  	 *       room if we go over a little bit in the logging below */
  	WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500);
  	len_max = MAX_EXECVE_AUDIT_LEN;
  
  	/* scratch buffer to hold the userspace args */
  	buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
  	if (!buf_head) {
  		audit_panic("out of memory for argv string");
  		return;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1000
  	}
43761473c   Paul Moore   audit: fix a doub...
1001
  	buf = buf_head;
040b3a2df   Peter Zijlstra   audit: fix two bu...
1002

43761473c   Paul Moore   audit: fix a doub...
1003
  	audit_log_format(*ab, "argc=%d", context->execve.argc);
040b3a2df   Peter Zijlstra   audit: fix two bu...
1004

43761473c   Paul Moore   audit: fix a doub...
1005
1006
1007
1008
1009
1010
1011
  	len_rem = len_max;
  	len_buf = 0;
  	len_full = 0;
  	require_data = true;
  	encode = false;
  	iter = 0;
  	arg = 0;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1012
  	do {
43761473c   Paul Moore   audit: fix a doub...
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
  		/* NOTE: we don't ever want to trust this value for anything
  		 *       serious, but the audit record format insists we
  		 *       provide an argument length for really long arguments,
  		 *       e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but
  		 *       to use strncpy_from_user() to obtain this value for
  		 *       recording in the log, although we don't use it
  		 *       anywhere here to avoid a double-fetch problem */
  		if (len_full == 0)
  			len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1;
  
  		/* read more data from userspace */
  		if (require_data) {
  			/* can we make more room in the buffer? */
  			if (buf != buf_head) {
  				memmove(buf_head, buf, len_buf);
  				buf = buf_head;
  			}
  
  			/* fetch as much as we can of the argument */
  			len_tmp = strncpy_from_user(&buf_head[len_buf], p,
  						    len_max - len_buf);
  			if (len_tmp == -EFAULT) {
  				/* unable to copy from userspace */
  				send_sig(SIGKILL, current, 0);
  				goto out;
  			} else if (len_tmp == (len_max - len_buf)) {
  				/* buffer is not large enough */
  				require_data = true;
  				/* NOTE: if we are going to span multiple
  				 *       buffers force the encoding so we stand
  				 *       a chance at a sane len_full value and
  				 *       consistent record encoding */
  				encode = true;
  				len_full = len_full * 2;
  				p += len_tmp;
  			} else {
  				require_data = false;
  				if (!encode)
  					encode = audit_string_contains_control(
  								buf, len_tmp);
  				/* try to use a trusted value for len_full */
  				if (len_full < len_max)
  					len_full = (encode ?
  						    len_tmp * 2 : len_tmp);
  				p += len_tmp + 1;
  			}
  			len_buf += len_tmp;
  			buf_head[len_buf] = '\0';
bdf4c48af   Peter Zijlstra   audit: rework exe...
1061

43761473c   Paul Moore   audit: fix a doub...
1062
1063
  			/* length of the buffer in the audit record? */
  			len_abuf = (encode ? len_buf * 2 : len_buf + 2);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1064
  		}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1065

43761473c   Paul Moore   audit: fix a doub...
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
  		/* write as much as we can to the audit log */
  		if (len_buf > 0) {
  			/* NOTE: some magic numbers here - basically if we
  			 *       can't fit a reasonable amount of data into the
  			 *       existing audit buffer, flush it and start with
  			 *       a new buffer */
  			if ((sizeof(abuf) + 8) > len_rem) {
  				len_rem = len_max;
  				audit_log_end(*ab);
  				*ab = audit_log_start(context,
  						      GFP_KERNEL, AUDIT_EXECVE);
  				if (!*ab)
  					goto out;
  			}
bdf4c48af   Peter Zijlstra   audit: rework exe...
1080

43761473c   Paul Moore   audit: fix a doub...
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
  			/* create the non-arg portion of the arg record */
  			len_tmp = 0;
  			if (require_data || (iter > 0) ||
  			    ((len_abuf + sizeof(abuf)) > len_rem)) {
  				if (iter == 0) {
  					len_tmp += snprintf(&abuf[len_tmp],
  							sizeof(abuf) - len_tmp,
  							" a%d_len=%lu",
  							arg, len_full);
  				}
  				len_tmp += snprintf(&abuf[len_tmp],
  						    sizeof(abuf) - len_tmp,
  						    " a%d[%d]=", arg, iter++);
  			} else
  				len_tmp += snprintf(&abuf[len_tmp],
  						    sizeof(abuf) - len_tmp,
  						    " a%d=", arg);
  			WARN_ON(len_tmp >= sizeof(abuf));
  			abuf[sizeof(abuf) - 1] = '\0';
  
  			/* log the arg in the audit record */
  			audit_log_format(*ab, "%s", abuf);
  			len_rem -= len_tmp;
  			len_tmp = len_buf;
  			if (encode) {
  				if (len_abuf > len_rem)
  					len_tmp = len_rem / 2; /* encoding */
  				audit_log_n_hex(*ab, buf, len_tmp);
  				len_rem -= len_tmp * 2;
  				len_abuf -= len_tmp * 2;
  			} else {
  				if (len_abuf > len_rem)
  					len_tmp = len_rem - 2; /* quotes */
  				audit_log_n_string(*ab, buf, len_tmp);
  				len_rem -= len_tmp + 2;
  				/* don't subtract the "2" because we still need
  				 * to add quotes to the remaining string */
  				len_abuf -= len_tmp;
  			}
  			len_buf -= len_tmp;
  			buf += len_tmp;
  		}
bdf4c48af   Peter Zijlstra   audit: rework exe...
1123

43761473c   Paul Moore   audit: fix a doub...
1124
1125
1126
1127
1128
1129
1130
1131
1132
  		/* ready to move to the next argument? */
  		if ((len_buf == 0) && !require_data) {
  			arg++;
  			iter = 0;
  			len_full = 0;
  			require_data = true;
  			encode = false;
  		}
  	} while (arg < context->execve.argc);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1133

43761473c   Paul Moore   audit: fix a doub...
1134
  	/* NOTE: the caller handles the final audit_log_end() call */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1135

43761473c   Paul Moore   audit: fix a doub...
1136
1137
  out:
  	kfree(buf_head);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1138
  }
a33e67510   Al Viro   sanitize audit_ip...
1139
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  {
  	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...
1156
1157
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1158
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
cca080d9b   Eric W. Biederman   userns: Convert a...
1159
1160
1161
  				 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...
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
  		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...
1173
1174
1175
1176
  		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...
1177
1178
  			if (unlikely(!ab))
  				return;
e816f370c   Al Viro   sanitize audit_ip...
1179
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1180
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1181
1182
1183
1184
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
e816f370c   Al Viro   sanitize audit_ip...
1185
  		}
a33e67510   Al Viro   sanitize audit_ip...
1186
  		break; }
564f6993f   Al Viro   sanitize audit_mq...
1187
1188
  	case AUDIT_MQ_OPEN: {
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1189
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1190
1191
1192
1193
1194
1195
1196
  			"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...
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
  	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...
1207
1208
1209
1210
1211
  	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...
1212
1213
1214
1215
1216
1217
1218
1219
1220
  	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...
1221
1222
1223
1224
1225
1226
  	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
1227
1228
1229
1230
  	case AUDIT_MMAP: {
  		audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
  				 context->mmap.flags);
  		break; }
d9cfea91e   Richard Guy Briggs   audit: move audit...
1231
1232
1233
  	case AUDIT_EXECVE: {
  		audit_log_execve_info(context, &ab);
  		break; }
f3298dc4f   Al Viro   sanitize audit_so...
1234
1235
1236
  	}
  	audit_log_end(ab);
  }
3f1c82502   William Roberts   audit: Audit proc...
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
  static inline int audit_proctitle_rtrim(char *proctitle, int len)
  {
  	char *end = proctitle + len - 1;
  	while (end > proctitle && !isprint(*end))
  		end--;
  
  	/* catch the case where proctitle is only 1 non-print character */
  	len = end - proctitle + 1;
  	len -= isprint(proctitle[len-1]) == 0;
  	return len;
  }
  
  static void audit_log_proctitle(struct task_struct *tsk,
  			 struct audit_context *context)
  {
  	int res;
  	char *buf;
  	char *msg = "(null)";
  	int len = strlen(msg);
  	struct audit_buffer *ab;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE);
  	if (!ab)
  		return;	/* audit_panic or being filtered */
  
  	audit_log_format(ab, "proctitle=");
  
  	/* Not  cached */
  	if (!context->proctitle.value) {
  		buf = kmalloc(MAX_PROCTITLE_AUDIT_LEN, GFP_KERNEL);
  		if (!buf)
  			goto out;
  		/* Historically called this from procfs naming */
  		res = get_cmdline(tsk, buf, MAX_PROCTITLE_AUDIT_LEN);
  		if (res == 0) {
  			kfree(buf);
  			goto out;
  		}
  		res = audit_proctitle_rtrim(buf, res);
  		if (res == 0) {
  			kfree(buf);
  			goto out;
  		}
  		context->proctitle.value = buf;
  		context->proctitle.len = res;
  	}
  	msg = context->proctitle.value;
  	len = context->proctitle.len;
  out:
  	audit_log_n_untrustedstring(ab, msg, len);
  	audit_log_end(ab);
  }
e495149b1   Al Viro   [PATCH] drop gfp_...
1289
  static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1290
  {
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1291
  	int i, call_panic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1292
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1293
  	struct audit_aux_data *aux;
5195d8e21   Eric Paris   audit: dynamicall...
1294
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1295

e495149b1   Al Viro   [PATCH] drop gfp_...
1296
  	/* tsk == current */
3f2792ffb   Al Viro   [PATCH] take fill...
1297
  	context->personality = tsk->personality;
e495149b1   Al Viro   [PATCH] drop gfp_...
1298
1299
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
1301
  	if (!ab)
  		return;		/* audit_panic has been called */
bccf6ae08   David Woodhouse   AUDIT: Unify auid...
1302
1303
  	audit_log_format(ab, "arch=%x syscall=%d",
  			 context->arch, context->major);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
1305
1306
  	if (context->personality != PER_LINUX)
  		audit_log_format(ab, " per=%lx", context->personality);
  	if (context->return_valid)
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1307
  		audit_log_format(ab, " success=%s exit=%ld",
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1308
1309
  				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
  				 context->return_code);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1310

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1311
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1312
1313
1314
1315
1316
1317
  			 " 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...
1318

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

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

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

3fc689e96   Eric Paris   Any time fcaps or...
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
  		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
1343
1344
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1346
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1347
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1348

157cf649a   Al Viro   sanitize audit_fd...
1349
1350
1351
1352
1353
1354
1355
1356
  	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 ...
1357
1358
1359
1360
1361
1362
1363
1364
1365
  	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...
1366
1367
  	for (aux = context->aux_pids; aux; aux = aux->next) {
  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1368
1369
1370
  
  		for (i = 0; i < axs->pid_count; i++)
  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1371
1372
  						  axs->target_auid[i],
  						  axs->target_uid[i],
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1373
  						  axs->target_sessionid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1374
1375
  						  axs->target_sid[i],
  						  axs->target_comm[i]))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1376
  				call_panic = 1;
a5cb013da   Al Viro   [PATCH] auditing ...
1377
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1378
1379
  	if (context->target_pid &&
  	    audit_log_pid_context(context, context->target_pid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1380
  				  context->target_auid, context->target_uid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1381
  				  context->target_sessionid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1382
  				  context->target_sid, context->target_comm))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1383
  			call_panic = 1;
44707fdf5   Jan Blunck   d_path: Use struc...
1384
  	if (context->pwd.dentry && context->pwd.mnt) {
e495149b1   Al Viro   [PATCH] drop gfp_...
1385
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1386
  		if (ab) {
0b7a0fdb2   Steve Grubb   audit: fix whites...
1387
  			audit_log_d_path(ab, "cwd=", &context->pwd);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1388
1389
1390
  			audit_log_end(ab);
  		}
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1391

5195d8e21   Eric Paris   audit: dynamicall...
1392
  	i = 0;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1393
1394
1395
  	list_for_each_entry(n, &context->names_list, list) {
  		if (n->hidden)
  			continue;
b24a30a73   Eric Paris   audit: fix event ...
1396
  		audit_log_name(context, n, NULL, i++, &call_panic);
79f6530cb   Jeff Layton   audit: fix mq_ope...
1397
  	}
c0641f28d   Eric Paris   [AUDIT] Add End o...
1398

3f1c82502   William Roberts   audit: Audit proc...
1399
  	audit_log_proctitle(tsk, context);
c0641f28d   Eric Paris   [AUDIT] Add End o...
1400
1401
1402
1403
  	/* 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...
1404
1405
  	if (call_panic)
  		audit_panic("error converting sid to string");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1406
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1407
1408
1409
1410
  /**
   * audit_free - free a per-task audit context
   * @tsk: task whose audit context block to free
   *
fa84cb935   Al Viro   [PATCH] move call...
1411
   * Called from copy_process and do_exit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1412
   */
a4ff8dba7   Eric Paris   audit: inline aud...
1413
  void __audit_free(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
1415
  {
  	struct audit_context *context;
4a3eb726d   Richard Guy Briggs   audit: rename the...
1416
  	context = audit_take_context(tsk, 0, 0);
56179a6ec   Eric Paris   audit: drop some ...
1417
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
1419
1420
  		return;
  
  	/* Check for system calls that do not go through the exit
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1421
1422
  	 * 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...
1423
  	 * in the context of the idle thread */
e495149b1   Al Viro   [PATCH] drop gfp_...
1424
  	/* that can happen only if we are called from do_exit() */
0590b9335   Al Viro   fixing audit rule...
1425
  	if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
e495149b1   Al Viro   [PATCH] drop gfp_...
1426
  		audit_log_exit(context, tsk);
916d75761   Al Viro   Fix rule eviction...
1427
1428
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
1431
  
  	audit_free_context(context);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1432
1433
  /**
   * audit_syscall_entry - fill in an audit record at syscall entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1434
1435
1436
1437
1438
1439
1440
   * @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
1441
1442
1443
1444
1445
   * 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...
1446
1447
   * be written).
   */
b4f0d3755   Richard Guy Briggs   audit: x86: drop ...
1448
1449
  void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
  			   unsigned long a3, unsigned long a4)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
  {
5411be59d   Al Viro   [PATCH] drop task...
1451
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
  	struct audit_context *context = tsk->audit_context;
  	enum audit_state     state;
56179a6ec   Eric Paris   audit: drop some ...
1454
  	if (!context)
86a1c34a9   Roland McGrath   x86_64 syscall au...
1455
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1456

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1457
1458
1459
1460
  	BUG_ON(context->in_syscall || context->name_count);
  
  	if (!audit_enabled)
  		return;
4a99854c5   Richard Guy Briggs   audit: __audit_sy...
1461
  	context->arch	    = syscall_get_arch();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1462
1463
1464
1465
1466
1467
1468
  	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...
1469
  	context->dummy = !audit_n_rules;
0590b9335   Al Viro   fixing audit rule...
1470
1471
  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
  		context->prio = 0;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1472
  		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
0590b9335   Al Viro   fixing audit rule...
1473
  	}
56179a6ec   Eric Paris   audit: drop some ...
1474
  	if (state == AUDIT_DISABLED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1475
  		return;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1476
  	context->serial     = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1477
1478
  	context->ctime      = CURRENT_TIME;
  	context->in_syscall = 1;
0590b9335   Al Viro   fixing audit rule...
1479
  	context->current_state  = state;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1480
  	context->ppid       = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1481
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1482
1483
  /**
   * audit_syscall_exit - deallocate audit context after a system call
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1484
1485
   * @success: success value of the syscall
   * @return_code: return value of the syscall
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1486
1487
   *
   * Tear down after system call.  If the audit context has been marked as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
   * auditable (either because of the AUDIT_RECORD_CONTEXT state from
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1489
   * filtering, or because some other part of the kernel wrote an audit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490
   * message), then write out the syscall information.  In call cases,
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1491
1492
   * free the names stored from getname().
   */
d7e7528bc   Eric Paris   Audit: push audit...
1493
  void __audit_syscall_exit(int success, long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
  {
5411be59d   Al Viro   [PATCH] drop task...
1495
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
  	struct audit_context *context;
d7e7528bc   Eric Paris   Audit: push audit...
1497
1498
1499
1500
  	if (success)
  		success = AUDITSC_SUCCESS;
  	else
  		success = AUDITSC_FAILURE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1501

4a3eb726d   Richard Guy Briggs   audit: rename the...
1502
  	context = audit_take_context(tsk, success, return_code);
56179a6ec   Eric Paris   audit: drop some ...
1503
  	if (!context)
97e94c453   Al Viro   [PATCH] no need t...
1504
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505

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

916d75761   Al Viro   Fix rule eviction...
1512
1513
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
c62d773a3   Al Viro   audit: no nested ...
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
  	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
1527
  	}
c62d773a3   Al Viro   audit: no nested ...
1528
  	tsk->audit_context = context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1530
1531
1532
1533
1534
1535
1536
  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 ...
1537
  	if (likely(hlist_empty(&inode->i_fsnotify_marks)))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
  		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))) {
f952d10ff   Richard Guy Briggs   audit: Use more c...
1550
1551
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
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
1578
1579
  		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(;;) {
3b362157b   David Howells   VFS: audit: d_bac...
1580
  		struct inode *inode = d_backing_inode(d);
e61ce8673   Eric Paris   fsnotify: rename ...
1581
  		if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_marks))) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
  			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 */
f952d10ff   Richard Guy Briggs   audit: Use more c...
1610
1611
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1612
1613
1614
1615
1616
1617
1618
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
  #endif
  }
78e2e802a   Jeff Layton   audit: add a new ...
1619
1620
  static struct audit_names *audit_alloc_name(struct audit_context *context,
  						unsigned char type)
5195d8e21   Eric Paris   audit: dynamicall...
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
  {
  	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;
  	}
84cb777e6   Richard Guy Briggs   audit: use macros...
1633
  	aname->ino = AUDIT_INO_UNSET;
78e2e802a   Jeff Layton   audit: add a new ...
1634
  	aname->type = type;
5195d8e21   Eric Paris   audit: dynamicall...
1635
1636
1637
  	list_add_tail(&aname->list, &context->names_list);
  
  	context->name_count++;
5195d8e21   Eric Paris   audit: dynamicall...
1638
1639
  	return aname;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1640
  /**
7ac86265d   Jeff Layton   audit: allow audi...
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
   * 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;
55422d0bd   Paul Moore   audit: replace ge...
1657
1658
  		if (n->name->uptr == uptr) {
  			n->name->refcnt++;
7ac86265d   Jeff Layton   audit: allow audi...
1659
  			return n->name;
55422d0bd   Paul Moore   audit: replace ge...
1660
  		}
7ac86265d   Jeff Layton   audit: allow audi...
1661
1662
1663
1664
1665
  	}
  	return NULL;
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1666
1667
1668
1669
1670
1671
   * 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...
1672
  void __audit_getname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
1674
  {
  	struct audit_context *context = current->audit_context;
5195d8e21   Eric Paris   audit: dynamicall...
1675
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676

55422d0bd   Paul Moore   audit: replace ge...
1677
  	if (!context->in_syscall)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
  		return;
91a27b2a7   Jeff Layton   vfs: define struc...
1679

78e2e802a   Jeff Layton   audit: add a new ...
1680
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1681
1682
1683
1684
1685
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
adb5c2473   Jeff Layton   audit: make audit...
1686
  	name->aname = n;
55422d0bd   Paul Moore   audit: replace ge...
1687
  	name->refcnt++;
5195d8e21   Eric Paris   audit: dynamicall...
1688

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1689
1690
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1692
  /**
bfcec7087   Jeff Layton   audit: set the na...
1693
   * __audit_inode - store the inode and device from a lookup
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1694
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1695
   * @dentry: dentry being audited
79f6530cb   Jeff Layton   audit: fix mq_ope...
1696
   * @flags: attributes for this particular entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1697
   */
adb5c2473   Jeff Layton   audit: make audit...
1698
  void __audit_inode(struct filename *name, const struct dentry *dentry,
79f6530cb   Jeff Layton   audit: fix mq_ope...
1699
  		   unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1700
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1701
  	struct audit_context *context = current->audit_context;
d6335d77a   Andreas Gruenbacher   security: Make in...
1702
  	struct inode *inode = d_backing_inode(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1703
  	struct audit_names *n;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1704
  	bool parent = flags & AUDIT_INODE_PARENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1705
1706
1707
  
  	if (!context->in_syscall)
  		return;
5195d8e21   Eric Paris   audit: dynamicall...
1708

9cec9d68a   Jeff Layton   audit: no need to...
1709
1710
  	if (!name)
  		goto out_alloc;
adb5c2473   Jeff Layton   audit: make audit...
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
  	/*
  	 * 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...
1726
  	list_for_each_entry_reverse(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
  		if (n->ino) {
  			/* valid inode number, use that for the comparison */
  			if (n->ino != inode->i_ino ||
  			    n->dev != inode->i_sb->s_dev)
  				continue;
  		} else if (n->name) {
  			/* inode number has not been set, check the name */
  			if (strcmp(n->name->name, name->name))
  				continue;
  		} else
  			/* no inode and no name (?!) ... this is odd ... */
bfcec7087   Jeff Layton   audit: set the na...
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
  			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
1749
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1750

9cec9d68a   Jeff Layton   audit: no need to...
1751
  out_alloc:
4a9284360   Paul Moore   audit: correctly ...
1752
1753
  	/* unable to find an entry with both a matching name and type */
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1754
1755
  	if (!n)
  		return;
fcf22d826   Paul Moore   audit: create pri...
1756
  	if (name) {
fd3522fdc   Paul Moore   audit: enable fil...
1757
  		n->name = name;
55422d0bd   Paul Moore   audit: replace ge...
1758
  		name->refcnt++;
fcf22d826   Paul Moore   audit: create pri...
1759
  	}
4a9284360   Paul Moore   audit: correctly ...
1760

5195d8e21   Eric Paris   audit: dynamicall...
1761
  out:
bfcec7087   Jeff Layton   audit: set the na...
1762
  	if (parent) {
91a27b2a7   Jeff Layton   vfs: define struc...
1763
  		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
bfcec7087   Jeff Layton   audit: set the na...
1764
  		n->type = AUDIT_TYPE_PARENT;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1765
1766
  		if (flags & AUDIT_INODE_HIDDEN)
  			n->hidden = true;
bfcec7087   Jeff Layton   audit: set the na...
1767
1768
1769
1770
  	} else {
  		n->name_len = AUDIT_NAME_FULL;
  		n->type = AUDIT_TYPE_NORMAL;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1771
  	handle_path(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1772
  	audit_copy_inode(n, dentry, inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1773
  }
9f45f5bf3   Al Viro   new helper: audit...
1774
1775
1776
1777
  void __audit_file(const struct file *file)
  {
  	__audit_inode(NULL, file->f_path.dentry, 0);
  }
73241ccca   Amy Griffis   [PATCH] Collect m...
1778
  /**
c43a25abb   Jeff Layton   audit: reverse ar...
1779
   * __audit_inode_child - collect inode info for created/removed objects
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1780
   * @parent: inode of dentry parent
c43a25abb   Jeff Layton   audit: reverse ar...
1781
   * @dentry: dentry being audited
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1782
   * @type:   AUDIT_TYPE_* value that we're looking for
73241ccca   Amy Griffis   [PATCH] Collect m...
1783
1784
1785
1786
1787
1788
1789
1790
1791
   *
   * 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.
   */
d6335d77a   Andreas Gruenbacher   security: Make in...
1792
  void __audit_inode_child(struct inode *parent,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1793
1794
  			 const struct dentry *dentry,
  			 const unsigned char type)
73241ccca   Amy Griffis   [PATCH] Collect m...
1795
  {
73241ccca   Amy Griffis   [PATCH] Collect m...
1796
  	struct audit_context *context = current->audit_context;
d6335d77a   Andreas Gruenbacher   security: Make in...
1797
  	struct inode *inode = d_backing_inode(dentry);
cccc6bba3   Al Viro   Lose the first ar...
1798
  	const char *dname = dentry->d_name.name;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1799
  	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
73241ccca   Amy Griffis   [PATCH] Collect m...
1800
1801
1802
  
  	if (!context->in_syscall)
  		return;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1803
1804
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1805

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1806
  	/* look for a parent entry first */
5195d8e21   Eric Paris   audit: dynamicall...
1807
  	list_for_each_entry(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
1808
1809
1810
  		if (!n->name ||
  		    (n->type != AUDIT_TYPE_PARENT &&
  		     n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
1811
  			continue;
57c59f583   Paul Moore   audit: fix filena...
1812
1813
1814
1815
1816
  		if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
  		    !audit_compare_dname_path(dname,
  					      n->name->name, n->name_len)) {
  			if (n->type == AUDIT_TYPE_UNKNOWN)
  				n->type = AUDIT_TYPE_PARENT;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1817
1818
  			found_parent = n;
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1819
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1820
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1821

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1822
  	/* is there a matching child entry? */
5195d8e21   Eric Paris   audit: dynamicall...
1823
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1824
  		/* can only match entries that have a name */
57c59f583   Paul Moore   audit: fix filena...
1825
1826
  		if (!n->name ||
  		    (n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
1827
  			continue;
91a27b2a7   Jeff Layton   vfs: define struc...
1828
1829
  		if (!strcmp(dname, n->name->name) ||
  		    !audit_compare_dname_path(dname, n->name->name,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1830
1831
  						found_parent ?
  						found_parent->name_len :
e3d6b07b8   Jeff Layton   audit: optimize a...
1832
  						AUDIT_NAME_FULL)) {
57c59f583   Paul Moore   audit: fix filena...
1833
1834
  			if (n->type == AUDIT_TYPE_UNKNOWN)
  				n->type = type;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1835
1836
  			found_child = n;
  			break;
5712e88f2   Amy Griffis   [PATCH] match aud...
1837
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1838
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1839

5712e88f2   Amy Griffis   [PATCH] match aud...
1840
  	if (!found_parent) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1841
1842
  		/* create a new, "anonymous" parent record */
  		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
5195d8e21   Eric Paris   audit: dynamicall...
1843
  		if (!n)
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1844
  			return;
5195d8e21   Eric Paris   audit: dynamicall...
1845
  		audit_copy_inode(n, NULL, parent);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1846
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1847
1848
  
  	if (!found_child) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1849
1850
  		found_child = audit_alloc_name(context, type);
  		if (!found_child)
5712e88f2   Amy Griffis   [PATCH] match aud...
1851
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
1852
1853
1854
1855
1856
  
  		/* 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 _...
1857
1858
  			found_child->name = found_parent->name;
  			found_child->name_len = AUDIT_NAME_FULL;
55422d0bd   Paul Moore   audit: replace ge...
1859
  			found_child->name->refcnt++;
5712e88f2   Amy Griffis   [PATCH] match aud...
1860
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1861
  	}
57c59f583   Paul Moore   audit: fix filena...
1862

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1863
1864
1865
  	if (inode)
  		audit_copy_inode(found_child, dentry, inode);
  	else
84cb777e6   Richard Guy Briggs   audit: use macros...
1866
  		found_child->ino = AUDIT_INO_UNSET;
3e2efce06   Amy Griffis   [PATCH] fix fault...
1867
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
1868
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
1869
1870
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1871
1872
1873
1874
1875
1876
1877
   * 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...
1878
  int auditsc_get_stamp(struct audit_context *ctx,
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1879
  		       struct timespec *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
  {
48887e63d   Al Viro   [PATCH] fix broke...
1881
1882
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1883
1884
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1885
1886
1887
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
1888
1889
1890
1891
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
1892
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1893
  }
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1894
1895
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
da0a61049   Eric Paris   audit: loginuid f...
1896
1897
  static int audit_set_loginuid_perm(kuid_t loginuid)
  {
da0a61049   Eric Paris   audit: loginuid f...
1898
1899
1900
  	/* if we are unset, we don't need privs */
  	if (!audit_loginuid_set(current))
  		return 0;
21b85c31d   Eric Paris   audit: audit feat...
1901
1902
1903
  	/* if AUDIT_FEATURE_LOGINUID_IMMUTABLE means never ever allow a change*/
  	if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
  		return -EPERM;
83fa6bbe4   Eric Paris   audit: remove CON...
1904
1905
1906
  	/* it is set, you need permission */
  	if (!capable(CAP_AUDIT_CONTROL))
  		return -EPERM;
d040e5af3   Eric Paris   audit: audit feat...
1907
1908
1909
  	/* reject if this is not an unset and we don't allow that */
  	if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
  		return -EPERM;
83fa6bbe4   Eric Paris   audit: remove CON...
1910
  	return 0;
da0a61049   Eric Paris   audit: loginuid f...
1911
1912
1913
1914
1915
1916
1917
  }
  
  static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
  				   unsigned int oldsessionid, unsigned int sessionid,
  				   int rc)
  {
  	struct audit_buffer *ab;
5ee9a75c9   Richard Guy Briggs   audit: fix dangli...
1918
  	uid_t uid, oldloginuid, loginuid;
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1919
  	struct tty_struct *tty;
da0a61049   Eric Paris   audit: loginuid f...
1920

c2412d91c   Gao feng   audit: don't gene...
1921
1922
  	if (!audit_enabled)
  		return;
76a658c20   Richard Guy Briggs   audit: move calcs...
1923
1924
1925
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
  	if (!ab)
  		return;
da0a61049   Eric Paris   audit: loginuid f...
1926
  	uid = from_kuid(&init_user_ns, task_uid(current));
5ee9a75c9   Richard Guy Briggs   audit: fix dangli...
1927
1928
  	oldloginuid = from_kuid(&init_user_ns, koldloginuid);
  	loginuid = from_kuid(&init_user_ns, kloginuid),
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1929
  	tty = audit_get_tty(current);
da0a61049   Eric Paris   audit: loginuid f...
1930

fa2bea2f5   Paul Moore   audit: consistent...
1931
  	audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
ddfad8aff   Eric Paris   audit: include su...
1932
  	audit_log_task_context(ab);
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1933
1934
1935
1936
  	audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
  			 oldloginuid, loginuid, tty ? tty_name(tty) : "(none)",
  			 oldsessionid, sessionid, !rc);
  	audit_put_tty(tty);
da0a61049   Eric Paris   audit: loginuid f...
1937
1938
  	audit_log_end(ab);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1939
  /**
0a300be6d   Eric Paris   audit: remove tas...
1940
   * audit_set_loginuid - set current task's audit_context loginuid
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1941
1942
1943
1944
1945
1946
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
e1760bd5f   Eric W. Biederman   userns: Convert t...
1947
  int audit_set_loginuid(kuid_t loginuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1948
  {
0a300be6d   Eric Paris   audit: remove tas...
1949
  	struct task_struct *task = current;
9175c9d2a   Eric Paris   audit: fix type o...
1950
1951
  	unsigned int oldsessionid, sessionid = (unsigned int)-1;
  	kuid_t oldloginuid;
da0a61049   Eric Paris   audit: loginuid f...
1952
  	int rc;
41757106b   Steve Grubb   [PATCH] make set_...
1953

da0a61049   Eric Paris   audit: loginuid f...
1954
1955
1956
1957
1958
1959
  	oldloginuid = audit_get_loginuid(current);
  	oldsessionid = audit_get_sessionid(current);
  
  	rc = audit_set_loginuid_perm(loginuid);
  	if (rc)
  		goto out;
633b45454   Eric Paris   audit: only allow...
1960

81407c84a   Eric Paris   audit: allow unse...
1961
  	/* are we setting or clearing? */
833fc48d1   Richard Guy Briggs   audit: skip sessi...
1962
  	if (uid_valid(loginuid)) {
4440e8548   Eric Paris   audit: convert al...
1963
  		sessionid = (unsigned int)atomic_inc_return(&session_id);
833fc48d1   Richard Guy Briggs   audit: skip sessi...
1964
1965
1966
  		if (unlikely(sessionid == (unsigned int)-1))
  			sessionid = (unsigned int)atomic_inc_return(&session_id);
  	}
bfef93a5d   Al Viro   [PATCH] get rid o...
1967

4746ec5b0   Eric Paris   [AUDIT] add sessi...
1968
  	task->sessionid = sessionid;
bfef93a5d   Al Viro   [PATCH] get rid o...
1969
  	task->loginuid = loginuid;
da0a61049   Eric Paris   audit: loginuid f...
1970
1971
1972
  out:
  	audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1974
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1975
1976
1977
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
1978
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1979
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1980
   */
df0a42837   Al Viro   switch mq_open() ...
1981
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1982
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1983
  	struct audit_context *context = current->audit_context;
564f6993f   Al Viro   sanitize audit_mq...
1984
1985
1986
1987
  	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 ...
1988

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

564f6993f   Al Viro   sanitize audit_mq...
1992
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1993
1994
1995
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1996
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1997
1998
1999
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2000
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2001
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2002
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2003
2004
  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 ...
2005
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2006
  	struct audit_context *context = current->audit_context;
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2007
  	struct timespec *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2008

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2009
2010
2011
2012
  	if (abs_timeout)
  		memcpy(p, abs_timeout, sizeof(struct timespec));
  	else
  		memset(p, 0, sizeof(struct timespec));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2013

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2014
2015
2016
  	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 ...
2017

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2018
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2019
2020
2021
2022
2023
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
2024
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2025
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2026
   */
20114f71b   Al Viro   sanitize audit_mq...
2027
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2028
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2029
  	struct audit_context *context = current->audit_context;
20114f71b   Al Viro   sanitize audit_mq...
2030
2031
2032
2033
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2034

20114f71b   Al Viro   sanitize audit_mq...
2035
2036
  	context->mq_notify.mqdes = mqdes;
  	context->type = AUDIT_MQ_NOTIFY;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2037
2038
2039
2040
2041
2042
2043
  }
  
  /**
   * __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 ...
2044
   */
7392906ea   Al Viro   sanitize audit_mq...
2045
  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2046
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2047
  	struct audit_context *context = current->audit_context;
7392906ea   Al Viro   sanitize audit_mq...
2048
2049
2050
  	context->mq_getsetattr.mqdes = mqdes;
  	context->mq_getsetattr.mqstat = *mqstat;
  	context->type = AUDIT_MQ_GETSETATTR;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2051
2052
2053
  }
  
  /**
073115d6b   Steve Grubb   [PATCH] Rework of...
2054
2055
2056
   * audit_ipc_obj - record audit data for ipc object
   * @ipcp: ipc permissions
   *
073115d6b   Steve Grubb   [PATCH] Rework of...
2057
   */
a33e67510   Al Viro   sanitize audit_ip...
2058
  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
073115d6b   Steve Grubb   [PATCH] Rework of...
2059
  {
073115d6b   Steve Grubb   [PATCH] Rework of...
2060
  	struct audit_context *context = current->audit_context;
a33e67510   Al Viro   sanitize audit_ip...
2061
2062
2063
  	context->ipc.uid = ipcp->uid;
  	context->ipc.gid = ipcp->gid;
  	context->ipc.mode = ipcp->mode;
e816f370c   Al Viro   sanitize audit_ip...
2064
  	context->ipc.has_perm = 0;
a33e67510   Al Viro   sanitize audit_ip...
2065
2066
  	security_ipc_getsecid(ipcp, &context->ipc.osid);
  	context->type = AUDIT_IPC;
073115d6b   Steve Grubb   [PATCH] Rework of...
2067
2068
2069
2070
  }
  
  /**
   * audit_ipc_set_perm - record audit data for new ipc permissions
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2071
2072
2073
2074
2075
   * @qbytes: msgq bytes
   * @uid: msgq user id
   * @gid: msgq group id
   * @mode: msgq mode (permissions)
   *
e816f370c   Al Viro   sanitize audit_ip...
2076
   * Called only after audit_ipc_obj().
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2077
   */
2570ebbd1   Al Viro   switch kern_ipc_p...
2078
  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
2079
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080
  	struct audit_context *context = current->audit_context;
e816f370c   Al Viro   sanitize audit_ip...
2081
2082
2083
2084
2085
  	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
2086
  }
c2f0c7c35   Steve Grubb   The attached patc...
2087

d9cfea91e   Richard Guy Briggs   audit: move audit...
2088
  void __audit_bprm(struct linux_binprm *bprm)
473ae30bc   Al Viro   [PATCH] execve ar...
2089
  {
473ae30bc   Al Viro   [PATCH] execve ar...
2090
  	struct audit_context *context = current->audit_context;
473ae30bc   Al Viro   [PATCH] execve ar...
2091

d9cfea91e   Richard Guy Briggs   audit: move audit...
2092
2093
  	context->type = AUDIT_EXECVE;
  	context->execve.argc = bprm->argc;
473ae30bc   Al Viro   [PATCH] execve ar...
2094
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2095
2096
  /**
   * audit_socketcall - record audit data for sys_socketcall
2950fa9d3   Chen Gang   kernel: audit: be...
2097
   * @nargs: number of args, which should not be more than AUDITSC_ARGS.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2098
2099
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2100
   */
2950fa9d3   Chen Gang   kernel: audit: be...
2101
  int __audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2102
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2103
  	struct audit_context *context = current->audit_context;
2950fa9d3   Chen Gang   kernel: audit: be...
2104
2105
  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
  		return -EINVAL;
f3298dc4f   Al Viro   sanitize audit_so...
2106
2107
2108
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
2950fa9d3   Chen Gang   kernel: audit: be...
2109
  	return 0;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2110
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2111
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2112
2113
2114
2115
   * __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_...
2116
   */
157cf649a   Al Viro   sanitize audit_fd...
2117
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2118
2119
  {
  	struct audit_context *context = current->audit_context;
157cf649a   Al Viro   sanitize audit_fd...
2120
2121
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2122
2123
2124
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2125
2126
2127
2128
2129
2130
   * 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...
2131
  int __audit_sockaddr(int len, void *a)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2132
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2133
  	struct audit_context *context = current->audit_context;
4f6b434fe   Al Viro   don't reallocate ...
2134
2135
2136
2137
2138
2139
  	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...
2140

4f6b434fe   Al Viro   don't reallocate ...
2141
2142
  	context->sockaddr_len = len;
  	memcpy(context->sockaddr, a, len);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2143
2144
  	return 0;
  }
a5cb013da   Al Viro   [PATCH] auditing ...
2145
2146
2147
  void __audit_ptrace(struct task_struct *t)
  {
  	struct audit_context *context = current->audit_context;
fa2bea2f5   Paul Moore   audit: consistent...
2148
  	context->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2149
  	context->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2150
  	context->target_uid = task_uid(t);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2151
  	context->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2152
  	security_task_getsecid(t, &context->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2153
  	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
a5cb013da   Al Viro   [PATCH] auditing ...
2154
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2155
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2156
2157
2158
2159
2160
2161
2162
   * 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...
2163
  int __audit_signal_info(int sig, struct task_struct *t)
c2f0c7c35   Steve Grubb   The attached patc...
2164
  {
e54dc2431   Amy Griffis   [PATCH] audit sig...
2165
2166
2167
  	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...
2168
  	kuid_t uid = current_uid(), t_uid = task_uid(t);
e1396065e   Al Viro   [PATCH] collect s...
2169

175fc4842   Al Viro   fix oops in __aud...
2170
  	if (audit_pid && t->tgid == audit_pid) {
ee1d31566   Eric Paris   [PATCH] Audit: Co...
2171
  		if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
fa2bea2f5   Paul Moore   audit: consistent...
2172
  			audit_sig_pid = task_tgid_nr(tsk);
e1760bd5f   Eric W. Biederman   userns: Convert t...
2173
  			if (uid_valid(tsk->loginuid))
bfef93a5d   Al Viro   [PATCH] get rid o...
2174
  				audit_sig_uid = tsk->loginuid;
175fc4842   Al Viro   fix oops in __aud...
2175
  			else
c69e8d9c0   David Howells   CRED: Use RCU to ...
2176
  				audit_sig_uid = uid;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2177
  			security_task_getsecid(tsk, &audit_sig_sid);
175fc4842   Al Viro   fix oops in __aud...
2178
2179
2180
  		}
  		if (!audit_signals || audit_dummy_context())
  			return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2181
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
2182

e54dc2431   Amy Griffis   [PATCH] audit sig...
2183
2184
2185
  	/* optimize the common case by putting first signal recipient directly
  	 * in audit_context */
  	if (!ctx->target_pid) {
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2186
  		ctx->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2187
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2188
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2189
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2190
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2191
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
  		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:...
2205
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2206

f1dc4867f   Richard Guy Briggs   audit: anchor all...
2207
  	axp->target_pid[axp->pid_count] = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2208
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2209
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2210
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2211
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2212
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2213
2214
2215
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2216
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2217
2218
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2219
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2220
2221
2222
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2223
2224
2225
2226
   *
   * 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...
2227
2228
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2229
2230
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2231
2232
2233
2234
  {
  	struct audit_aux_data_bprm_fcaps *ax;
  	struct audit_context *context = current->audit_context;
  	struct cpu_vfs_cap_data vcaps;
3fc689e96   Eric Paris   Any time fcaps or...
2235
2236
2237
  
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
  	if (!ax)
d84f4f992   David Howells   CRED: Inaugurate ...
2238
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2239
2240
2241
2242
  
  	ax->d.type = AUDIT_BPRM_FCAPS;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
f4a4a8b12   Al Viro   file->f_path.dent...
2243
  	get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
3fc689e96   Eric Paris   Any time fcaps or...
2244
2245
2246
2247
2248
  
  	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 ...
2249
2250
2251
  	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...
2252

d84f4f992   David Howells   CRED: Inaugurate ...
2253
2254
2255
2256
  	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...
2257
2258
2259
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2260
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2261
2262
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2263
   *
da3dae54e   Masanari Iida   Documentation: Do...
2264
   * Record the arguments userspace sent to sys_capset for later printing by the
e68b75a02   Eric Paris   When the capset s...
2265
2266
   * audit system if applicable
   */
ca24a23eb   Eric W. Biederman   audit: Simplify a...
2267
  void __audit_log_capset(const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2268
  {
e68b75a02   Eric Paris   When the capset s...
2269
  	struct audit_context *context = current->audit_context;
fa2bea2f5   Paul Moore   audit: consistent...
2270
  	context->capset.pid = task_tgid_nr(current);
57f71a0af   Al Viro   sanitize audit_lo...
2271
2272
2273
2274
  	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...
2275
  }
120a795da   Al Viro   audit mmap
2276
2277
2278
2279
2280
2281
2282
  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...
2283
  static void audit_log_task(struct audit_buffer *ab)
85e7bac33   Eric Paris   seccomp: audit ab...
2284
  {
cca080d9b   Eric W. Biederman   userns: Convert a...
2285
2286
  	kuid_t auid, uid;
  	kgid_t gid;
85e7bac33   Eric Paris   seccomp: audit ab...
2287
  	unsigned int sessionid;
9eab339b1   Richard Guy Briggs   audit: get comm u...
2288
  	char comm[sizeof(current->comm)];
85e7bac33   Eric Paris   seccomp: audit ab...
2289
2290
2291
2292
2293
2294
  
  	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...
2295
2296
2297
2298
  			 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...
2299
  	audit_log_task_context(ab);
fa2bea2f5   Paul Moore   audit: consistent...
2300
  	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
9eab339b1   Richard Guy Briggs   audit: get comm u...
2301
  	audit_log_untrustedstring(ab, get_task_comm(comm, current));
4766b199e   Davidlohr Bueso   audit: consolidat...
2302
  	audit_log_d_path_exe(ab, current->mm);
7b9205bd7   Kees Cook   audit: create exp...
2303
  }
e68b75a02   Eric Paris   When the capset s...
2304
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2305
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2306
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2307
2308
2309
2310
2311
2312
2313
   *
   * 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 ...
2314
2315
2316
2317
2318
2319
2320
2321
  
  	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...
2322
2323
  	if (unlikely(!ab))
  		return;
61c0ee879   Paul Davies C   audit: drop audit...
2324
2325
  	audit_log_task(ab);
  	audit_log_format(ab, " sig=%ld", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2326
2327
  	audit_log_end(ab);
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2328

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