Blame view

kernel/auditsc.c 65.9 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>
a6c043a88   Steve Grubb   [PATCH] Add tty t...
64
  #include <linux/tty.h>
473ae30bc   Al Viro   [PATCH] execve ar...
65
  #include <linux/binfmts.h>
a1f8e7f7f   Al Viro   [PATCH] severing ...
66
  #include <linux/highmem.h>
f46038ff7   Al Viro   [PATCH] log ppid
67
  #include <linux/syscalls.h>
851f7ff56   Eric Paris   This patch will p...
68
  #include <linux/capability.h>
5ad4e53bd   Al Viro   Get rid of indire...
69
  #include <linux/fs_struct.h>
3dc1c1b2d   Kees Cook   seccomp: remove d...
70
  #include <linux/compat.h>
3f1c82502   William Roberts   audit: Audit proc...
71
  #include <linux/ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72

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

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

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

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

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

93315ed6d   Amy Griffis   [PATCH] audit str...
442
  		switch (f->type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
443
  		case AUDIT_PID:
f1dc4867f   Richard Guy Briggs   audit: anchor all...
444
445
  			pid = task_pid_nr(tsk);
  			result = audit_comparator(pid, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  			break;
3c66251e5   Al Viro   [PATCH] add filte...
447
  		case AUDIT_PPID:
419c58f11   Alexander Viro   [PATCH] PPID filt...
448
449
  			if (ctx) {
  				if (!ctx->ppid)
c92cdeb45   Richard Guy Briggs   audit: convert PP...
450
  					ctx->ppid = task_ppid_nr(tsk);
3c66251e5   Al Viro   [PATCH] add filte...
451
  				result = audit_comparator(ctx->ppid, f->op, f->val);
419c58f11   Alexander Viro   [PATCH] PPID filt...
452
  			}
3c66251e5   Al Viro   [PATCH] add filte...
453
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  		case AUDIT_UID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
455
  			result = audit_uid_comparator(cred->uid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
  			break;
  		case AUDIT_EUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
458
  			result = audit_uid_comparator(cred->euid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
  			break;
  		case AUDIT_SUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
461
  			result = audit_uid_comparator(cred->suid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
  			break;
  		case AUDIT_FSUID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
464
  			result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
  			break;
  		case AUDIT_GID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
467
  			result = audit_gid_comparator(cred->gid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
468
469
470
471
472
473
474
  			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
475
476
  			break;
  		case AUDIT_EGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
477
  			result = audit_gid_comparator(cred->egid, f->op, f->gid);
37eebe39c   Matvejchikov Ilya   audit: improve GI...
478
479
480
481
482
483
484
  			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
485
486
  			break;
  		case AUDIT_SGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
487
  			result = audit_gid_comparator(cred->sgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
489
  			break;
  		case AUDIT_FSGID:
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
490
  			result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
  			break;
  		case AUDIT_PERS:
93315ed6d   Amy Griffis   [PATCH] audit str...
493
  			result = audit_comparator(tsk->personality, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
  			break;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
495
  		case AUDIT_ARCH:
9f8dbe9c9   Daniel Walker   whitespace fixes:...
496
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
497
  				result = audit_comparator(ctx->arch, f->op, f->val);
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
498
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
500
501
  
  		case AUDIT_EXIT:
  			if (ctx && ctx->return_valid)
93315ed6d   Amy Griffis   [PATCH] audit str...
502
  				result = audit_comparator(ctx->return_code, f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
  			break;
  		case AUDIT_SUCCESS:
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
505
  			if (ctx && ctx->return_valid) {
93315ed6d   Amy Griffis   [PATCH] audit str...
506
507
  				if (f->val)
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
508
  				else
93315ed6d   Amy Griffis   [PATCH] audit str...
509
  					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE);
b01f2cc1c   David Woodhouse   [AUDIT] Allow fil...
510
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
512
  			break;
  		case AUDIT_DEVMAJOR:
16c174bd9   Eric Paris   audit: check curr...
513
514
515
516
517
  			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...
518
  				list_for_each_entry(n, &ctx->names_list, list) {
16c174bd9   Eric Paris   audit: check curr...
519
520
  					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
521
522
523
524
525
526
527
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_DEVMINOR:
16c174bd9   Eric Paris   audit: check curr...
528
529
530
531
532
  			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...
533
  				list_for_each_entry(n, &ctx->names_list, list) {
16c174bd9   Eric Paris   audit: check curr...
534
535
  					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
536
537
538
539
540
541
542
  						++result;
  						break;
  					}
  				}
  			}
  			break;
  		case AUDIT_INODE:
f368c07d7   Amy Griffis   [PATCH] audit: pa...
543
  			if (name)
db510fc5c   Richard Guy Briggs   audit: update AUD...
544
  				result = audit_comparator(name->ino, f->op, f->val);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
545
  			else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
546
547
  				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
548
549
550
551
552
553
  						++result;
  						break;
  					}
  				}
  			}
  			break;
efaffd6e4   Eric Paris   audit: allow matc...
554
555
  		case AUDIT_OBJ_UID:
  			if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
556
  				result = audit_uid_comparator(name->uid, f->op, f->uid);
efaffd6e4   Eric Paris   audit: allow matc...
557
558
  			} else if (ctx) {
  				list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
559
  					if (audit_uid_comparator(n->uid, f->op, f->uid)) {
efaffd6e4   Eric Paris   audit: allow matc...
560
561
562
563
564
565
  						++result;
  						break;
  					}
  				}
  			}
  			break;
54d3218b3   Eric Paris   audit: allow audi...
566
567
  		case AUDIT_OBJ_GID:
  			if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
568
  				result = audit_gid_comparator(name->gid, f->op, f->gid);
54d3218b3   Eric Paris   audit: allow audi...
569
570
  			} else if (ctx) {
  				list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
571
  					if (audit_gid_comparator(n->gid, f->op, f->gid)) {
54d3218b3   Eric Paris   audit: allow audi...
572
573
574
575
576
577
  						++result;
  						break;
  					}
  				}
  			}
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
578
  		case AUDIT_WATCH:
ae7b8f410   Eric Paris   Audit: clean up t...
579
580
  			if (name)
  				result = audit_watch_compare(rule->watch, name->ino, name->dev);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
581
  			break;
74c3cbe33   Al Viro   [PATCH] audit: wa...
582
583
584
585
  		case AUDIT_DIR:
  			if (ctx)
  				result = match_tree_refs(ctx, rule->tree);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
587
588
  		case AUDIT_LOGINUID:
  			result = 0;
  			if (ctx)
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
589
  				result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  			break;
780a7654c   Eric W. Biederman   audit: Make testi...
591
592
593
  		case AUDIT_LOGINUID_SET:
  			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
  			break;
3a6b9f85c   Darrel Goeddel   [PATCH] audit: re...
594
595
596
597
598
  		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...
599
600
601
602
603
  			/* 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...
604
  			if (f->lsm_rule) {
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
605
  				if (need_sid) {
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
606
  					security_task_getsecid(tsk, &sid);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
607
608
  					need_sid = 0;
  				}
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
609
  				result = security_audit_rule_match(sid, f->type,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
610
  				                                  f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
611
  				                                  f->lsm_rule,
3dc7e3153   Darrel Goeddel   [PATCH] support f...
612
  				                                  ctx);
2ad312d20   Steve Grubb   [PATCH] Audit Fil...
613
  			}
3dc7e3153   Darrel Goeddel   [PATCH] support f...
614
  			break;
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
615
616
617
618
619
620
621
  		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...
622
  			if (f->lsm_rule) {
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
623
624
  				/* Find files that match */
  				if (name) {
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
625
  					result = security_audit_rule_match(
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
626
  					           name->osid, f->type, f->op,
04305e4af   Ahmed S. Darwish   Audit: Final rena...
627
  					           f->lsm_rule, ctx);
6e5a2d1d3   Darrel Goeddel   [PATCH] audit: su...
628
  				} else if (ctx) {
5195d8e21   Eric Paris   audit: dynamicall...
629
630
631
632
  					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...
633
634
635
636
637
638
  							++result;
  							break;
  						}
  					}
  				}
  				/* Find ipc objects that match */
a33e67510   Al Viro   sanitize audit_ip...
639
640
641
642
643
644
  				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...
645
646
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
648
649
650
651
  		case AUDIT_ARG0:
  		case AUDIT_ARG1:
  		case AUDIT_ARG2:
  		case AUDIT_ARG3:
  			if (ctx)
93315ed6d   Amy Griffis   [PATCH] audit str...
652
  				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  			break;
5adc8a6ad   Amy Griffis   [PATCH] add rule ...
654
655
656
657
  		case AUDIT_FILTERKEY:
  			/* ignore this field for filtering */
  			result = 1;
  			break;
55669bfa1   Al Viro   [PATCH] audit: AU...
658
659
660
  		case AUDIT_PERM:
  			result = audit_match_perm(ctx, f->val);
  			break;
8b67dca94   Al Viro   [PATCH] new predi...
661
662
663
  		case AUDIT_FILETYPE:
  			result = audit_match_filetype(ctx, f->val);
  			break;
02d86a568   Eric Paris   audit: allow inte...
664
665
666
  		case AUDIT_FIELD_COMPARE:
  			result = audit_field_compare(tsk, cred, f, ctx, name);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
  		}
f56298835   Tony Jones   audit: acquire cr...
668
  		if (!result)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
670
  			return 0;
  	}
0590b9335   Al Viro   fixing audit rule...
671
672
673
674
675
676
677
678
679
680
  
  	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
681
682
  	switch (rule->action) {
  	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
683
684
685
686
687
688
689
690
691
  	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
  	}
  	return 1;
  }
  
  /* At process creation time, we can determine if system-call auditing is
   * completely disabled for this task.  Since we only have the task
   * structure at this point, we can only check uid and gid.
   */
e048e02c8   Al Viro   make sure that fi...
692
  static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
694
695
696
697
  {
  	struct audit_entry *e;
  	enum audit_state   state;
  
  	rcu_read_lock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
698
  	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
f56298835   Tony Jones   audit: acquire cr...
699
700
  		if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
  				       &state, true)) {
e048e02c8   Al Viro   make sure that fi...
701
702
  			if (state == AUDIT_RECORD_CONTEXT)
  				*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
705
706
707
708
709
710
711
712
  			rcu_read_unlock();
  			return state;
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
  
  /* At syscall entry and exit time, this filter is called if the
   * audit_state is not low enough that auditing cannot take place, but is
23f32d18a   Steve Grubb   AUDIT: Fix some s...
713
   * also not high enough that we already know we have to write an audit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
714
   * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
717
718
719
720
   */
  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...
721
  	enum audit_state state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722

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

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

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

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

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

e1760bd5f   Eric W. Biederman   userns: Convert t...
958
959
  	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...
960
  			 from_kuid(&init_user_ns, uid), sessionid);
ad395abec   Eric Paris   Audit: do not pri...
961
962
963
964
965
966
967
968
  	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...
969
  	}
c2a7780ef   Eric Paris   [AUDIT] collect u...
970
971
  	audit_log_format(ab, " ocomm=");
  	audit_log_untrustedstring(ab, comm);
e54dc2431   Amy Griffis   [PATCH] audit sig...
972
  	audit_log_end(ab);
e54dc2431   Amy Griffis   [PATCH] audit sig...
973
974
975
  
  	return rc;
  }
de6bbd1d3   Eric Paris   [AUDIT] break lar...
976
977
978
  /*
   * to_send and len_sent accounting are very loose estimates.  We aren't
   * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being
25985edce   Lucas De Marchi   Fix common misspe...
979
   * within about 500 bytes (next page boundary)
de6bbd1d3   Eric Paris   [AUDIT] break lar...
980
981
982
983
984
985
986
987
988
989
990
991
992
   *
   * why snprintf?  an int is up to 12 digits long.  if we just assumed when
   * logging that a[%d]= was going to be 16 characters long we would be wasting
   * space in every audit message.  In one 7500 byte message we can log up to
   * about 1000 min size arguments.  That comes down to about 50% waste of space
   * if we didn't do the snprintf to find out how long arg_num_len was.
   */
  static int audit_log_single_execve_arg(struct audit_context *context,
  					struct audit_buffer **ab,
  					int arg_num,
  					size_t *len_sent,
  					const char __user *p,
  					char *buf)
bdf4c48af   Peter Zijlstra   audit: rework exe...
993
  {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
994
995
  	char arg_num_len_buf[12];
  	const char __user *tmp_p = p;
b87ce6e41   Eric Paris   Audit: better est...
996
997
  	/* how many digits are in arg_num? 5 is the length of ' a=""' */
  	size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
998
999
1000
1001
1002
1003
1004
  	size_t len, len_left, to_send;
  	size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
  	unsigned int i, has_cntl = 0, too_long = 0;
  	int ret;
  
  	/* strnlen_user includes the null we don't want to send */
  	len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1005

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

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

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

d9cfea91e   Richard Guy Briggs   audit: move audit...
1131
  	p = (const char __user *)current->mm->arg_start;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1132

d9cfea91e   Richard Guy Briggs   audit: move audit...
1133
  	audit_log_format(*ab, "argc=%d", context->execve.argc);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1134
1135
1136
1137
1138
1139
1140
1141
1142
  
  	/*
  	 * we need some kernel buffer to hold the userspace args.  Just
  	 * allocate one big one rather than allocating one of the right size
  	 * for every single argument inside audit_log_single_execve_arg()
  	 * should be <8k allocation so should be pretty safe.
  	 */
  	buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
  	if (!buf) {
b7550787f   Joe Perches   audit: remove str...
1143
  		audit_panic("out of memory for argv string");
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1144
  		return;
bdf4c48af   Peter Zijlstra   audit: rework exe...
1145
  	}
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1146

d9cfea91e   Richard Guy Briggs   audit: move audit...
1147
  	for (i = 0; i < context->execve.argc; i++) {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1148
1149
1150
1151
1152
1153
1154
  		len = audit_log_single_execve_arg(context, ab, i,
  						  &len_sent, p, buf);
  		if (len <= 0)
  			break;
  		p += len;
  	}
  	kfree(buf);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1155
  }
a33e67510   Al Viro   sanitize audit_ip...
1156
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
  {
  	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...
1173
1174
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1175
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
cca080d9b   Eric W. Biederman   userns: Convert a...
1176
1177
1178
  				 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...
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
  		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...
1190
1191
1192
1193
  		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...
1194
1195
  			if (unlikely(!ab))
  				return;
e816f370c   Al Viro   sanitize audit_ip...
1196
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1197
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1198
1199
1200
1201
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
e816f370c   Al Viro   sanitize audit_ip...
1202
  		}
a33e67510   Al Viro   sanitize audit_ip...
1203
  		break; }
564f6993f   Al Viro   sanitize audit_mq...
1204
1205
  	case AUDIT_MQ_OPEN: {
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1206
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1207
1208
1209
1210
1211
1212
1213
  			"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...
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
  	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...
1224
1225
1226
1227
1228
  	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...
1229
1230
1231
1232
1233
1234
1235
1236
1237
  	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...
1238
1239
1240
1241
1242
1243
  	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
1244
1245
1246
1247
  	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...
1248
1249
1250
  	case AUDIT_EXECVE: {
  		audit_log_execve_info(context, &ab);
  		break; }
f3298dc4f   Al Viro   sanitize audit_so...
1251
1252
1253
  	}
  	audit_log_end(ab);
  }
3f1c82502   William Roberts   audit: Audit proc...
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
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
  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_...
1306
  static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307
  {
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1308
  	int i, call_panic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1310
  	struct audit_aux_data *aux;
5195d8e21   Eric Paris   audit: dynamicall...
1311
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312

e495149b1   Al Viro   [PATCH] drop gfp_...
1313
  	/* tsk == current */
3f2792ffb   Al Viro   [PATCH] take fill...
1314
  	context->personality = tsk->personality;
e495149b1   Al Viro   [PATCH] drop gfp_...
1315
1316
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1317
1318
  	if (!ab)
  		return;		/* audit_panic has been called */
bccf6ae08   David Woodhouse   AUDIT: Unify auid...
1319
1320
  	audit_log_format(ab, "arch=%x syscall=%d",
  			 context->arch, context->major);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1321
1322
1323
  	if (context->personality != PER_LINUX)
  		audit_log_format(ab, " per=%lx", context->personality);
  	if (context->return_valid)
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1324
  		audit_log_format(ab, " success=%s exit=%ld",
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1325
1326
  				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
  				 context->return_code);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1327

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1328
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1329
1330
1331
1332
1333
1334
  			 " 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...
1335

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

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

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

3fc689e96   Eric Paris   Any time fcaps or...
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
  		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
1360
1361
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1363
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1364
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1365

157cf649a   Al Viro   sanitize audit_fd...
1366
1367
1368
1369
1370
1371
1372
1373
  	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 ...
1374
1375
1376
1377
1378
1379
1380
1381
1382
  	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...
1383
1384
  	for (aux = context->aux_pids; aux; aux = aux->next) {
  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1385
1386
1387
  
  		for (i = 0; i < axs->pid_count; i++)
  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1388
1389
  						  axs->target_auid[i],
  						  axs->target_uid[i],
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1390
  						  axs->target_sessionid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1391
1392
  						  axs->target_sid[i],
  						  axs->target_comm[i]))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1393
  				call_panic = 1;
a5cb013da   Al Viro   [PATCH] auditing ...
1394
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1395
1396
  	if (context->target_pid &&
  	    audit_log_pid_context(context, context->target_pid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1397
  				  context->target_auid, context->target_uid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1398
  				  context->target_sessionid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1399
  				  context->target_sid, context->target_comm))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1400
  			call_panic = 1;
44707fdf5   Jan Blunck   d_path: Use struc...
1401
  	if (context->pwd.dentry && context->pwd.mnt) {
e495149b1   Al Viro   [PATCH] drop gfp_...
1402
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1403
  		if (ab) {
c158a35c8   Kees Cook   audit: no leading...
1404
  			audit_log_d_path(ab, " cwd=", &context->pwd);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1405
1406
1407
  			audit_log_end(ab);
  		}
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1408

5195d8e21   Eric Paris   audit: dynamicall...
1409
  	i = 0;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1410
1411
1412
  	list_for_each_entry(n, &context->names_list, list) {
  		if (n->hidden)
  			continue;
b24a30a73   Eric Paris   audit: fix event ...
1413
  		audit_log_name(context, n, NULL, i++, &call_panic);
79f6530cb   Jeff Layton   audit: fix mq_ope...
1414
  	}
c0641f28d   Eric Paris   [AUDIT] Add End o...
1415

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1476
1477
1478
1479
  	BUG_ON(context->in_syscall || context->name_count);
  
  	if (!audit_enabled)
  		return;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1480
  	context->arch	    = arch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1481
1482
1483
1484
1485
1486
1487
  	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...
1488
  	context->dummy = !audit_n_rules;
0590b9335   Al Viro   fixing audit rule...
1489
1490
  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
  		context->prio = 0;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1491
  		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
0590b9335   Al Viro   fixing audit rule...
1492
  	}
56179a6ec   Eric Paris   audit: drop some ...
1493
  	if (state == AUDIT_DISABLED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
  		return;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1495
  	context->serial     = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
1497
  	context->ctime      = CURRENT_TIME;
  	context->in_syscall = 1;
0590b9335   Al Viro   fixing audit rule...
1498
  	context->current_state  = state;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1499
  	context->ppid       = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1501
1502
  /**
   * audit_syscall_exit - deallocate audit context after a system call
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1503
1504
   * @success: success value of the syscall
   * @return_code: return value of the syscall
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1505
1506
   *
   * Tear down after system call.  If the audit context has been marked as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
   * auditable (either because of the AUDIT_RECORD_CONTEXT state from
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1508
   * filtering, or because some other part of the kernel wrote an audit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509
   * message), then write out the syscall information.  In call cases,
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1510
1511
   * free the names stored from getname().
   */
d7e7528bc   Eric Paris   Audit: push audit...
1512
  void __audit_syscall_exit(int success, long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  {
5411be59d   Al Viro   [PATCH] drop task...
1514
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
  	struct audit_context *context;
d7e7528bc   Eric Paris   Audit: push audit...
1516
1517
1518
1519
  	if (success)
  		success = AUDITSC_SUCCESS;
  	else
  		success = AUDITSC_FAILURE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520

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

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

916d75761   Al Viro   Fix rule eviction...
1531
1532
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
c62d773a3   Al Viro   audit: no nested ...
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
  	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
1546
  	}
c62d773a3   Al Viro   audit: no nested ...
1547
  	tsk->audit_context = context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1548
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1549
1550
1551
1552
1553
1554
1555
  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 ...
1556
  	if (likely(hlist_empty(&inode->i_fsnotify_marks)))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
  		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...
1569
1570
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
  		audit_set_auditable(context);
  		audit_put_chunk(chunk);
  		unroll_tree_refs(context, p, count);
  		return;
  	}
  	put_tree_ref(context, chunk);
  #endif
  }
  
  static void handle_path(const struct dentry *dentry)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_context *context;
  	struct audit_tree_refs *p;
  	const struct dentry *d, *parent;
  	struct audit_chunk *drop;
  	unsigned long seq;
  	int count;
  
  	context = current->audit_context;
  	p = context->trees;
  	count = context->tree_count;
  retry:
  	drop = NULL;
  	d = dentry;
  	rcu_read_lock();
  	seq = read_seqbegin(&rename_lock);
  	for(;;) {
  		struct inode *inode = d->d_inode;
e61ce8673   Eric Paris   fsnotify: rename ...
1600
  		if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_marks))) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
  			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...
1629
1630
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1631
1632
1633
1634
1635
1636
1637
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
  #endif
  }
78e2e802a   Jeff Layton   audit: add a new ...
1638
1639
  static struct audit_names *audit_alloc_name(struct audit_context *context,
  						unsigned char type)
5195d8e21   Eric Paris   audit: dynamicall...
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
  {
  	struct audit_names *aname;
  
  	if (context->name_count < AUDIT_NAMES) {
  		aname = &context->preallocated_names[context->name_count];
  		memset(aname, 0, sizeof(*aname));
  	} else {
  		aname = kzalloc(sizeof(*aname), GFP_NOFS);
  		if (!aname)
  			return NULL;
  		aname->should_free = true;
  	}
  
  	aname->ino = (unsigned long)-1;
78e2e802a   Jeff Layton   audit: add a new ...
1654
  	aname->type = type;
5195d8e21   Eric Paris   audit: dynamicall...
1655
1656
1657
1658
1659
1660
1661
1662
  	list_add_tail(&aname->list, &context->names_list);
  
  	context->name_count++;
  #if AUDIT_DEBUG
  	context->ino_count++;
  #endif
  	return aname;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1663
  /**
7ac86265d   Jeff Layton   audit: allow audi...
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
   * audit_reusename - fill out filename with info from existing entry
   * @uptr: userland ptr to pathname
   *
   * Search the audit_names list for the current audit context. If there is an
   * existing entry with a matching "uptr" then return the filename
   * associated with that audit_name. If not, return NULL.
   */
  struct filename *
  __audit_reusename(const __user char *uptr)
  {
  	struct audit_context *context = current->audit_context;
  	struct audit_names *n;
  
  	list_for_each_entry(n, &context->names_list, list) {
  		if (!n->name)
  			continue;
  		if (n->name->uptr == uptr)
  			return n->name;
  	}
  	return NULL;
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1687
1688
1689
1690
1691
1692
   * 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...
1693
  void __audit_getname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694
1695
  {
  	struct audit_context *context = current->audit_context;
5195d8e21   Eric Paris   audit: dynamicall...
1696
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1698
1699
  	if (!context->in_syscall) {
  #if AUDIT_DEBUG == 2
f952d10ff   Richard Guy Briggs   audit: Use more c...
1700
1701
  		pr_err("%s:%d(:%d): ignoring getname(%p)
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702
1703
1704
1705
1706
  		       __FILE__, __LINE__, context->serial, name);
  		dump_stack();
  #endif
  		return;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1707

91a27b2a7   Jeff Layton   vfs: define struc...
1708
1709
1710
1711
  #if AUDIT_DEBUG
  	/* The filename _must_ have a populated ->name */
  	BUG_ON(!name->name);
  #endif
78e2e802a   Jeff Layton   audit: add a new ...
1712
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1713
1714
1715
1716
1717
1718
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
  	n->name_put = true;
adb5c2473   Jeff Layton   audit: make audit...
1719
  	name->aname = n;
5195d8e21   Eric Paris   audit: dynamicall...
1720

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1721
1722
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1723
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1724
1725
1726
1727
1728
1729
1730
  /* audit_putname - intercept a putname request
   * @name: name to intercept and delay for putname
   *
   * If we have stored the name from getname in the audit context,
   * then we delay the putname until syscall exit.
   * Called from include/linux/fs.h:putname().
   */
91a27b2a7   Jeff Layton   vfs: define struc...
1731
  void audit_putname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
1733
1734
1735
  {
  	struct audit_context *context = current->audit_context;
  
  	BUG_ON(!context);
c4ad8f98b   Linus Torvalds   execve: use 'stru...
1736
  	if (!name->aname || !context->in_syscall) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
  #if AUDIT_DEBUG == 2
f952d10ff   Richard Guy Briggs   audit: Use more c...
1738
1739
  		pr_err("%s:%d(:%d): final_putname(%p)
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1740
1741
  		       __FILE__, __LINE__, context->serial, name);
  		if (context->name_count) {
5195d8e21   Eric Paris   audit: dynamicall...
1742
  			struct audit_names *n;
34c474de7   Eric Paris   audit: fix build ...
1743
  			int i = 0;
5195d8e21   Eric Paris   audit: dynamicall...
1744
1745
  
  			list_for_each_entry(n, &context->names_list, list)
f952d10ff   Richard Guy Briggs   audit: Use more c...
1746
1747
1748
  				pr_err("name[%d] = %p = %s
  ", i++, n->name,
  				       n->name->name ?: "(null)");
5195d8e21   Eric Paris   audit: dynamicall...
1749
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1750
  #endif
65ada7bc0   Dmitry Monakhov   audit: destroy lo...
1751
  		final_putname(name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1752
1753
1754
1755
1756
  	}
  #if AUDIT_DEBUG
  	else {
  		++context->put_count;
  		if (context->put_count > context->name_count) {
f952d10ff   Richard Guy Briggs   audit: Use more c...
1757
1758
1759
  			pr_err("%s:%d(:%d): major=%d in_syscall=%d putname(%p)"
  			       " name_count=%d put_count=%d
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1760
1761
  			       __FILE__, __LINE__,
  			       context->serial, context->major,
91a27b2a7   Jeff Layton   vfs: define struc...
1762
1763
  			       context->in_syscall, name->name,
  			       context->name_count, context->put_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1764
1765
1766
1767
1768
  			dump_stack();
  		}
  	}
  #endif
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1769
  /**
bfcec7087   Jeff Layton   audit: set the na...
1770
   * __audit_inode - store the inode and device from a lookup
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1771
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1772
   * @dentry: dentry being audited
79f6530cb   Jeff Layton   audit: fix mq_ope...
1773
   * @flags: attributes for this particular entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1774
   */
adb5c2473   Jeff Layton   audit: make audit...
1775
  void __audit_inode(struct filename *name, const struct dentry *dentry,
79f6530cb   Jeff Layton   audit: fix mq_ope...
1776
  		   unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1778
  	struct audit_context *context = current->audit_context;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1779
  	const struct inode *inode = dentry->d_inode;
5195d8e21   Eric Paris   audit: dynamicall...
1780
  	struct audit_names *n;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1781
  	bool parent = flags & AUDIT_INODE_PARENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
1783
1784
  
  	if (!context->in_syscall)
  		return;
5195d8e21   Eric Paris   audit: dynamicall...
1785

9cec9d68a   Jeff Layton   audit: no need to...
1786
1787
  	if (!name)
  		goto out_alloc;
adb5c2473   Jeff Layton   audit: make audit...
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
  #if AUDIT_DEBUG
  	/* The struct filename _must_ have a populated ->name */
  	BUG_ON(!name->name);
  #endif
  	/*
  	 * If we have a pointer to an audit_names entry already, then we can
  	 * just use it directly if the type is correct.
  	 */
  	n = name->aname;
  	if (n) {
  		if (parent) {
  			if (n->type == AUDIT_TYPE_PARENT ||
  			    n->type == AUDIT_TYPE_UNKNOWN)
  				goto out;
  		} else {
  			if (n->type != AUDIT_TYPE_PARENT)
  				goto out;
  		}
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1807
  	list_for_each_entry_reverse(n, &context->names_list, list) {
bfcec7087   Jeff Layton   audit: set the na...
1808
  		/* does the name pointer match? */
adb5c2473   Jeff Layton   audit: make audit...
1809
  		if (!n->name || n->name->name != name->name)
bfcec7087   Jeff Layton   audit: set the na...
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
  			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
1821
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1822

9cec9d68a   Jeff Layton   audit: no need to...
1823
  out_alloc:
bfcec7087   Jeff Layton   audit: set the na...
1824
1825
1826
  	/* unable to find the name from a previous getname(). Allocate a new
  	 * anonymous entry.
  	 */
78e2e802a   Jeff Layton   audit: add a new ...
1827
  	n = audit_alloc_name(context, AUDIT_TYPE_NORMAL);
5195d8e21   Eric Paris   audit: dynamicall...
1828
1829
1830
  	if (!n)
  		return;
  out:
bfcec7087   Jeff Layton   audit: set the na...
1831
  	if (parent) {
91a27b2a7   Jeff Layton   vfs: define struc...
1832
  		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
bfcec7087   Jeff Layton   audit: set the na...
1833
  		n->type = AUDIT_TYPE_PARENT;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1834
1835
  		if (flags & AUDIT_INODE_HIDDEN)
  			n->hidden = true;
bfcec7087   Jeff Layton   audit: set the na...
1836
1837
1838
1839
  	} else {
  		n->name_len = AUDIT_NAME_FULL;
  		n->type = AUDIT_TYPE_NORMAL;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1840
  	handle_path(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1841
  	audit_copy_inode(n, dentry, inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1842
1843
1844
  }
  
  /**
c43a25abb   Jeff Layton   audit: reverse ar...
1845
   * __audit_inode_child - collect inode info for created/removed objects
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1846
   * @parent: inode of dentry parent
c43a25abb   Jeff Layton   audit: reverse ar...
1847
   * @dentry: dentry being audited
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1848
   * @type:   AUDIT_TYPE_* value that we're looking for
73241ccca   Amy Griffis   [PATCH] Collect m...
1849
1850
1851
1852
1853
1854
1855
1856
1857
   *
   * For syscalls that create or remove filesystem objects, audit_inode
   * can only collect information for the filesystem object's parent.
   * This call updates the audit context with the child's information.
   * Syscalls that create a new filesystem object must be hooked after
   * the object is created.  Syscalls that remove a filesystem object
   * must be hooked prior, in order to capture the target inode during
   * unsuccessful attempts.
   */
c43a25abb   Jeff Layton   audit: reverse ar...
1858
  void __audit_inode_child(const struct inode *parent,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1859
1860
  			 const struct dentry *dentry,
  			 const unsigned char type)
73241ccca   Amy Griffis   [PATCH] Collect m...
1861
  {
73241ccca   Amy Griffis   [PATCH] Collect m...
1862
  	struct audit_context *context = current->audit_context;
5a190ae69   Al Viro   [PATCH] pass dent...
1863
  	const struct inode *inode = dentry->d_inode;
cccc6bba3   Al Viro   Lose the first ar...
1864
  	const char *dname = dentry->d_name.name;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1865
  	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
73241ccca   Amy Griffis   [PATCH] Collect m...
1866
1867
1868
  
  	if (!context->in_syscall)
  		return;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1869
1870
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1871

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1872
  	/* look for a parent entry first */
5195d8e21   Eric Paris   audit: dynamicall...
1873
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1874
  		if (!n->name || n->type != AUDIT_TYPE_PARENT)
5712e88f2   Amy Griffis   [PATCH] match aud...
1875
1876
1877
  			continue;
  
  		if (n->ino == parent->i_ino &&
91a27b2a7   Jeff Layton   vfs: define struc...
1878
  		    !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1879
1880
  			found_parent = n;
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1881
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1882
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1883

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1884
  	/* is there a matching child entry? */
5195d8e21   Eric Paris   audit: dynamicall...
1885
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1886
1887
1888
1889
1890
1891
  		/* can only match entries that have a name */
  		if (!n->name || n->type != type)
  			continue;
  
  		/* if we found a parent, make sure this one is a child of it */
  		if (found_parent && (n->name != found_parent->name))
5712e88f2   Amy Griffis   [PATCH] match aud...
1892
  			continue;
91a27b2a7   Jeff Layton   vfs: define struc...
1893
1894
  		if (!strcmp(dname, n->name->name) ||
  		    !audit_compare_dname_path(dname, n->name->name,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1895
1896
  						found_parent ?
  						found_parent->name_len :
e3d6b07b8   Jeff Layton   audit: optimize a...
1897
  						AUDIT_NAME_FULL)) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1898
1899
  			found_child = n;
  			break;
5712e88f2   Amy Griffis   [PATCH] match aud...
1900
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1901
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1902

5712e88f2   Amy Griffis   [PATCH] match aud...
1903
  	if (!found_parent) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1904
1905
  		/* create a new, "anonymous" parent record */
  		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
5195d8e21   Eric Paris   audit: dynamicall...
1906
  		if (!n)
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1907
  			return;
5195d8e21   Eric Paris   audit: dynamicall...
1908
  		audit_copy_inode(n, NULL, parent);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1909
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1910
1911
  
  	if (!found_child) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1912
1913
  		found_child = audit_alloc_name(context, type);
  		if (!found_child)
5712e88f2   Amy Griffis   [PATCH] match aud...
1914
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
1915
1916
1917
1918
1919
  
  		/* 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 _...
1920
1921
  			found_child->name = found_parent->name;
  			found_child->name_len = AUDIT_NAME_FULL;
5712e88f2   Amy Griffis   [PATCH] match aud...
1922
  			/* don't call __putname() */
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1923
  			found_child->name_put = false;
5712e88f2   Amy Griffis   [PATCH] match aud...
1924
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1925
  	}
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1926
1927
1928
1929
  	if (inode)
  		audit_copy_inode(found_child, dentry, inode);
  	else
  		found_child->ino = (unsigned long)-1;
3e2efce06   Amy Griffis   [PATCH] fix fault...
1930
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
1931
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
1932
1933
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1934
1935
1936
1937
1938
1939
1940
   * 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...
1941
  int auditsc_get_stamp(struct audit_context *ctx,
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1942
  		       struct timespec *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1943
  {
48887e63d   Al Viro   [PATCH] fix broke...
1944
1945
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1946
1947
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1948
1949
1950
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
1951
1952
1953
1954
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
1955
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1956
  }
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1957
1958
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
da0a61049   Eric Paris   audit: loginuid f...
1959
1960
  static int audit_set_loginuid_perm(kuid_t loginuid)
  {
da0a61049   Eric Paris   audit: loginuid f...
1961
1962
1963
  	/* if we are unset, we don't need privs */
  	if (!audit_loginuid_set(current))
  		return 0;
21b85c31d   Eric Paris   audit: audit feat...
1964
1965
1966
  	/* 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...
1967
1968
1969
  	/* it is set, you need permission */
  	if (!capable(CAP_AUDIT_CONTROL))
  		return -EPERM;
d040e5af3   Eric Paris   audit: audit feat...
1970
1971
1972
  	/* 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...
1973
  	return 0;
da0a61049   Eric Paris   audit: loginuid f...
1974
1975
1976
1977
1978
1979
1980
  }
  
  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...
1981
  	uid_t uid, oldloginuid, loginuid;
da0a61049   Eric Paris   audit: loginuid f...
1982

c2412d91c   Gao feng   audit: don't gene...
1983
1984
  	if (!audit_enabled)
  		return;
da0a61049   Eric Paris   audit: loginuid f...
1985
  	uid = from_kuid(&init_user_ns, task_uid(current));
5ee9a75c9   Richard Guy Briggs   audit: fix dangli...
1986
1987
  	oldloginuid = from_kuid(&init_user_ns, koldloginuid);
  	loginuid = from_kuid(&init_user_ns, kloginuid),
da0a61049   Eric Paris   audit: loginuid f...
1988
1989
1990
1991
  
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
  	if (!ab)
  		return;
ddfad8aff   Eric Paris   audit: include su...
1992
1993
1994
1995
  	audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid);
  	audit_log_task_context(ab);
  	audit_log_format(ab, " old-auid=%u auid=%u old-ses=%u ses=%u res=%d",
  			 oldloginuid, loginuid, oldsessionid, sessionid, !rc);
da0a61049   Eric Paris   audit: loginuid f...
1996
1997
  	audit_log_end(ab);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1998
  /**
0a300be6d   Eric Paris   audit: remove tas...
1999
   * audit_set_loginuid - set current task's audit_context loginuid
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2000
2001
2002
2003
2004
2005
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
e1760bd5f   Eric W. Biederman   userns: Convert t...
2006
  int audit_set_loginuid(kuid_t loginuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2007
  {
0a300be6d   Eric Paris   audit: remove tas...
2008
  	struct task_struct *task = current;
9175c9d2a   Eric Paris   audit: fix type o...
2009
2010
  	unsigned int oldsessionid, sessionid = (unsigned int)-1;
  	kuid_t oldloginuid;
da0a61049   Eric Paris   audit: loginuid f...
2011
  	int rc;
41757106b   Steve Grubb   [PATCH] make set_...
2012

da0a61049   Eric Paris   audit: loginuid f...
2013
2014
2015
2016
2017
2018
  	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...
2019

81407c84a   Eric Paris   audit: allow unse...
2020
2021
  	/* are we setting or clearing? */
  	if (uid_valid(loginuid))
4440e8548   Eric Paris   audit: convert al...
2022
  		sessionid = (unsigned int)atomic_inc_return(&session_id);
bfef93a5d   Al Viro   [PATCH] get rid o...
2023

4746ec5b0   Eric Paris   [AUDIT] add sessi...
2024
  	task->sessionid = sessionid;
bfef93a5d   Al Viro   [PATCH] get rid o...
2025
  	task->loginuid = loginuid;
da0a61049   Eric Paris   audit: loginuid f...
2026
2027
2028
  out:
  	audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2029
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2030
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2031
2032
2033
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
2034
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2035
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2036
   */
df0a42837   Al Viro   switch mq_open() ...
2037
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2038
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2039
  	struct audit_context *context = current->audit_context;
564f6993f   Al Viro   sanitize audit_mq...
2040
2041
2042
2043
  	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 ...
2044

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

564f6993f   Al Viro   sanitize audit_mq...
2048
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2049
2050
2051
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2052
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2053
2054
2055
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2056
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2057
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2058
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2059
2060
  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 ...
2061
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2062
  	struct audit_context *context = current->audit_context;
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2063
  	struct timespec *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2064

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2065
2066
2067
2068
  	if (abs_timeout)
  		memcpy(p, abs_timeout, sizeof(struct timespec));
  	else
  		memset(p, 0, sizeof(struct timespec));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2069

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2070
2071
2072
  	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 ...
2073

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2074
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2075
2076
2077
2078
2079
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
2080
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2081
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2082
   */
20114f71b   Al Viro   sanitize audit_mq...
2083
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2084
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2085
  	struct audit_context *context = current->audit_context;
20114f71b   Al Viro   sanitize audit_mq...
2086
2087
2088
2089
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2090

20114f71b   Al Viro   sanitize audit_mq...
2091
2092
  	context->mq_notify.mqdes = mqdes;
  	context->type = AUDIT_MQ_NOTIFY;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2093
2094
2095
2096
2097
2098
2099
  }
  
  /**
   * __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 ...
2100
   */
7392906ea   Al Viro   sanitize audit_mq...
2101
  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2102
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2103
  	struct audit_context *context = current->audit_context;
7392906ea   Al Viro   sanitize audit_mq...
2104
2105
2106
  	context->mq_getsetattr.mqdes = mqdes;
  	context->mq_getsetattr.mqstat = *mqstat;
  	context->type = AUDIT_MQ_GETSETATTR;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2107
2108
2109
  }
  
  /**
073115d6b   Steve Grubb   [PATCH] Rework of...
2110
2111
2112
   * audit_ipc_obj - record audit data for ipc object
   * @ipcp: ipc permissions
   *
073115d6b   Steve Grubb   [PATCH] Rework of...
2113
   */
a33e67510   Al Viro   sanitize audit_ip...
2114
  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
073115d6b   Steve Grubb   [PATCH] Rework of...
2115
  {
073115d6b   Steve Grubb   [PATCH] Rework of...
2116
  	struct audit_context *context = current->audit_context;
a33e67510   Al Viro   sanitize audit_ip...
2117
2118
2119
  	context->ipc.uid = ipcp->uid;
  	context->ipc.gid = ipcp->gid;
  	context->ipc.mode = ipcp->mode;
e816f370c   Al Viro   sanitize audit_ip...
2120
  	context->ipc.has_perm = 0;
a33e67510   Al Viro   sanitize audit_ip...
2121
2122
  	security_ipc_getsecid(ipcp, &context->ipc.osid);
  	context->type = AUDIT_IPC;
073115d6b   Steve Grubb   [PATCH] Rework of...
2123
2124
2125
2126
  }
  
  /**
   * audit_ipc_set_perm - record audit data for new ipc permissions
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2127
2128
2129
2130
2131
   * @qbytes: msgq bytes
   * @uid: msgq user id
   * @gid: msgq group id
   * @mode: msgq mode (permissions)
   *
e816f370c   Al Viro   sanitize audit_ip...
2132
   * Called only after audit_ipc_obj().
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2133
   */
2570ebbd1   Al Viro   switch kern_ipc_p...
2134
  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
2135
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2136
  	struct audit_context *context = current->audit_context;
e816f370c   Al Viro   sanitize audit_ip...
2137
2138
2139
2140
2141
  	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
2142
  }
c2f0c7c35   Steve Grubb   The attached patc...
2143

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

d9cfea91e   Richard Guy Briggs   audit: move audit...
2148
2149
  	context->type = AUDIT_EXECVE;
  	context->execve.argc = bprm->argc;
473ae30bc   Al Viro   [PATCH] execve ar...
2150
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2151
2152
  /**
   * audit_socketcall - record audit data for sys_socketcall
2950fa9d3   Chen Gang   kernel: audit: be...
2153
   * @nargs: number of args, which should not be more than AUDITSC_ARGS.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2154
2155
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2156
   */
2950fa9d3   Chen Gang   kernel: audit: be...
2157
  int __audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2158
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2159
  	struct audit_context *context = current->audit_context;
2950fa9d3   Chen Gang   kernel: audit: be...
2160
2161
  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
  		return -EINVAL;
f3298dc4f   Al Viro   sanitize audit_so...
2162
2163
2164
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
2950fa9d3   Chen Gang   kernel: audit: be...
2165
  	return 0;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2166
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2167
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2168
2169
2170
2171
   * __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_...
2172
   */
157cf649a   Al Viro   sanitize audit_fd...
2173
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2174
2175
  {
  	struct audit_context *context = current->audit_context;
157cf649a   Al Viro   sanitize audit_fd...
2176
2177
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2178
2179
2180
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2181
2182
2183
2184
2185
2186
   * 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...
2187
  int __audit_sockaddr(int len, void *a)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2188
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2189
  	struct audit_context *context = current->audit_context;
4f6b434fe   Al Viro   don't reallocate ...
2190
2191
2192
2193
2194
2195
  	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...
2196

4f6b434fe   Al Viro   don't reallocate ...
2197
2198
  	context->sockaddr_len = len;
  	memcpy(context->sockaddr, a, len);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2199
2200
  	return 0;
  }
a5cb013da   Al Viro   [PATCH] auditing ...
2201
2202
2203
  void __audit_ptrace(struct task_struct *t)
  {
  	struct audit_context *context = current->audit_context;
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2204
  	context->target_pid = task_pid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2205
  	context->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2206
  	context->target_uid = task_uid(t);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2207
  	context->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2208
  	security_task_getsecid(t, &context->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2209
  	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
a5cb013da   Al Viro   [PATCH] auditing ...
2210
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2211
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2212
2213
2214
2215
2216
2217
2218
   * 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...
2219
  int __audit_signal_info(int sig, struct task_struct *t)
c2f0c7c35   Steve Grubb   The attached patc...
2220
  {
e54dc2431   Amy Griffis   [PATCH] audit sig...
2221
2222
2223
  	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...
2224
  	kuid_t uid = current_uid(), t_uid = task_uid(t);
e1396065e   Al Viro   [PATCH] collect s...
2225

175fc4842   Al Viro   fix oops in __aud...
2226
  	if (audit_pid && t->tgid == audit_pid) {
ee1d31566   Eric Paris   [PATCH] Audit: Co...
2227
  		if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2228
  			audit_sig_pid = task_pid_nr(tsk);
e1760bd5f   Eric W. Biederman   userns: Convert t...
2229
  			if (uid_valid(tsk->loginuid))
bfef93a5d   Al Viro   [PATCH] get rid o...
2230
  				audit_sig_uid = tsk->loginuid;
175fc4842   Al Viro   fix oops in __aud...
2231
  			else
c69e8d9c0   David Howells   CRED: Use RCU to ...
2232
  				audit_sig_uid = uid;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2233
  			security_task_getsecid(tsk, &audit_sig_sid);
175fc4842   Al Viro   fix oops in __aud...
2234
2235
2236
  		}
  		if (!audit_signals || audit_dummy_context())
  			return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2237
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
2238

e54dc2431   Amy Griffis   [PATCH] audit sig...
2239
2240
2241
  	/* optimize the common case by putting first signal recipient directly
  	 * in audit_context */
  	if (!ctx->target_pid) {
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2242
  		ctx->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2243
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2244
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2245
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2246
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2247
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
  		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:...
2261
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2262

f1dc4867f   Richard Guy Briggs   audit: anchor all...
2263
  	axp->target_pid[axp->pid_count] = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2264
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2265
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2266
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2267
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2268
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2269
2270
2271
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2272
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2273
2274
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2275
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2276
2277
2278
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2279
2280
2281
2282
   *
   * 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...
2283
2284
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2285
2286
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2287
2288
2289
2290
2291
2292
2293
2294
  {
  	struct audit_aux_data_bprm_fcaps *ax;
  	struct audit_context *context = current->audit_context;
  	struct cpu_vfs_cap_data vcaps;
  	struct dentry *dentry;
  
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
  	if (!ax)
d84f4f992   David Howells   CRED: Inaugurate ...
2295
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
  
  	ax->d.type = AUDIT_BPRM_FCAPS;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
  
  	dentry = dget(bprm->file->f_dentry);
  	get_vfs_caps_from_disk(dentry, &vcaps);
  	dput(dentry);
  
  	ax->fcap.permitted = vcaps.permitted;
  	ax->fcap.inheritable = vcaps.inheritable;
  	ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
  	ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
d84f4f992   David Howells   CRED: Inaugurate ...
2309
2310
2311
  	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...
2312

d84f4f992   David Howells   CRED: Inaugurate ...
2313
2314
2315
2316
  	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...
2317
2318
2319
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2320
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2321
2322
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2323
2324
2325
2326
   *
   * Record the aguments userspace sent to sys_capset for later printing by the
   * audit system if applicable
   */
ca24a23eb   Eric W. Biederman   audit: Simplify a...
2327
  void __audit_log_capset(const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2328
  {
e68b75a02   Eric Paris   When the capset s...
2329
  	struct audit_context *context = current->audit_context;
ca24a23eb   Eric W. Biederman   audit: Simplify a...
2330
  	context->capset.pid = task_pid_nr(current);
57f71a0af   Al Viro   sanitize audit_lo...
2331
2332
2333
2334
  	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...
2335
  }
120a795da   Al Viro   audit mmap
2336
2337
2338
2339
2340
2341
2342
  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...
2343
  static void audit_log_task(struct audit_buffer *ab)
85e7bac33   Eric Paris   seccomp: audit ab...
2344
  {
cca080d9b   Eric W. Biederman   userns: Convert a...
2345
2346
  	kuid_t auid, uid;
  	kgid_t gid;
85e7bac33   Eric Paris   seccomp: audit ab...
2347
  	unsigned int sessionid;
ff235f51a   Paul Davies C   audit: Added exe ...
2348
  	struct mm_struct *mm = current->mm;
85e7bac33   Eric Paris   seccomp: audit ab...
2349
2350
2351
2352
2353
2354
  
  	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...
2355
2356
2357
2358
  			 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...
2359
  	audit_log_task_context(ab);
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2360
  	audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
85e7bac33   Eric Paris   seccomp: audit ab...
2361
  	audit_log_untrustedstring(ab, current->comm);
ff235f51a   Paul Davies C   audit: Added exe ...
2362
2363
2364
2365
2366
2367
2368
  	if (mm) {
  		down_read(&mm->mmap_sem);
  		if (mm->exe_file)
  			audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
  		up_read(&mm->mmap_sem);
  	} else
  		audit_log_format(ab, " exe=(null)");
7b9205bd7   Kees Cook   audit: create exp...
2369
  }
e68b75a02   Eric Paris   When the capset s...
2370
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2371
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2372
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2373
2374
2375
2376
2377
2378
2379
   *
   * 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 ...
2380
2381
2382
2383
2384
2385
2386
2387
  
  	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...
2388
2389
  	if (unlikely(!ab))
  		return;
61c0ee879   Paul Davies C   audit: drop audit...
2390
2391
  	audit_log_task(ab);
  	audit_log_format(ab, " sig=%ld", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2392
2393
  	audit_log_end(ab);
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2394

3dc1c1b2d   Kees Cook   seccomp: remove d...
2395
  void __audit_seccomp(unsigned long syscall, long signr, int code)
85e7bac33   Eric Paris   seccomp: audit ab...
2396
2397
  {
  	struct audit_buffer *ab;
7b9205bd7   Kees Cook   audit: create exp...
2398
2399
2400
2401
2402
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
  	if (unlikely(!ab))
  		return;
  	audit_log_task(ab);
  	audit_log_format(ab, " sig=%ld", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2403
  	audit_log_format(ab, " syscall=%ld", syscall);
3dc1c1b2d   Kees Cook   seccomp: remove d...
2404
2405
2406
  	audit_log_format(ab, " compat=%d", is_compat_task());
  	audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
  	audit_log_format(ab, " code=0x%x", code);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2407
2408
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2409
2410
2411
2412
2413
2414
2415
2416
  
  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;
  }