Blame view

kernel/auditsc.c 65.5 KB
85c8721ff   David Woodhouse   audit: update poi...
1
  /* auditsc.c -- System-call auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
   * Handles all system-call specific auditing features.
   *
   * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
73241ccca   Amy Griffis   [PATCH] Collect m...
5
   * Copyright 2005 Hewlett-Packard Development Company, L.P.
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
6
   * Copyright (C) 2005, 2006 IBM Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
   * Many of the ideas implemented here are from Stephen C. Tweedie,
   * especially the idea of avoiding a copy by using getname.
   *
   * The method for actual interception of syscall entry and exit (not in
   * this file -- see entry.S) is based on a GPL'd patch written by
   * okir@suse.de and Copyright 2003 SuSE Linux AG.
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
32
33
34
   * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
   * 2006.
   *
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
35
36
37
   * The support of additional filter rules compares (>, <, >=, <=) was
   * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
   *
73241ccca   Amy Griffis   [PATCH] Collect m...
38
39
   * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
   * filesystem information.
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
40
41
42
   *
   * Subject and object context labeling support added by <danjones@us.ibm.com>
   * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
   */
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>
9dd813c15   Jan Kara   fsnotify: Move ma...
74
  #include <linux/fsnotify_backend.h>
fcf22d826   Paul Moore   audit: create pri...
75
  #include <uapi/linux/limits.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

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

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

55669bfa1   Al Viro   [PATCH] audit: AU...
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
162
  	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...
163
  static int audit_match_filetype(struct audit_context *ctx, int val)
8b67dca94   Al Viro   [PATCH] new predi...
164
  {
5195d8e21   Eric Paris   audit: dynamicall...
165
  	struct audit_names *n;
5ef30ee53   Eric Paris   audit: make filet...
166
  	umode_t mode = (umode_t)val;
1a61c88de   zhangxiliang   Re: [PATCH] Fix t...
167
168
169
  
  	if (unlikely(!ctx))
  		return 0;
5195d8e21   Eric Paris   audit: dynamicall...
170
  	list_for_each_entry(n, &ctx->names_list, list) {
84cb777e6   Richard Guy Briggs   audit: use macros...
171
  		if ((n->ino != AUDIT_INO_UNSET) &&
5195d8e21   Eric Paris   audit: dynamicall...
172
  		    ((n->mode & S_IFMT) == mode))
5ef30ee53   Eric Paris   audit: make filet...
173
174
  			return 1;
  	}
5195d8e21   Eric Paris   audit: dynamicall...
175

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

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

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

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

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

5b52330bb   Paul Moore   audit: fix auditd...
798
  	if (auditd_test_task(tsk))
0590b9335   Al Viro   fixing audit rule...
799
  		return;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
800
801
  
  	rcu_read_lock();
f368c07d7   Amy Griffis   [PATCH] audit: pa...
802

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

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

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

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

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

e1760bd5f   Eric W. Biederman   userns: Convert t...
951
952
  	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...
953
  			 from_kuid(&init_user_ns, uid), sessionid);
ad395abec   Eric Paris   Audit: do not pri...
954
955
956
957
958
959
960
961
  	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...
962
  	}
c2a7780ef   Eric Paris   [AUDIT] collect u...
963
964
  	audit_log_format(ab, " ocomm=");
  	audit_log_untrustedstring(ab, comm);
e54dc2431   Amy Griffis   [PATCH] audit sig...
965
  	audit_log_end(ab);
e54dc2431   Amy Griffis   [PATCH] audit sig...
966
967
968
  
  	return rc;
  }
43761473c   Paul Moore   audit: fix a doub...
969
970
  static void audit_log_execve_info(struct audit_context *context,
  				  struct audit_buffer **ab)
bdf4c48af   Peter Zijlstra   audit: rework exe...
971
  {
43761473c   Paul Moore   audit: fix a doub...
972
973
974
975
  	long len_max;
  	long len_rem;
  	long len_full;
  	long len_buf;
8443075ea   Richard Guy Briggs   audit: tame initi...
976
  	long len_abuf = 0;
43761473c   Paul Moore   audit: fix a doub...
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
  	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...
1003
  	}
43761473c   Paul Moore   audit: fix a doub...
1004
  	buf = buf_head;
040b3a2df   Peter Zijlstra   audit: fix two bu...
1005

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

43761473c   Paul Moore   audit: fix a doub...
1008
1009
1010
1011
1012
1013
1014
  	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...
1015
  	do {
43761473c   Paul Moore   audit: fix a doub...
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
  		/* 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...
1064

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

43761473c   Paul Moore   audit: fix a doub...
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
  		/* 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...
1083

43761473c   Paul Moore   audit: fix a doub...
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
  			/* 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...
1126

43761473c   Paul Moore   audit: fix a doub...
1127
1128
1129
1130
1131
1132
1133
1134
1135
  		/* 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...
1136

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

43761473c   Paul Moore   audit: fix a doub...
1139
1140
  out:
  	kfree(buf_head);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1141
  }
a33e67510   Al Viro   sanitize audit_ip...
1142
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
  {
  	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...
1159
1160
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1161
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
cca080d9b   Eric W. Biederman   userns: Convert a...
1162
1163
1164
  				 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...
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  		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...
1176
1177
1178
1179
  		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...
1180
1181
  			if (unlikely(!ab))
  				return;
e816f370c   Al Viro   sanitize audit_ip...
1182
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1183
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1184
1185
1186
1187
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
e816f370c   Al Viro   sanitize audit_ip...
1188
  		}
a33e67510   Al Viro   sanitize audit_ip...
1189
  		break; }
fe8e52b9b   Paul Moore   audit: remove unn...
1190
  	case AUDIT_MQ_OPEN:
564f6993f   Al Viro   sanitize audit_mq...
1191
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1192
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1193
1194
1195
1196
1197
1198
  			"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);
fe8e52b9b   Paul Moore   audit: remove unn...
1199
1200
  		break;
  	case AUDIT_MQ_SENDRECV:
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1201
1202
  		audit_log_format(ab,
  			"mqdes=%d msg_len=%zd msg_prio=%u "
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
1203
  			"abs_timeout_sec=%lld abs_timeout_nsec=%ld",
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1204
1205
1206
  			context->mq_sendrecv.mqdes,
  			context->mq_sendrecv.msg_len,
  			context->mq_sendrecv.msg_prio,
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
1207
  			(long long) context->mq_sendrecv.abs_timeout.tv_sec,
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1208
  			context->mq_sendrecv.abs_timeout.tv_nsec);
fe8e52b9b   Paul Moore   audit: remove unn...
1209
1210
  		break;
  	case AUDIT_MQ_NOTIFY:
20114f71b   Al Viro   sanitize audit_mq...
1211
1212
1213
  		audit_log_format(ab, "mqdes=%d sigev_signo=%d",
  				context->mq_notify.mqdes,
  				context->mq_notify.sigev_signo);
fe8e52b9b   Paul Moore   audit: remove unn...
1214
  		break;
7392906ea   Al Viro   sanitize audit_mq...
1215
1216
1217
1218
1219
1220
1221
1222
1223
  	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; }
fe8e52b9b   Paul Moore   audit: remove unn...
1224
  	case AUDIT_CAPSET:
57f71a0af   Al Viro   sanitize audit_lo...
1225
1226
1227
1228
  		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);
7786f6b6d   Richard Guy Briggs   audit: add ambien...
1229
  		audit_log_cap(ab, "cap_pa", &context->capset.cap.ambient);
fe8e52b9b   Paul Moore   audit: remove unn...
1230
1231
  		break;
  	case AUDIT_MMAP:
120a795da   Al Viro   audit mmap
1232
1233
  		audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
  				 context->mmap.flags);
fe8e52b9b   Paul Moore   audit: remove unn...
1234
1235
  		break;
  	case AUDIT_EXECVE:
d9cfea91e   Richard Guy Briggs   audit: move audit...
1236
  		audit_log_execve_info(context, &ab);
fe8e52b9b   Paul Moore   audit: remove unn...
1237
  		break;
ca86cad73   Richard Guy Briggs   audit: log module...
1238
1239
  	case AUDIT_KERN_MODULE:
  		audit_log_format(ab, "name=");
a1b5bcffe   Yi Wang   audit: fix potent...
1240
1241
1242
1243
1244
  		if (context->module.name) {
  			audit_log_untrustedstring(ab, context->module.name);
  			kfree(context->module.name);
  		} else
  			audit_log_format(ab, "(null)");
ca86cad73   Richard Guy Briggs   audit: log module...
1245
  		break;
f3298dc4f   Al Viro   sanitize audit_so...
1246
1247
1248
  	}
  	audit_log_end(ab);
  }
3f1c82502   William Roberts   audit: Audit proc...
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
  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_...
1301
  static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
  {
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1303
  	int i, call_panic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1305
  	struct audit_aux_data *aux;
5195d8e21   Eric Paris   audit: dynamicall...
1306
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1324
1325
1326
1327
1328
1329
  			 " 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...
1330

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

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

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

3fc689e96   Eric Paris   Any time fcaps or...
1342
1343
1344
1345
1346
1347
1348
1349
1350
  		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);
7786f6b6d   Richard Guy Briggs   audit: add ambien...
1351
1352
1353
1354
1355
  			audit_log_cap(ab, "old_pa", &axs->old_pcap.ambient);
  			audit_log_cap(ab, "pp", &axs->new_pcap.permitted);
  			audit_log_cap(ab, "pi", &axs->new_pcap.inheritable);
  			audit_log_cap(ab, "pe", &axs->new_pcap.effective);
  			audit_log_cap(ab, "pa", &axs->new_pcap.ambient);
3fc689e96   Eric Paris   Any time fcaps or...
1356
  			break; }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357
1358
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1359
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1360
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1361
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1362

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

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

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

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

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

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

916d75761   Al Viro   Fix rule eviction...
1526
1527
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(&context->killed_trees);
c62d773a3   Al Viro   audit: no nested ...
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
  	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
1541
  	}
c62d773a3   Al Viro   audit: no nested ...
1542
  	tsk->audit_context = context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1543
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1544
1545
1546
1547
1548
1549
1550
  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;
08991e83b   Jan Kara   fsnotify: Free fs...
1551
  	if (likely(!inode->i_fsnotify_marks))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
  		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...
1564
1565
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  		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...
1594
  		struct inode *inode = d_backing_inode(d);
08991e83b   Jan Kara   fsnotify: Free fs...
1595
  		if (inode && unlikely(inode->i_fsnotify_marks)) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
  			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...
1624
1625
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1626
1627
1628
1629
1630
1631
1632
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
  #endif
  }
78e2e802a   Jeff Layton   audit: add a new ...
1633
1634
  static struct audit_names *audit_alloc_name(struct audit_context *context,
  						unsigned char type)
5195d8e21   Eric Paris   audit: dynamicall...
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
  {
  	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...
1647
  	aname->ino = AUDIT_INO_UNSET;
78e2e802a   Jeff Layton   audit: add a new ...
1648
  	aname->type = type;
5195d8e21   Eric Paris   audit: dynamicall...
1649
1650
1651
  	list_add_tail(&aname->list, &context->names_list);
  
  	context->name_count++;
5195d8e21   Eric Paris   audit: dynamicall...
1652
1653
  	return aname;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1654
  /**
196a50855   Geliang Tang   audit: update the...
1655
   * __audit_reusename - fill out filename with info from existing entry
7ac86265d   Jeff Layton   audit: allow audi...
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
   * @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...
1671
1672
  		if (n->name->uptr == uptr) {
  			n->name->refcnt++;
7ac86265d   Jeff Layton   audit: allow audi...
1673
  			return n->name;
55422d0bd   Paul Moore   audit: replace ge...
1674
  		}
7ac86265d   Jeff Layton   audit: allow audi...
1675
1676
1677
1678
1679
  	}
  	return NULL;
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
1680
   * __audit_getname - add a name to the list
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1681
1682
1683
1684
1685
   * @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...
1686
  void __audit_getname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
1688
  {
  	struct audit_context *context = current->audit_context;
5195d8e21   Eric Paris   audit: dynamicall...
1689
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1690

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

78e2e802a   Jeff Layton   audit: add a new ...
1694
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1695
1696
1697
1698
1699
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
adb5c2473   Jeff Layton   audit: make audit...
1700
  	name->aname = n;
55422d0bd   Paul Moore   audit: replace ge...
1701
  	name->refcnt++;
5195d8e21   Eric Paris   audit: dynamicall...
1702

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1703
1704
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1705
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1706
  /**
bfcec7087   Jeff Layton   audit: set the na...
1707
   * __audit_inode - store the inode and device from a lookup
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1708
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1709
   * @dentry: dentry being audited
79f6530cb   Jeff Layton   audit: fix mq_ope...
1710
   * @flags: attributes for this particular entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1711
   */
adb5c2473   Jeff Layton   audit: make audit...
1712
  void __audit_inode(struct filename *name, const struct dentry *dentry,
79f6530cb   Jeff Layton   audit: fix mq_ope...
1713
  		   unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715
  	struct audit_context *context = current->audit_context;
d6335d77a   Andreas Gruenbacher   security: Make in...
1716
  	struct inode *inode = d_backing_inode(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1717
  	struct audit_names *n;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1718
  	bool parent = flags & AUDIT_INODE_PARENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1719
1720
1721
  
  	if (!context->in_syscall)
  		return;
5195d8e21   Eric Paris   audit: dynamicall...
1722

9cec9d68a   Jeff Layton   audit: no need to...
1723
1724
  	if (!name)
  		goto out_alloc;
adb5c2473   Jeff Layton   audit: make audit...
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
  	/*
  	 * 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...
1740
  	list_for_each_entry_reverse(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  		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...
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
  			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
1763
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1764

9cec9d68a   Jeff Layton   audit: no need to...
1765
  out_alloc:
4a9284360   Paul Moore   audit: correctly ...
1766
1767
  	/* 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...
1768
1769
  	if (!n)
  		return;
fcf22d826   Paul Moore   audit: create pri...
1770
  	if (name) {
fd3522fdc   Paul Moore   audit: enable fil...
1771
  		n->name = name;
55422d0bd   Paul Moore   audit: replace ge...
1772
  		name->refcnt++;
fcf22d826   Paul Moore   audit: create pri...
1773
  	}
4a9284360   Paul Moore   audit: correctly ...
1774

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

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1820
  	/* look for a parent entry first */
5195d8e21   Eric Paris   audit: dynamicall...
1821
  	list_for_each_entry(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
1822
1823
1824
  		if (!n->name ||
  		    (n->type != AUDIT_TYPE_PARENT &&
  		     n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
1825
  			continue;
57c59f583   Paul Moore   audit: fix filena...
1826
1827
1828
1829
1830
  		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 _...
1831
1832
  			found_parent = n;
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1833
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1834
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1835

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1836
  	/* is there a matching child entry? */
5195d8e21   Eric Paris   audit: dynamicall...
1837
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1838
  		/* can only match entries that have a name */
57c59f583   Paul Moore   audit: fix filena...
1839
1840
  		if (!n->name ||
  		    (n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
1841
  			continue;
91a27b2a7   Jeff Layton   vfs: define struc...
1842
1843
  		if (!strcmp(dname, n->name->name) ||
  		    !audit_compare_dname_path(dname, n->name->name,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1844
1845
  						found_parent ?
  						found_parent->name_len :
e3d6b07b8   Jeff Layton   audit: optimize a...
1846
  						AUDIT_NAME_FULL)) {
57c59f583   Paul Moore   audit: fix filena...
1847
1848
  			if (n->type == AUDIT_TYPE_UNKNOWN)
  				n->type = type;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1849
1850
  			found_child = n;
  			break;
5712e88f2   Amy Griffis   [PATCH] match aud...
1851
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1852
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1853

5712e88f2   Amy Griffis   [PATCH] match aud...
1854
  	if (!found_parent) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1855
1856
  		/* create a new, "anonymous" parent record */
  		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
5195d8e21   Eric Paris   audit: dynamicall...
1857
  		if (!n)
ac9910ce0   Steve Grubb   [PATCH] name_coun...
1858
  			return;
5195d8e21   Eric Paris   audit: dynamicall...
1859
  		audit_copy_inode(n, NULL, parent);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1860
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
1861
1862
  
  	if (!found_child) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1863
1864
  		found_child = audit_alloc_name(context, type);
  		if (!found_child)
5712e88f2   Amy Griffis   [PATCH] match aud...
1865
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
1866
1867
1868
1869
1870
  
  		/* 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 _...
1871
1872
  			found_child->name = found_parent->name;
  			found_child->name_len = AUDIT_NAME_FULL;
55422d0bd   Paul Moore   audit: replace ge...
1873
  			found_child->name->refcnt++;
5712e88f2   Amy Griffis   [PATCH] match aud...
1874
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
1875
  	}
57c59f583   Paul Moore   audit: fix filena...
1876

4fa6b5ecb   Jeff Layton   audit: overhaul _...
1877
1878
1879
  	if (inode)
  		audit_copy_inode(found_child, dentry, inode);
  	else
84cb777e6   Richard Guy Briggs   audit: use macros...
1880
  		found_child->ino = AUDIT_INO_UNSET;
3e2efce06   Amy Griffis   [PATCH] fix fault...
1881
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
1882
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
1883
1884
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1885
1886
   * auditsc_get_stamp - get local copies of audit_context values
   * @ctx: audit_context for the task
2115bb250   Deepa Dinamani   audit: Use timesp...
1887
   * @t: timespec64 to store time recorded in the audit_context
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1888
1889
1890
1891
   * @serial: serial value that is recorded in the audit_context
   *
   * Also sets the context as auditable.
   */
48887e63d   Al Viro   [PATCH] fix broke...
1892
  int auditsc_get_stamp(struct audit_context *ctx,
2115bb250   Deepa Dinamani   audit: Use timesp...
1893
  		       struct timespec64 *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1894
  {
48887e63d   Al Viro   [PATCH] fix broke...
1895
1896
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1897
1898
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1899
1900
1901
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
1902
1903
1904
1905
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
1906
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1907
  }
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1908
1909
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
da0a61049   Eric Paris   audit: loginuid f...
1910
1911
  static int audit_set_loginuid_perm(kuid_t loginuid)
  {
da0a61049   Eric Paris   audit: loginuid f...
1912
1913
1914
  	/* if we are unset, we don't need privs */
  	if (!audit_loginuid_set(current))
  		return 0;
21b85c31d   Eric Paris   audit: audit feat...
1915
1916
1917
  	/* 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...
1918
1919
1920
  	/* it is set, you need permission */
  	if (!capable(CAP_AUDIT_CONTROL))
  		return -EPERM;
d040e5af3   Eric Paris   audit: audit feat...
1921
1922
1923
  	/* 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...
1924
  	return 0;
da0a61049   Eric Paris   audit: loginuid f...
1925
1926
1927
1928
1929
1930
1931
  }
  
  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...
1932
  	uid_t uid, oldloginuid, loginuid;
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1933
  	struct tty_struct *tty;
da0a61049   Eric Paris   audit: loginuid f...
1934

c2412d91c   Gao feng   audit: don't gene...
1935
1936
  	if (!audit_enabled)
  		return;
76a658c20   Richard Guy Briggs   audit: move calcs...
1937
1938
1939
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
  	if (!ab)
  		return;
da0a61049   Eric Paris   audit: loginuid f...
1940
  	uid = from_kuid(&init_user_ns, task_uid(current));
5ee9a75c9   Richard Guy Briggs   audit: fix dangli...
1941
1942
  	oldloginuid = from_kuid(&init_user_ns, koldloginuid);
  	loginuid = from_kuid(&init_user_ns, kloginuid),
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1943
  	tty = audit_get_tty(current);
da0a61049   Eric Paris   audit: loginuid f...
1944

fa2bea2f5   Paul Moore   audit: consistent...
1945
  	audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
ddfad8aff   Eric Paris   audit: include su...
1946
  	audit_log_task_context(ab);
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
1947
1948
1949
1950
  	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...
1951
1952
  	audit_log_end(ab);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1953
  /**
0a300be6d   Eric Paris   audit: remove tas...
1954
   * audit_set_loginuid - set current task's audit_context loginuid
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1955
1956
1957
1958
1959
1960
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
e1760bd5f   Eric W. Biederman   userns: Convert t...
1961
  int audit_set_loginuid(kuid_t loginuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1962
  {
0a300be6d   Eric Paris   audit: remove tas...
1963
  	struct task_struct *task = current;
9175c9d2a   Eric Paris   audit: fix type o...
1964
1965
  	unsigned int oldsessionid, sessionid = (unsigned int)-1;
  	kuid_t oldloginuid;
da0a61049   Eric Paris   audit: loginuid f...
1966
  	int rc;
41757106b   Steve Grubb   [PATCH] make set_...
1967

da0a61049   Eric Paris   audit: loginuid f...
1968
1969
1970
1971
1972
1973
  	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...
1974

81407c84a   Eric Paris   audit: allow unse...
1975
  	/* are we setting or clearing? */
833fc48d1   Richard Guy Briggs   audit: skip sessi...
1976
  	if (uid_valid(loginuid)) {
4440e8548   Eric Paris   audit: convert al...
1977
  		sessionid = (unsigned int)atomic_inc_return(&session_id);
833fc48d1   Richard Guy Briggs   audit: skip sessi...
1978
1979
1980
  		if (unlikely(sessionid == (unsigned int)-1))
  			sessionid = (unsigned int)atomic_inc_return(&session_id);
  	}
bfef93a5d   Al Viro   [PATCH] get rid o...
1981

4746ec5b0   Eric Paris   [AUDIT] add sessi...
1982
  	task->sessionid = sessionid;
bfef93a5d   Al Viro   [PATCH] get rid o...
1983
  	task->loginuid = loginuid;
da0a61049   Eric Paris   audit: loginuid f...
1984
1985
1986
  out:
  	audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc);
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1987
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1988
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1989
1990
1991
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
1992
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1993
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1994
   */
df0a42837   Al Viro   switch mq_open() ...
1995
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1996
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
1997
  	struct audit_context *context = current->audit_context;
564f6993f   Al Viro   sanitize audit_mq...
1998
1999
2000
2001
  	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 ...
2002

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

564f6993f   Al Viro   sanitize audit_mq...
2006
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2007
2008
2009
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2010
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2011
2012
2013
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2014
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2015
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2016
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2017
  void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2018
  			const struct timespec64 *abs_timeout)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2019
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2020
  	struct audit_context *context = current->audit_context;
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2021
  	struct timespec64 *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2022

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2023
  	if (abs_timeout)
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2024
  		memcpy(p, abs_timeout, sizeof(*p));
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2025
  	else
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2026
  		memset(p, 0, sizeof(*p));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2027

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2028
2029
2030
  	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 ...
2031

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2032
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2033
2034
2035
2036
2037
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
2038
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2039
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2040
   */
20114f71b   Al Viro   sanitize audit_mq...
2041
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2042
  {
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2043
  	struct audit_context *context = current->audit_context;
20114f71b   Al Viro   sanitize audit_mq...
2044
2045
2046
2047
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2048

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

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

d9cfea91e   Richard Guy Briggs   audit: move audit...
2106
2107
  	context->type = AUDIT_EXECVE;
  	context->execve.argc = bprm->argc;
473ae30bc   Al Viro   [PATCH] execve ar...
2108
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2109
  /**
196a50855   Geliang Tang   audit: update the...
2110
   * __audit_socketcall - record audit data for sys_socketcall
2950fa9d3   Chen Gang   kernel: audit: be...
2111
   * @nargs: number of args, which should not be more than AUDITSC_ARGS.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2112
2113
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2114
   */
2950fa9d3   Chen Gang   kernel: audit: be...
2115
  int __audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2116
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2117
  	struct audit_context *context = current->audit_context;
2950fa9d3   Chen Gang   kernel: audit: be...
2118
2119
  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
  		return -EINVAL;
f3298dc4f   Al Viro   sanitize audit_so...
2120
2121
2122
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
2950fa9d3   Chen Gang   kernel: audit: be...
2123
  	return 0;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2124
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2125
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2126
2127
2128
2129
   * __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_...
2130
   */
157cf649a   Al Viro   sanitize audit_fd...
2131
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2132
2133
  {
  	struct audit_context *context = current->audit_context;
157cf649a   Al Viro   sanitize audit_fd...
2134
2135
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2136
2137
2138
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
2139
   * __audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2140
2141
2142
2143
2144
   * @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...
2145
  int __audit_sockaddr(int len, void *a)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2146
  {
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2147
  	struct audit_context *context = current->audit_context;
4f6b434fe   Al Viro   don't reallocate ...
2148
2149
2150
2151
2152
2153
  	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...
2154

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

ab6434a13   Paul Moore   audit: move audit...
2184
2185
2186
2187
2188
2189
2190
2191
2192
  	if (auditd_test_task(t) &&
  	    (sig == SIGTERM || sig == SIGHUP ||
  	     sig == SIGUSR1 || sig == SIGUSR2)) {
  		audit_sig_pid = task_tgid_nr(tsk);
  		if (uid_valid(tsk->loginuid))
  			audit_sig_uid = tsk->loginuid;
  		else
  			audit_sig_uid = uid;
  		security_task_getsecid(tsk, &audit_sig_sid);
c2f0c7c35   Steve Grubb   The attached patc...
2193
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
2194

ab6434a13   Paul Moore   audit: move audit...
2195
2196
  	if (!audit_signals || audit_dummy_context())
  		return 0;
e54dc2431   Amy Griffis   [PATCH] audit sig...
2197
2198
2199
  	/* optimize the common case by putting first signal recipient directly
  	 * in audit_context */
  	if (!ctx->target_pid) {
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2200
  		ctx->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2201
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2202
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2203
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2204
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2205
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
  		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:...
2219
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2220

f1dc4867f   Richard Guy Briggs   audit: anchor all...
2221
  	axp->target_pid[axp->pid_count] = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2222
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2223
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2224
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2225
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2226
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2227
2228
2229
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2230
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2231
2232
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2233
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2234
2235
2236
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2237
2238
2239
2240
   *
   * 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...
2241
2242
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2243
2244
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2245
2246
2247
2248
  {
  	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...
2249
2250
2251
  
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
  	if (!ax)
d84f4f992   David Howells   CRED: Inaugurate ...
2252
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2253
2254
2255
2256
  
  	ax->d.type = AUDIT_BPRM_FCAPS;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
f4a4a8b12   Al Viro   file->f_path.dent...
2257
  	get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
3fc689e96   Eric Paris   Any time fcaps or...
2258
2259
2260
2261
2262
  
  	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 ...
2263
2264
2265
  	ax->old_pcap.permitted   = old->cap_permitted;
  	ax->old_pcap.inheritable = old->cap_inheritable;
  	ax->old_pcap.effective   = old->cap_effective;
7786f6b6d   Richard Guy Briggs   audit: add ambien...
2266
  	ax->old_pcap.ambient     = old->cap_ambient;
3fc689e96   Eric Paris   Any time fcaps or...
2267

d84f4f992   David Howells   CRED: Inaugurate ...
2268
2269
2270
  	ax->new_pcap.permitted   = new->cap_permitted;
  	ax->new_pcap.inheritable = new->cap_inheritable;
  	ax->new_pcap.effective   = new->cap_effective;
7786f6b6d   Richard Guy Briggs   audit: add ambien...
2271
  	ax->new_pcap.ambient     = new->cap_ambient;
d84f4f992   David Howells   CRED: Inaugurate ...
2272
  	return 0;
3fc689e96   Eric Paris   Any time fcaps or...
2273
2274
2275
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2276
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2277
2278
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2279
   *
da3dae54e   Masanari Iida   Documentation: Do...
2280
   * Record the arguments userspace sent to sys_capset for later printing by the
e68b75a02   Eric Paris   When the capset s...
2281
2282
   * audit system if applicable
   */
ca24a23eb   Eric W. Biederman   audit: Simplify a...
2283
  void __audit_log_capset(const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2284
  {
e68b75a02   Eric Paris   When the capset s...
2285
  	struct audit_context *context = current->audit_context;
fa2bea2f5   Paul Moore   audit: consistent...
2286
  	context->capset.pid = task_tgid_nr(current);
57f71a0af   Al Viro   sanitize audit_lo...
2287
2288
2289
  	context->capset.cap.effective   = new->cap_effective;
  	context->capset.cap.inheritable = new->cap_effective;
  	context->capset.cap.permitted   = new->cap_permitted;
7786f6b6d   Richard Guy Briggs   audit: add ambien...
2290
  	context->capset.cap.ambient     = new->cap_ambient;
57f71a0af   Al Viro   sanitize audit_lo...
2291
  	context->type = AUDIT_CAPSET;
e68b75a02   Eric Paris   When the capset s...
2292
  }
120a795da   Al Viro   audit mmap
2293
2294
2295
2296
2297
2298
2299
  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;
  }
ca86cad73   Richard Guy Briggs   audit: log module...
2300
2301
2302
  void __audit_log_kern_module(char *name)
  {
  	struct audit_context *context = current->audit_context;
a1b5bcffe   Yi Wang   audit: fix potent...
2303
2304
2305
  	context->module.name = kstrdup(name, GFP_KERNEL);
  	if (!context->module.name)
  		audit_log_lost("out of memory in __audit_log_kern_module");
ca86cad73   Richard Guy Briggs   audit: log module...
2306
2307
  	context->type = AUDIT_KERN_MODULE;
  }
7b9205bd7   Kees Cook   audit: create exp...
2308
  static void audit_log_task(struct audit_buffer *ab)
85e7bac33   Eric Paris   seccomp: audit ab...
2309
  {
cca080d9b   Eric W. Biederman   userns: Convert a...
2310
2311
  	kuid_t auid, uid;
  	kgid_t gid;
85e7bac33   Eric Paris   seccomp: audit ab...
2312
  	unsigned int sessionid;
9eab339b1   Richard Guy Briggs   audit: get comm u...
2313
  	char comm[sizeof(current->comm)];
85e7bac33   Eric Paris   seccomp: audit ab...
2314
2315
2316
2317
2318
2319
  
  	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...
2320
2321
2322
2323
  			 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...
2324
  	audit_log_task_context(ab);
fa2bea2f5   Paul Moore   audit: consistent...
2325
  	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
9eab339b1   Richard Guy Briggs   audit: get comm u...
2326
  	audit_log_untrustedstring(ab, get_task_comm(comm, current));
4766b199e   Davidlohr Bueso   audit: consolidat...
2327
  	audit_log_d_path_exe(ab, current->mm);
7b9205bd7   Kees Cook   audit: create exp...
2328
  }
e68b75a02   Eric Paris   When the capset s...
2329
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2330
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2331
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2332
2333
2334
2335
2336
2337
2338
   *
   * 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 ...
2339
2340
2341
2342
2343
2344
2345
2346
  
  	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...
2347
2348
  	if (unlikely(!ab))
  		return;
61c0ee879   Paul Davies C   audit: drop audit...
2349
  	audit_log_task(ab);
89670affa   Steve Grubb   audit: Make AUDIT...
2350
  	audit_log_format(ab, " sig=%ld res=1", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2351
2352
  	audit_log_end(ab);
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2353

3dc1c1b2d   Kees Cook   seccomp: remove d...
2354
  void __audit_seccomp(unsigned long syscall, long signr, int code)
85e7bac33   Eric Paris   seccomp: audit ab...
2355
2356
  {
  	struct audit_buffer *ab;
7b9205bd7   Kees Cook   audit: create exp...
2357
2358
2359
2360
  	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...
2361
  	audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
efbc0fbf3   Andy Lutomirski   auditsc: for secc...
2362
2363
  			 signr, syscall_get_arch(), syscall,
  			 in_compat_syscall(), KSTK_EIP(current), code);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2364
2365
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2366
2367
2368
2369
2370
2371
2372
2373
  
  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;
  }