Blame view

kernel/auditsc.c 64.4 KB
85c8721ff   David Woodhouse   audit: update poi...
1
  /* auditsc.c -- System-call auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
   * Handles all system-call specific auditing features.
   *
   * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
73241ccca   Amy Griffis   [PATCH] Collect m...
5
   * Copyright 2005 Hewlett-Packard Development Company, L.P.
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
6
   * Copyright (C) 2005, 2006 IBM Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
   * Many of the ideas implemented here are from Stephen C. Tweedie,
   * especially the idea of avoiding a copy by using getname.
   *
   * The method for actual interception of syscall entry and exit (not in
   * this file -- see entry.S) is based on a GPL'd patch written by
   * okir@suse.de and Copyright 2003 SuSE Linux AG.
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
32
33
34
   * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
   * 2006.
   *
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
35
36
37
   * The support of additional filter rules compares (>, <, >=, <=) was
   * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
   *
73241ccca   Amy Griffis   [PATCH] Collect m...
38
39
   * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
   * filesystem information.
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
40
41
42
   *
   * Subject and object context labeling support added by <danjones@us.ibm.com>
   * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
   */
f952d10ff   Richard Guy Briggs   audit: Use more c...
44
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  #include <asm/types.h>
60063497a   Arun Sharma   atomic: use <linu...
47
  #include <linux/atomic.h>
73241ccca   Amy Griffis   [PATCH] Collect m...
48
49
  #include <linux/fs.h>
  #include <linux/namei.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
51
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
52
  #include <linux/slab.h>
011161051   Stephen Smalley   AUDIT: Avoid slee...
53
  #include <linux/mount.h>
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
54
  #include <linux/socket.h>
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
55
  #include <linux/mqueue.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  #include <linux/audit.h>
  #include <linux/personality.h>
  #include <linux/time.h>
5bb289b5a   David Woodhouse   AUDIT: Clean up u...
59
  #include <linux/netlink.h>
f55619642   David Woodhouse   AUDIT: Avoid sche...
60
  #include <linux/compiler.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #include <asm/unistd.h>
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
62
  #include <linux/security.h>
fe7752bab   David Woodhouse   [PATCH] Fix audit...
63
  #include <linux/list.h>
473ae30bc   Al Viro   [PATCH] execve ar...
64
  #include <linux/binfmts.h>
a1f8e7f7f   Al Viro   [PATCH] severing ...
65
  #include <linux/highmem.h>
f46038ff7   Al Viro   [PATCH] log ppid
66
  #include <linux/syscalls.h>
84db564aa   Richard Guy Briggs   audit: add arch f...
67
  #include <asm/syscall.h>
851f7ff56   Eric Paris   This patch will p...
68
  #include <linux/capability.h>
5ad4e53bd   Al Viro   Get rid of indire...
69
  #include <linux/fs_struct.h>
3dc1c1b2d   Kees Cook   seccomp: remove d...
70
  #include <linux/compat.h>
3f1c82502   William Roberts   audit: Audit proc...
71
  #include <linux/ctype.h>
fcf22d826   Paul Moore   audit: create pri...
72
  #include <linux/string.h>
43761473c   Paul Moore   audit: fix a doub...
73
  #include <linux/uaccess.h>
fcf22d826   Paul Moore   audit: create pri...
74
  #include <uapi/linux/limits.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

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

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

55669bfa1   Al Viro   [PATCH] audit: AU...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  	switch (audit_classify_syscall(ctx->arch, n)) {
  	case 0:	/* native */
  		if ((mask & AUDIT_PERM_WRITE) &&
  		     audit_match_class(AUDIT_CLASS_WRITE, n))
  			return 1;
  		if ((mask & AUDIT_PERM_READ) &&
  		     audit_match_class(AUDIT_CLASS_READ, n))
  			return 1;
  		if ((mask & AUDIT_PERM_ATTR) &&
  		     audit_match_class(AUDIT_CLASS_CHATTR, n))
  			return 1;
  		return 0;
  	case 1: /* 32bit on biarch */
  		if ((mask & AUDIT_PERM_WRITE) &&
  		     audit_match_class(AUDIT_CLASS_WRITE_32, n))
  			return 1;
  		if ((mask & AUDIT_PERM_READ) &&
  		     audit_match_class(AUDIT_CLASS_READ_32, n))
  			return 1;
  		if ((mask & AUDIT_PERM_ATTR) &&
  		     audit_match_class(AUDIT_CLASS_CHATTR_32, n))
  			return 1;
  		return 0;
  	case 2: /* open */
  		return mask & ACC_MODE(ctx->argv[1]);
  	case 3: /* openat */
  		return mask & ACC_MODE(ctx->argv[2]);
  	case 4: /* socketcall */
  		return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND);
  	case 5: /* execve */
  		return mask & AUDIT_PERM_EXEC;
  	default:
  		return 0;
  	}
  }
5ef30ee53   Eric Paris   audit: make filet...
162
  static int audit_match_filetype(struct audit_context *ctx, int val)
8b67dca94   Al Viro   [PATCH] new predi...
163
  {
5195d8e21   Eric Paris   audit: dynamicall...
164
  	struct audit_names *n;
5ef30ee53   Eric Paris   audit: make filet...
165
  	umode_t mode = (umode_t)val;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
166
167
168
  
  	if (unlikely(!ctx))
  		return 0;
5195d8e21   Eric Paris   audit: dynamicall...
169
  	list_for_each_entry(n, &ctx->names_list, list) {
84cb777e6   Richard Guy Briggs   audit: use macros...
170
  		if ((n->ino != AUDIT_INO_UNSET) &&
5195d8e21   Eric Paris   audit: dynamicall...
171
  		    ((n->mode & S_IFMT) == mode))
5ef30ee53   Eric Paris   audit: make filet...
172
173
  			return 1;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
174

5ef30ee53   Eric Paris   audit: make filet...
175
  	return 0;
8b67dca94   Al Viro   [PATCH] new predi...
176
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
177
178
179
180
181
182
183
184
185
186
187
  /*
   * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
   * ->first_trees points to its beginning, ->trees - to the current end of data.
   * ->tree_count is the number of free entries in array pointed to by ->trees.
   * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
   * "empty" becomes (p, p, 31) afterwards.  We don't shrink the list (and seriously,
   * it's going to remain 1-element for almost any setup) until we free context itself.
   * References in it _are_ dropped - at the same time we free/drop aux stuff.
   */
  
  #ifdef CONFIG_AUDIT_TREE
679173b72   Eric Paris   audit: audit_set_...
188
189
190
191
192
193
194
  static void audit_set_auditable(struct audit_context *ctx)
  {
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
  {
  	struct audit_tree_refs *p = ctx->trees;
  	int left = ctx->tree_count;
  	if (likely(left)) {
  		p->c[--left] = chunk;
  		ctx->tree_count = left;
  		return 1;
  	}
  	if (!p)
  		return 0;
  	p = p->next;
  	if (p) {
  		p->c[30] = chunk;
  		ctx->trees = p;
  		ctx->tree_count = 30;
  		return 1;
  	}
  	return 0;
  }
  
  static int grow_tree_refs(struct audit_context *ctx)
  {
  	struct audit_tree_refs *p = ctx->trees;
  	ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
  	if (!ctx->trees) {
  		ctx->trees = p;
  		return 0;
  	}
  	if (p)
  		p->next = ctx->trees;
  	else
  		ctx->first_trees = ctx->trees;
  	ctx->tree_count = 31;
  	return 1;
  }
  #endif
  
  static void unroll_tree_refs(struct audit_context *ctx,
  		      struct audit_tree_refs *p, int count)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_tree_refs *q;
  	int n;
  	if (!p) {
  		/* we started with empty chain */
  		p = ctx->first_trees;
  		count = 31;
  		/* if the very first allocation has failed, nothing to do */
  		if (!p)
  			return;
  	}
  	n = count;
  	for (q = p; q != ctx->trees; q = q->next, n = 31) {
  		while (n--) {
  			audit_put_chunk(q->c[n]);
  			q->c[n] = NULL;
  		}
  	}
  	while (n-- > ctx->tree_count) {
  		audit_put_chunk(q->c[n]);
  		q->c[n] = NULL;
  	}
  	ctx->trees = p;
  	ctx->tree_count = count;
  #endif
  }
  
  static void free_tree_refs(struct audit_context *ctx)
  {
  	struct audit_tree_refs *p, *q;
  	for (p = ctx->first_trees; p; p = q) {
  		q = p->next;
  		kfree(p);
  	}
  }
  
  static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
  {
  #ifdef CONFIG_AUDIT_TREE
  	struct audit_tree_refs *p;
  	int n;
  	if (!tree)
  		return 0;
  	/* full ones */
  	for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
  		for (n = 0; n < 31; n++)
  			if (audit_tree_match(p->c[n], tree))
  				return 1;
  	}
  	/* partial */
  	if (p) {
  		for (n = ctx->tree_count; n < 31; n++)
  			if (audit_tree_match(p->c[n], tree))
  				return 1;
  	}
  #endif
  	return 0;
  }
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
294
295
296
297
  static int audit_compare_uid(kuid_t uid,
  			     struct audit_names *name,
  			     struct audit_field *f,
  			     struct audit_context *ctx)
b34b03932   Eric Paris   audit: complex in...
298
299
  {
  	struct audit_names *n;
b34b03932   Eric Paris   audit: complex in...
300
  	int rc;
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
301
   
b34b03932   Eric Paris   audit: complex in...
302
  	if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
303
  		rc = audit_uid_comparator(uid, f->op, name->uid);
b34b03932   Eric Paris   audit: complex in...
304
305
306
  		if (rc)
  			return rc;
  	}
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
307
   
b34b03932   Eric Paris   audit: complex in...
308
309
  	if (ctx) {
  		list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
310
311
312
313
314
315
316
  			rc = audit_uid_comparator(uid, f->op, n->uid);
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
b34b03932   Eric Paris   audit: complex in...
317

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

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

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

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

0590b9335   Al Viro   fixing audit rule...
828
829
830
  	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
831
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
833
834
  	tsk->audit_context = NULL;
  	return context;
  }
3f1c82502   William Roberts   audit: Audit proc...
835
836
837
838
839
840
  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
841
842
  static inline void audit_free_names(struct audit_context *context)
  {
5195d8e21   Eric Paris   audit: dynamicall...
843
  	struct audit_names *n, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844

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

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

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

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

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

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

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

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

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

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1306
1307
1308
1309
1310
1311
  			 " 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...
1312

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

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

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

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

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

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

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

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

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

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

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

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

78e2e802a   Jeff Layton   audit: add a new ...
1674
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1675
1676
1677
1678
1679
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
adb5c2473   Jeff Layton   audit: make audit...
1680
  	name->aname = n;
55422d0bd   Paul Moore   audit: replace ge...
1681
  	name->refcnt++;
5195d8e21   Eric Paris   audit: dynamicall...
1682

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

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

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

5195d8e21   Eric Paris   audit: dynamicall...
1755
  out:
bfcec7087   Jeff Layton   audit: set the na...
1756
  	if (parent) {
91a27b2a7   Jeff Layton   vfs: define struc...
1757
  		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
bfcec7087   Jeff Layton   audit: set the na...
1758
  		n->type = AUDIT_TYPE_PARENT;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1759
1760
  		if (flags & AUDIT_INODE_HIDDEN)
  			n->hidden = true;
bfcec7087   Jeff Layton   audit: set the na...
1761
1762
1763
1764
  	} else {
  		n->name_len = AUDIT_NAME_FULL;
  		n->type = AUDIT_TYPE_NORMAL;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1765
  	handle_path(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1766
  	audit_copy_inode(n, dentry, inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1767
  }
9f45f5bf3   Al Viro   new helper: audit...
1768
1769
1770
1771
  void __audit_file(const struct file *file)
  {
  	__audit_inode(NULL, file->f_path.dentry, 0);
  }
73241ccca   Amy Griffis   [PATCH] Collect m...
1772
  /**
c43a25abb   Jeff Layton   audit: reverse ar...
1773
   * __audit_inode_child - collect inode info for created/removed objects
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1774
   * @parent: inode of dentry parent
c43a25abb   Jeff Layton   audit: reverse ar...
1775
   * @dentry: dentry being audited
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1776
   * @type:   AUDIT_TYPE_* value that we're looking for
73241ccca   Amy Griffis   [PATCH] Collect m...
1777
1778
1779
1780
1781
1782
1783
1784
1785
   *
   * For syscalls that create or remove filesystem objects, audit_inode
   * can only collect information for the filesystem object's parent.
   * This call updates the audit context with the child's information.
   * Syscalls that create a new filesystem object must be hooked after
   * the object is created.  Syscalls that remove a filesystem object
   * must be hooked prior, in order to capture the target inode during
   * unsuccessful attempts.
   */
d6335d77a   Andreas Gruenbacher   security: Make in...
1786
  void __audit_inode_child(struct inode *parent,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1787
1788
  			 const struct dentry *dentry,
  			 const unsigned char type)
73241ccca   Amy Griffis   [PATCH] Collect m...
1789
  {
73241ccca   Amy Griffis   [PATCH] Collect m...
1790
  	struct audit_context *context = current->audit_context;
d6335d77a   Andreas Gruenbacher   security: Make in...
1791
  	struct inode *inode = d_backing_inode(dentry);
cccc6bba3   Al Viro   Lose the first ar...
1792
  	const char *dname = dentry->d_name.name;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1793
  	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
73241ccca   Amy Griffis   [PATCH] Collect m...
1794
1795
1796
  
  	if (!context->in_syscall)
  		return;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1797
1798
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
1799

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

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

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

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

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

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

da0a61049   Eric Paris   audit: loginuid f...
1948
1949
1950
1951
1952
1953
  	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...
1954

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

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

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

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

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2000
2001
2002
2003
  	if (abs_timeout)
  		memcpy(p, abs_timeout, sizeof(struct timespec));
  	else
  		memset(p, 0, sizeof(struct timespec));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2004

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2005
2006
2007
  	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 ...
2008

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

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

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

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

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

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

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

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

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

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