Blame view

kernel/auditsc.c 69.7 KB
85c8721ff   David Woodhouse   audit: update poi...
1
  /* auditsc.c -- System-call auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
   * Handles all system-call specific auditing features.
   *
   * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
73241ccca   Amy Griffis   [PATCH] Collect m...
5
   * Copyright 2005 Hewlett-Packard Development Company, L.P.
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
6
   * Copyright (C) 2005, 2006 IBM Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
   * Many of the ideas implemented here are from Stephen C. Tweedie,
   * especially the idea of avoiding a copy by using getname.
   *
   * The method for actual interception of syscall entry and exit (not in
   * this file -- see entry.S) is based on a GPL'd patch written by
   * okir@suse.de and Copyright 2003 SuSE Linux AG.
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
32
33
34
   * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
   * 2006.
   *
b63862f46   Dustin Kirkland   [PATCH] Filter ru...
35
36
37
   * The support of additional filter rules compares (>, <, >=, <=) was
   * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
   *
73241ccca   Amy Griffis   [PATCH] Collect m...
38
39
   * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
   * filesystem information.
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
40
41
42
   *
   * Subject and object context labeling support added by <danjones@us.ibm.com>
   * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
   */
f952d10ff   Richard Guy Briggs   audit: Use more c...
44
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  #include <asm/types.h>
60063497a   Arun Sharma   atomic: use <linu...
47
  #include <linux/atomic.h>
73241ccca   Amy Griffis   [PATCH] Collect m...
48
49
  #include <linux/fs.h>
  #include <linux/namei.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
51
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
52
  #include <linux/slab.h>
011161051   Stephen Smalley   AUDIT: Avoid slee...
53
  #include <linux/mount.h>
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
54
  #include <linux/socket.h>
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
55
  #include <linux/mqueue.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  #include <linux/audit.h>
  #include <linux/personality.h>
  #include <linux/time.h>
5bb289b5a   David Woodhouse   AUDIT: Clean up u...
59
  #include <linux/netlink.h>
f55619642   David Woodhouse   AUDIT: Avoid sche...
60
  #include <linux/compiler.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #include <asm/unistd.h>
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
62
  #include <linux/security.h>
fe7752bab   David Woodhouse   [PATCH] Fix audit...
63
  #include <linux/list.h>
473ae30bc   Al Viro   [PATCH] execve ar...
64
  #include <linux/binfmts.h>
a1f8e7f7f   Al Viro   [PATCH] severing ...
65
  #include <linux/highmem.h>
f46038ff7   Al Viro   [PATCH] log ppid
66
  #include <linux/syscalls.h>
84db564aa   Richard Guy Briggs   audit: add arch f...
67
  #include <asm/syscall.h>
851f7ff56   Eric Paris   This patch will p...
68
  #include <linux/capability.h>
5ad4e53bd   Al Viro   Get rid of indire...
69
  #include <linux/fs_struct.h>
3dc1c1b2d   Kees Cook   seccomp: remove d...
70
  #include <linux/compat.h>
3f1c82502   William Roberts   audit: Audit proc...
71
  #include <linux/ctype.h>
fcf22d826   Paul Moore   audit: create pri...
72
  #include <linux/string.h>
43761473c   Paul Moore   audit: fix a doub...
73
  #include <linux/uaccess.h>
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
  /*
   * 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.
   */
679173b72   Eric Paris   audit: audit_set_...
187
188
189
190
191
192
193
  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...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  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;
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
230
231
232
233
  
  static void unroll_tree_refs(struct audit_context *ctx,
  		      struct audit_tree_refs *p, int count)
  {
74c3cbe33   Al Viro   [PATCH] audit: wa...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  	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;
74c3cbe33   Al Viro   [PATCH] audit: wa...
257
258
259
260
261
262
263
264
265
266
267
268
269
  }
  
  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)
  {
74c3cbe33   Al Viro   [PATCH] audit: wa...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  	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;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
286
287
  	return 0;
  }
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
288
289
290
291
  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...
292
293
  {
  	struct audit_names *n;
b34b03932   Eric Paris   audit: complex in...
294
  	int rc;
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
295
   
b34b03932   Eric Paris   audit: complex in...
296
  	if (name) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
297
  		rc = audit_uid_comparator(uid, f->op, name->uid);
b34b03932   Eric Paris   audit: complex in...
298
299
300
  		if (rc)
  			return rc;
  	}
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
301
   
b34b03932   Eric Paris   audit: complex in...
302
303
  	if (ctx) {
  		list_for_each_entry(n, &ctx->names_list, list) {
ca57ec0f0   Eric W. Biederman   audit: Add typesp...
304
305
306
307
308
309
310
  			rc = audit_uid_comparator(uid, f->op, n->uid);
  			if (rc)
  				return rc;
  		}
  	}
  	return 0;
  }
b34b03932   Eric Paris   audit: complex in...
311

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

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

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

5b52330bb   Paul Moore   audit: fix auditd...
765
  	if (auditd_test_task(tsk))
f7056d64a   David Woodhouse   AUDIT: Really exe...
766
  		return AUDIT_DISABLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
  	rcu_read_lock();
699c1868a   Richard Guy Briggs   audit: purge unne...
768
769
770
771
772
773
774
  	list_for_each_entry_rcu(e, list, list) {
  		if (audit_in_mask(&e->rule, ctx->major) &&
  		    audit_filter_rules(tsk, &e->rule, ctx, NULL,
  				       &state, false)) {
  			rcu_read_unlock();
  			ctx->current_state = state;
  			return state;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
775
776
777
778
779
  		}
  	}
  	rcu_read_unlock();
  	return AUDIT_BUILD_CONTEXT;
  }
5195d8e21   Eric Paris   audit: dynamicall...
780
781
782
783
784
785
786
  /*
   * 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...
787
788
789
790
  	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...
791
  	list_for_each_entry_rcu(e, list, list) {
a3c549311   Andy Lutomirski   auditsc: audit_kr...
792
  		if (audit_in_mask(&e->rule, ctx->major) &&
5195d8e21   Eric Paris   audit: dynamicall...
793
794
795
796
797
  		    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
  			ctx->current_state = state;
  			return 1;
  		}
  	}
5195d8e21   Eric Paris   audit: dynamicall...
798
799
800
801
  	return 0;
  }
  
  /* At syscall exit time, this filter is called if any audit_names have been
f368c07d7   Amy Griffis   [PATCH] audit: pa...
802
   * collected during syscall processing.  We only check rules in sublists at hash
5195d8e21   Eric Paris   audit: dynamicall...
803
   * buckets applicable to the inode numbers in audit_names.
f368c07d7   Amy Griffis   [PATCH] audit: pa...
804
805
   * Regarding audit_state, same rules apply as for audit_filter_syscall().
   */
0590b9335   Al Viro   fixing audit rule...
806
  void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
f368c07d7   Amy Griffis   [PATCH] audit: pa...
807
  {
5195d8e21   Eric Paris   audit: dynamicall...
808
  	struct audit_names *n;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
809

5b52330bb   Paul Moore   audit: fix auditd...
810
  	if (auditd_test_task(tsk))
0590b9335   Al Viro   fixing audit rule...
811
  		return;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
812
813
  
  	rcu_read_lock();
f368c07d7   Amy Griffis   [PATCH] audit: pa...
814

5195d8e21   Eric Paris   audit: dynamicall...
815
816
817
  	list_for_each_entry(n, &ctx->names_list, list) {
  		if (audit_filter_inode_name(tsk, n, ctx))
  			break;
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
818
819
  	}
  	rcu_read_unlock();
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
820
  }
3f1c82502   William Roberts   audit: Audit proc...
821
822
823
824
825
826
  static inline void audit_proctitle_free(struct audit_context *context)
  {
  	kfree(context->proctitle.value);
  	context->proctitle.value = NULL;
  	context->proctitle.len = 0;
  }
95e0b46fc   Li RongQing   audit: fix a meml...
827
828
829
830
831
832
833
  static inline void audit_free_module(struct audit_context *context)
  {
  	if (context->type == AUDIT_KERN_MODULE) {
  		kfree(context->module.name);
  		context->module.name = NULL;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
835
  static inline void audit_free_names(struct audit_context *context)
  {
5195d8e21   Eric Paris   audit: dynamicall...
836
  	struct audit_names *n, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837

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

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

c0b0ae8a8   Richard Guy Briggs   audit: use inline...
906
  	audit_set_context(tsk, context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
908
909
910
911
912
  	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
  	return 0;
  }
  
  static inline void audit_free_context(struct audit_context *context)
  {
95e0b46fc   Li RongQing   audit: fix a meml...
913
  	audit_free_module(context);
c62d773a3   Al Viro   audit: no nested ...
914
915
916
917
918
919
  	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...
920
  	audit_proctitle_free(context);
c62d773a3   Al Viro   audit: no nested ...
921
  	kfree(context);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
  }
e54dc2431   Amy Griffis   [PATCH] audit sig...
923
  static int audit_log_pid_context(struct audit_context *context, pid_t pid,
cca080d9b   Eric W. Biederman   userns: Convert a...
924
  				 kuid_t auid, kuid_t uid, unsigned int sessionid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
925
  				 u32 sid, char *comm)
e54dc2431   Amy Griffis   [PATCH] audit sig...
926
927
  {
  	struct audit_buffer *ab;
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
928
  	char *ctx = NULL;
e54dc2431   Amy Griffis   [PATCH] audit sig...
929
930
931
932
933
  	u32 len;
  	int rc = 0;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
  	if (!ab)
6246ccab9   Eric Paris   [AUDIT] do not pa...
934
  		return rc;
e54dc2431   Amy Griffis   [PATCH] audit sig...
935

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

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

43761473c   Paul Moore   audit: fix a doub...
993
994
995
996
997
998
999
  	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...
1000
  	do {
43761473c   Paul Moore   audit: fix a doub...
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  		/* 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...
1049

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

43761473c   Paul Moore   audit: fix a doub...
1054
  		/* write as much as we can to the audit log */
ea956d8be   Richard Guy Briggs   audit: print empt...
1055
  		if (len_buf >= 0) {
43761473c   Paul Moore   audit: fix a doub...
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
  			/* 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...
1068

43761473c   Paul Moore   audit: fix a doub...
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
  			/* 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...
1111

43761473c   Paul Moore   audit: fix a doub...
1112
1113
1114
1115
1116
1117
1118
1119
1120
  		/* 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...
1121

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

43761473c   Paul Moore   audit: fix a doub...
1124
1125
  out:
  	kfree(buf_head);
bdf4c48af   Peter Zijlstra   audit: rework exe...
1126
  }
2efa48fec   YueHaibing   audit: Make audit...
1127
1128
  static void audit_log_cap(struct audit_buffer *ab, char *prefix,
  			  kernel_cap_t *cap)
5f3d544f1   Richard Guy Briggs   audit: remove aud...
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
  {
  	int i;
  
  	if (cap_isclear(*cap)) {
  		audit_log_format(ab, " %s=0", prefix);
  		return;
  	}
  	audit_log_format(ab, " %s=", prefix);
  	CAP_FOR_EACH_U32(i)
  		audit_log_format(ab, "%08x", cap->cap[CAP_LAST_U32 - i]);
  }
  
  static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
  {
  	if (name->fcap_ver == -1) {
  		audit_log_format(ab, " cap_fe=? cap_fver=? cap_fp=? cap_fi=?");
  		return;
  	}
  	audit_log_cap(ab, "cap_fp", &name->fcap.permitted);
  	audit_log_cap(ab, "cap_fi", &name->fcap.inheritable);
  	audit_log_format(ab, " cap_fe=%d cap_fver=%x cap_frootid=%d",
  			 name->fcap.fE, name->fcap_ver,
  			 from_kuid(&init_user_ns, name->fcap.rootid));
  }
a33e67510   Al Viro   sanitize audit_ip...
1153
  static void show_special(struct audit_context *context, int *call_panic)
f3298dc4f   Al Viro   sanitize audit_so...
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  {
  	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...
1170
1171
  	case AUDIT_IPC: {
  		u32 osid = context->ipc.osid;
2570ebbd1   Al Viro   switch kern_ipc_p...
1172
  		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
cca080d9b   Eric W. Biederman   userns: Convert a...
1173
1174
1175
  				 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...
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
  		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...
1187
1188
1189
1190
  		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...
1191
1192
  			if (unlikely(!ab))
  				return;
e816f370c   Al Viro   sanitize audit_ip...
1193
  			audit_log_format(ab,
2570ebbd1   Al Viro   switch kern_ipc_p...
1194
  				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
e816f370c   Al Viro   sanitize audit_ip...
1195
1196
1197
1198
  				context->ipc.qbytes,
  				context->ipc.perm_uid,
  				context->ipc.perm_gid,
  				context->ipc.perm_mode);
e816f370c   Al Viro   sanitize audit_ip...
1199
  		}
a33e67510   Al Viro   sanitize audit_ip...
1200
  		break; }
fe8e52b9b   Paul Moore   audit: remove unn...
1201
  	case AUDIT_MQ_OPEN:
564f6993f   Al Viro   sanitize audit_mq...
1202
  		audit_log_format(ab,
df0a42837   Al Viro   switch mq_open() ...
1203
  			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
564f6993f   Al Viro   sanitize audit_mq...
1204
1205
1206
1207
1208
1209
  			"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...
1210
1211
  		break;
  	case AUDIT_MQ_SENDRECV:
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1212
1213
  		audit_log_format(ab,
  			"mqdes=%d msg_len=%zd msg_prio=%u "
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
1214
  			"abs_timeout_sec=%lld abs_timeout_nsec=%ld",
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1215
1216
1217
  			context->mq_sendrecv.mqdes,
  			context->mq_sendrecv.msg_len,
  			context->mq_sendrecv.msg_prio,
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
1218
  			(long long) context->mq_sendrecv.abs_timeout.tv_sec,
c32c8af43   Al Viro   sanitize AUDIT_MQ...
1219
  			context->mq_sendrecv.abs_timeout.tv_nsec);
fe8e52b9b   Paul Moore   audit: remove unn...
1220
1221
  		break;
  	case AUDIT_MQ_NOTIFY:
20114f71b   Al Viro   sanitize audit_mq...
1222
1223
1224
  		audit_log_format(ab, "mqdes=%d sigev_signo=%d",
  				context->mq_notify.mqdes,
  				context->mq_notify.sigev_signo);
fe8e52b9b   Paul Moore   audit: remove unn...
1225
  		break;
7392906ea   Al Viro   sanitize audit_mq...
1226
1227
1228
1229
1230
1231
1232
1233
1234
  	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...
1235
  	case AUDIT_CAPSET:
57f71a0af   Al Viro   sanitize audit_lo...
1236
1237
1238
1239
  		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...
1240
  		audit_log_cap(ab, "cap_pa", &context->capset.cap.ambient);
fe8e52b9b   Paul Moore   audit: remove unn...
1241
1242
  		break;
  	case AUDIT_MMAP:
120a795da   Al Viro   audit mmap
1243
1244
  		audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
  				 context->mmap.flags);
fe8e52b9b   Paul Moore   audit: remove unn...
1245
1246
  		break;
  	case AUDIT_EXECVE:
d9cfea91e   Richard Guy Briggs   audit: move audit...
1247
  		audit_log_execve_info(context, &ab);
fe8e52b9b   Paul Moore   audit: remove unn...
1248
  		break;
ca86cad73   Richard Guy Briggs   audit: log module...
1249
1250
  	case AUDIT_KERN_MODULE:
  		audit_log_format(ab, "name=");
b305f7ed0   Yi Wang   audit: fix potent...
1251
1252
  		if (context->module.name) {
  			audit_log_untrustedstring(ab, context->module.name);
b305f7ed0   Yi Wang   audit: fix potent...
1253
1254
  		} else
  			audit_log_format(ab, "(null)");
ca86cad73   Richard Guy Briggs   audit: log module...
1255
  		break;
f3298dc4f   Al Viro   sanitize audit_so...
1256
1257
1258
  	}
  	audit_log_end(ab);
  }
3f1c82502   William Roberts   audit: Audit proc...
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
  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;
  }
5f3d544f1   Richard Guy Briggs   audit: remove aud...
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
  /*
   * audit_log_name - produce AUDIT_PATH record from struct audit_names
   * @context: audit_context for the task
   * @n: audit_names structure with reportable details
   * @path: optional path to report instead of audit_names->name
   * @record_num: record number to report when handling a list of names
   * @call_panic: optional pointer to int that will be updated if secid fails
   */
  static void audit_log_name(struct audit_context *context, struct audit_names *n,
  		    const struct path *path, int record_num, int *call_panic)
  {
  	struct audit_buffer *ab;
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
  	if (!ab)
  		return;
  
  	audit_log_format(ab, "item=%d", record_num);
  
  	if (path)
  		audit_log_d_path(ab, " name=", path);
  	else if (n->name) {
  		switch (n->name_len) {
  		case AUDIT_NAME_FULL:
  			/* log the full path */
  			audit_log_format(ab, " name=");
  			audit_log_untrustedstring(ab, n->name->name);
  			break;
  		case 0:
  			/* name was specified as a relative path and the
  			 * directory component is the cwd
  			 */
  			audit_log_d_path(ab, " name=", &context->pwd);
  			break;
  		default:
  			/* log the name's directory component */
  			audit_log_format(ab, " name=");
  			audit_log_n_untrustedstring(ab, n->name->name,
  						    n->name_len);
  		}
  	} else
  		audit_log_format(ab, " name=(null)");
  
  	if (n->ino != AUDIT_INO_UNSET)
  		audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#ho ouid=%u ogid=%u rdev=%02x:%02x",
  				 n->ino,
  				 MAJOR(n->dev),
  				 MINOR(n->dev),
  				 n->mode,
  				 from_kuid(&init_user_ns, n->uid),
  				 from_kgid(&init_user_ns, n->gid),
  				 MAJOR(n->rdev),
  				 MINOR(n->rdev));
  	if (n->osid != 0) {
  		char *ctx = NULL;
  		u32 len;
  
  		if (security_secid_to_secctx(
  			n->osid, &ctx, &len)) {
  			audit_log_format(ab, " osid=%u", n->osid);
  			if (call_panic)
  				*call_panic = 2;
  		} else {
  			audit_log_format(ab, " obj=%s", ctx);
  			security_release_secctx(ctx, len);
  		}
  	}
  
  	/* log the audit_names record type */
  	switch (n->type) {
  	case AUDIT_TYPE_NORMAL:
  		audit_log_format(ab, " nametype=NORMAL");
  		break;
  	case AUDIT_TYPE_PARENT:
  		audit_log_format(ab, " nametype=PARENT");
  		break;
  	case AUDIT_TYPE_CHILD_DELETE:
  		audit_log_format(ab, " nametype=DELETE");
  		break;
  	case AUDIT_TYPE_CHILD_CREATE:
  		audit_log_format(ab, " nametype=CREATE");
  		break;
  	default:
  		audit_log_format(ab, " nametype=UNKNOWN");
  		break;
  	}
  
  	audit_log_fcaps(ab, n);
  	audit_log_end(ab);
  }
2a1fe215e   Paul Moore   audit: use curren...
1360
  static void audit_log_proctitle(void)
3f1c82502   William Roberts   audit: Audit proc...
1361
1362
1363
1364
1365
  {
  	int res;
  	char *buf;
  	char *msg = "(null)";
  	int len = strlen(msg);
2a1fe215e   Paul Moore   audit: use curren...
1366
  	struct audit_context *context = audit_context();
3f1c82502   William Roberts   audit: Audit proc...
1367
  	struct audit_buffer *ab;
2a1fe215e   Paul Moore   audit: use curren...
1368
1369
  	if (!context || context->dummy)
  		return;
3f1c82502   William Roberts   audit: Audit proc...
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
  	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 */
2a1fe215e   Paul Moore   audit: use curren...
1382
  		res = get_cmdline(current, buf, MAX_PROCTITLE_AUDIT_LEN);
3f1c82502   William Roberts   audit: Audit proc...
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  		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);
  }
2a1fe215e   Paul Moore   audit: use curren...
1401
  static void audit_log_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1402
  {
9c7aa6aa7   Steve Grubb   [PATCH] change ls...
1403
  	int i, call_panic = 0;
2a1fe215e   Paul Moore   audit: use curren...
1404
  	struct audit_context *context = audit_context();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405
  	struct audit_buffer *ab;
7551ced33   David Woodhouse   AUDIT: Defer free...
1406
  	struct audit_aux_data *aux;
5195d8e21   Eric Paris   audit: dynamicall...
1407
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408

2a1fe215e   Paul Moore   audit: use curren...
1409
  	context->personality = current->personality;
e495149b1   Al Viro   [PATCH] drop gfp_...
1410
1411
  
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412
1413
  	if (!ab)
  		return;		/* audit_panic has been called */
bccf6ae08   David Woodhouse   AUDIT: Unify auid...
1414
1415
  	audit_log_format(ab, "arch=%x syscall=%d",
  			 context->arch, context->major);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
1417
1418
  	if (context->personality != PER_LINUX)
  		audit_log_format(ab, " per=%lx", context->personality);
  	if (context->return_valid)
9f8dbe9c9   Daniel Walker   whitespace fixes:...
1419
  		audit_log_format(ab, " success=%s exit=%ld",
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1420
1421
  				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
  				 context->return_code);
eb84a20e9   Alan Cox   [PATCH] audit/acc...
1422

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1423
  	audit_log_format(ab,
e23eb920b   Peter Moody   audit: export aud...
1424
1425
1426
1427
1428
1429
  			 " 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...
1430

2a1fe215e   Paul Moore   audit: use curren...
1431
  	audit_log_task_info(ab);
9d9609851   Eric Paris   Audit: clean up a...
1432
  	audit_log_key(ab, context->filterkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1433
  	audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1434

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

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

3fc689e96   Eric Paris   Any time fcaps or...
1442
1443
1444
1445
1446
1447
1448
1449
1450
  		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...
1451
1452
1453
1454
1455
  			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);
2fec30e24   Richard Guy Briggs   audit: add suppor...
1456
1457
1458
  			audit_log_format(ab, " frootid=%d",
  					 from_kuid(&init_user_ns,
  						   axs->fcap.rootid));
3fc689e96   Eric Paris   Any time fcaps or...
1459
  			break; }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
1461
  		}
  		audit_log_end(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1462
  	}
f3298dc4f   Al Viro   sanitize audit_so...
1463
  	if (context->type)
a33e67510   Al Viro   sanitize audit_ip...
1464
  		show_special(context, &call_panic);
f3298dc4f   Al Viro   sanitize audit_so...
1465

157cf649a   Al Viro   sanitize audit_fd...
1466
1467
1468
1469
1470
1471
1472
1473
  	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 ...
1474
1475
1476
1477
1478
1479
1480
1481
1482
  	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...
1483
1484
  	for (aux = context->aux_pids; aux; aux = aux->next) {
  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431   Amy Griffis   [PATCH] audit sig...
1485
1486
1487
  
  		for (i = 0; i < axs->pid_count; i++)
  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1488
1489
  						  axs->target_auid[i],
  						  axs->target_uid[i],
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1490
  						  axs->target_sessionid[i],
c2a7780ef   Eric Paris   [AUDIT] collect u...
1491
1492
  						  axs->target_sid[i],
  						  axs->target_comm[i]))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1493
  				call_panic = 1;
a5cb013da   Al Viro   [PATCH] auditing ...
1494
  	}
e54dc2431   Amy Griffis   [PATCH] audit sig...
1495
1496
  	if (context->target_pid &&
  	    audit_log_pid_context(context, context->target_pid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1497
  				  context->target_auid, context->target_uid,
4746ec5b0   Eric Paris   [AUDIT] add sessi...
1498
  				  context->target_sessionid,
c2a7780ef   Eric Paris   [AUDIT] collect u...
1499
  				  context->target_sid, context->target_comm))
e54dc2431   Amy Griffis   [PATCH] audit sig...
1500
  			call_panic = 1;
44707fdf5   Jan Blunck   d_path: Use struc...
1501
  	if (context->pwd.dentry && context->pwd.mnt) {
e495149b1   Al Viro   [PATCH] drop gfp_...
1502
  		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1503
  		if (ab) {
0b7a0fdb2   Steve Grubb   audit: fix whites...
1504
  			audit_log_d_path(ab, "cwd=", &context->pwd);
8f37d47c9   David Woodhouse   AUDIT: Record wor...
1505
1506
1507
  			audit_log_end(ab);
  		}
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
1508

5195d8e21   Eric Paris   audit: dynamicall...
1509
  	i = 0;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1510
1511
1512
  	list_for_each_entry(n, &context->names_list, list) {
  		if (n->hidden)
  			continue;
b24a30a73   Eric Paris   audit: fix event ...
1513
  		audit_log_name(context, n, NULL, i++, &call_panic);
79f6530cb   Jeff Layton   audit: fix mq_ope...
1514
  	}
c0641f28d   Eric Paris   [AUDIT] Add End o...
1515

2a1fe215e   Paul Moore   audit: use curren...
1516
  	audit_log_proctitle();
3f1c82502   William Roberts   audit: Audit proc...
1517

c0641f28d   Eric Paris   [AUDIT] Add End o...
1518
1519
1520
1521
  	/* 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...
1522
1523
  	if (call_panic)
  		audit_panic("error converting sid to string");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1524
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1525
  /**
196a50855   Geliang Tang   audit: update the...
1526
   * __audit_free - free a per-task audit context
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1527
1528
   * @tsk: task whose audit context block to free
   *
fa84cb935   Al Viro   [PATCH] move call...
1529
   * Called from copy_process and do_exit
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1530
   */
a4ff8dba7   Eric Paris   audit: inline aud...
1531
  void __audit_free(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
  {
2a1fe215e   Paul Moore   audit: use curren...
1533
  	struct audit_context *context = tsk->audit_context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1534

56179a6ec   Eric Paris   audit: drop some ...
1535
  	if (!context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1536
  		return;
9e36a5d49   Richard Guy Briggs   audit: hand taken...
1537
1538
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(context);
2a1fe215e   Paul Moore   audit: use curren...
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
  	/* We are called either by do_exit() or the fork() error handling code;
  	 * in the former case tsk == current and in the latter tsk is a
  	 * random task_struct that doesn't doesn't have any meaningful data we
  	 * need to log via audit_log_exit().
  	 */
  	if (tsk == current && !context->dummy && context->in_syscall) {
  		context->return_valid = 0;
  		context->return_code = 0;
  
  		audit_filter_syscall(tsk, context,
  				     &audit_filter_list[AUDIT_FILTER_EXIT]);
  		audit_filter_inodes(tsk, context);
  		if (context->current_state == AUDIT_RECORD_CONTEXT)
  			audit_log_exit();
  	}
2a1fe215e   Paul Moore   audit: use curren...
1554
  	audit_set_context(tsk, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1555
1556
  	audit_free_context(context);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1557
  /**
196a50855   Geliang Tang   audit: update the...
1558
   * __audit_syscall_entry - fill in an audit record at syscall entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1559
1560
1561
1562
1563
1564
1565
   * @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
1566
1567
1568
1569
1570
   * 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...
1571
1572
   * be written).
   */
b4f0d3755   Richard Guy Briggs   audit: x86: drop ...
1573
1574
  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
1575
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
1576
  	struct audit_context *context = audit_context();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
  	enum audit_state     state;
94d14e3e7   Richard Guy Briggs   audit: bail befor...
1578
  	if (!audit_enabled || !context)
86a1c34a9   Roland McGrath   x86_64 syscall au...
1579
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1580

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1581
  	BUG_ON(context->in_syscall || context->name_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1582
  	state = context->state;
5260ecc2e   Richard Guy Briggs   audit: deprecate ...
1583
1584
  	if (state == AUDIT_DISABLED)
  		return;
d51374adf   Al Viro   [PATCH] mark cont...
1585
  	context->dummy = !audit_n_rules;
0590b9335   Al Viro   fixing audit rule...
1586
1587
  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
  		context->prio = 0;
cdfb6b341   Richard Guy Briggs   audit: use inline...
1588
  		if (auditd_test_task(current))
5260ecc2e   Richard Guy Briggs   audit: deprecate ...
1589
  			return;
0590b9335   Al Viro   fixing audit rule...
1590
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591

16add4116   Dmitry V. Levin   syscall_get_arch:...
1592
  	context->arch	    = syscall_get_arch(current);
5260ecc2e   Richard Guy Briggs   audit: deprecate ...
1593
1594
1595
1596
1597
  	context->major      = major;
  	context->argv[0]    = a1;
  	context->argv[1]    = a2;
  	context->argv[2]    = a3;
  	context->argv[3]    = a4;
ce625a801   David Woodhouse   AUDIT: Reduce con...
1598
  	context->serial     = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1599
  	context->in_syscall = 1;
0590b9335   Al Viro   fixing audit rule...
1600
  	context->current_state  = state;
419c58f11   Alexander Viro   [PATCH] PPID filt...
1601
  	context->ppid       = 0;
290e44b7d   Paul Moore   audit: use ktime_...
1602
  	ktime_get_coarse_real_ts64(&context->ctime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1604
  /**
196a50855   Geliang Tang   audit: update the...
1605
   * __audit_syscall_exit - deallocate audit context after a system call
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1606
1607
   * @success: success value of the syscall
   * @return_code: return value of the syscall
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1608
1609
   *
   * Tear down after system call.  If the audit context has been marked as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1610
   * auditable (either because of the AUDIT_RECORD_CONTEXT state from
42ae610c1   Randy Dunlap   kernel-doc: fix n...
1611
   * filtering, or because some other part of the kernel wrote an audit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
   * message), then write out the syscall information.  In call cases,
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1613
1614
   * free the names stored from getname().
   */
d7e7528bc   Eric Paris   Audit: push audit...
1615
  void __audit_syscall_exit(int success, long return_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1616
1617
  {
  	struct audit_context *context;
2a1fe215e   Paul Moore   audit: use curren...
1618
  	context = audit_context();
56179a6ec   Eric Paris   audit: drop some ...
1619
  	if (!context)
97e94c453   Al Viro   [PATCH] no need t...
1620
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621

9e36a5d49   Richard Guy Briggs   audit: hand taken...
1622
1623
  	if (!list_empty(&context->killed_trees))
  		audit_kill_trees(context);
2a1fe215e   Paul Moore   audit: use curren...
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
  	if (!context->dummy && context->in_syscall) {
  		if (success)
  			context->return_valid = AUDITSC_SUCCESS;
  		else
  			context->return_valid = AUDITSC_FAILURE;
  
  		/*
  		 * 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;
  
  		audit_filter_syscall(current, context,
  				     &audit_filter_list[AUDIT_FILTER_EXIT]);
  		audit_filter_inodes(current, context);
  		if (context->current_state == AUDIT_RECORD_CONTEXT)
  			audit_log_exit();
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
1655
  
  	context->in_syscall = 0;
0590b9335   Al Viro   fixing audit rule...
1656
  	context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
2fd6f58ba   David Woodhouse   [AUDIT] Don't all...
1657

95e0b46fc   Li RongQing   audit: fix a meml...
1658
  	audit_free_module(context);
c62d773a3   Al Viro   audit: no nested ...
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
  	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
1672
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
  }
74c3cbe33   Al Viro   [PATCH] audit: wa...
1674
1675
  static inline void handle_one(const struct inode *inode)
  {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1676
1677
1678
1679
  	struct audit_context *context;
  	struct audit_tree_refs *p;
  	struct audit_chunk *chunk;
  	int count;
08991e83b   Jan Kara   fsnotify: Free fs...
1680
  	if (likely(!inode->i_fsnotify_marks))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1681
  		return;
cdfb6b341   Richard Guy Briggs   audit: use inline...
1682
  	context = audit_context();
74c3cbe33   Al Viro   [PATCH] audit: wa...
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
  	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...
1693
1694
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1695
1696
1697
1698
1699
1700
  		audit_set_auditable(context);
  		audit_put_chunk(chunk);
  		unroll_tree_refs(context, p, count);
  		return;
  	}
  	put_tree_ref(context, chunk);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1701
1702
1703
1704
  }
  
  static void handle_path(const struct dentry *dentry)
  {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1705
1706
1707
1708
1709
1710
  	struct audit_context *context;
  	struct audit_tree_refs *p;
  	const struct dentry *d, *parent;
  	struct audit_chunk *drop;
  	unsigned long seq;
  	int count;
cdfb6b341   Richard Guy Briggs   audit: use inline...
1711
  	context = audit_context();
74c3cbe33   Al Viro   [PATCH] audit: wa...
1712
1713
1714
1715
1716
1717
1718
1719
  	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...
1720
  		struct inode *inode = d_backing_inode(d);
08991e83b   Jan Kara   fsnotify: Free fs...
1721
  		if (inode && unlikely(inode->i_fsnotify_marks)) {
74c3cbe33   Al Viro   [PATCH] audit: wa...
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
  			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...
1750
1751
  		pr_warn("out of memory, audit has lost a tree reference
  ");
74c3cbe33   Al Viro   [PATCH] audit: wa...
1752
1753
1754
1755
1756
  		unroll_tree_refs(context, p, count);
  		audit_set_auditable(context);
  		return;
  	}
  	rcu_read_unlock();
74c3cbe33   Al Viro   [PATCH] audit: wa...
1757
  }
78e2e802a   Jeff Layton   audit: add a new ...
1758
1759
  static struct audit_names *audit_alloc_name(struct audit_context *context,
  						unsigned char type)
5195d8e21   Eric Paris   audit: dynamicall...
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
  {
  	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...
1772
  	aname->ino = AUDIT_INO_UNSET;
78e2e802a   Jeff Layton   audit: add a new ...
1773
  	aname->type = type;
5195d8e21   Eric Paris   audit: dynamicall...
1774
1775
1776
  	list_add_tail(&aname->list, &context->names_list);
  
  	context->name_count++;
5195d8e21   Eric Paris   audit: dynamicall...
1777
1778
  	return aname;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1779
  /**
196a50855   Geliang Tang   audit: update the...
1780
   * __audit_reusename - fill out filename with info from existing entry
7ac86265d   Jeff Layton   audit: allow audi...
1781
1782
1783
1784
1785
1786
1787
1788
1789
   * @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)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
1790
  	struct audit_context *context = audit_context();
7ac86265d   Jeff Layton   audit: allow audi...
1791
1792
1793
1794
1795
  	struct audit_names *n;
  
  	list_for_each_entry(n, &context->names_list, list) {
  		if (!n->name)
  			continue;
55422d0bd   Paul Moore   audit: replace ge...
1796
1797
  		if (n->name->uptr == uptr) {
  			n->name->refcnt++;
7ac86265d   Jeff Layton   audit: allow audi...
1798
  			return n->name;
55422d0bd   Paul Moore   audit: replace ge...
1799
  		}
7ac86265d   Jeff Layton   audit: allow audi...
1800
1801
1802
1803
1804
  	}
  	return NULL;
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
1805
   * __audit_getname - add a name to the list
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1806
1807
1808
1809
1810
   * @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...
1811
  void __audit_getname(struct filename *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1812
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
1813
  	struct audit_context *context = audit_context();
5195d8e21   Eric Paris   audit: dynamicall...
1814
  	struct audit_names *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1815

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

78e2e802a   Jeff Layton   audit: add a new ...
1819
  	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
5195d8e21   Eric Paris   audit: dynamicall...
1820
1821
1822
1823
1824
  	if (!n)
  		return;
  
  	n->name = name;
  	n->name_len = AUDIT_NAME_FULL;
adb5c2473   Jeff Layton   audit: make audit...
1825
  	name->aname = n;
55422d0bd   Paul Moore   audit: replace ge...
1826
  	name->refcnt++;
5195d8e21   Eric Paris   audit: dynamicall...
1827

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
1828
1829
  	if (!context->pwd.dentry)
  		get_fs_pwd(current->fs, &context->pwd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1830
  }
5f3d544f1   Richard Guy Briggs   audit: remove aud...
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
  static inline int audit_copy_fcaps(struct audit_names *name,
  				   const struct dentry *dentry)
  {
  	struct cpu_vfs_cap_data caps;
  	int rc;
  
  	if (!dentry)
  		return 0;
  
  	rc = get_vfs_caps_from_disk(dentry, &caps);
  	if (rc)
  		return rc;
  
  	name->fcap.permitted = caps.permitted;
  	name->fcap.inheritable = caps.inheritable;
  	name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
  	name->fcap.rootid = caps.rootid;
  	name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >>
  				VFS_CAP_REVISION_SHIFT;
  
  	return 0;
  }
  
  /* Copy inode data into an audit_names. */
2efa48fec   YueHaibing   audit: Make audit...
1855
1856
1857
  static void audit_copy_inode(struct audit_names *name,
  			     const struct dentry *dentry,
  			     struct inode *inode, unsigned int flags)
5f3d544f1   Richard Guy Briggs   audit: remove aud...
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
  {
  	name->ino   = inode->i_ino;
  	name->dev   = inode->i_sb->s_dev;
  	name->mode  = inode->i_mode;
  	name->uid   = inode->i_uid;
  	name->gid   = inode->i_gid;
  	name->rdev  = inode->i_rdev;
  	security_inode_getsecid(inode, &name->osid);
  	if (flags & AUDIT_INODE_NOEVAL) {
  		name->fcap_ver = -1;
  		return;
  	}
  	audit_copy_fcaps(name, dentry);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1872
  /**
bfcec7087   Jeff Layton   audit: set the na...
1873
   * __audit_inode - store the inode and device from a lookup
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1874
   * @name: name being audited
481968f44   Randy Dunlap   auditsc: fix kern...
1875
   * @dentry: dentry being audited
79f6530cb   Jeff Layton   audit: fix mq_ope...
1876
   * @flags: attributes for this particular entry
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1877
   */
adb5c2473   Jeff Layton   audit: make audit...
1878
  void __audit_inode(struct filename *name, const struct dentry *dentry,
79f6530cb   Jeff Layton   audit: fix mq_ope...
1879
  		   unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
1881
  	struct audit_context *context = audit_context();
d6335d77a   Andreas Gruenbacher   security: Make in...
1882
  	struct inode *inode = d_backing_inode(dentry);
5195d8e21   Eric Paris   audit: dynamicall...
1883
  	struct audit_names *n;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1884
  	bool parent = flags & AUDIT_INODE_PARENT;
a252f56a3   Richard Guy Briggs   audit: more filte...
1885
1886
1887
  	struct audit_entry *e;
  	struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1888
1889
1890
  
  	if (!context->in_syscall)
  		return;
5195d8e21   Eric Paris   audit: dynamicall...
1891

a252f56a3   Richard Guy Briggs   audit: more filte...
1892
  	rcu_read_lock();
699c1868a   Richard Guy Briggs   audit: purge unne...
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
  	list_for_each_entry_rcu(e, list, list) {
  		for (i = 0; i < e->rule.field_count; i++) {
  			struct audit_field *f = &e->rule.fields[i];
  
  			if (f->type == AUDIT_FSTYPE
  			    && audit_comparator(inode->i_sb->s_magic,
  						f->op, f->val)
  			    && e->rule.action == AUDIT_NEVER) {
  				rcu_read_unlock();
  				return;
a252f56a3   Richard Guy Briggs   audit: more filte...
1903
1904
1905
1906
  			}
  		}
  	}
  	rcu_read_unlock();
9cec9d68a   Jeff Layton   audit: no need to...
1907
1908
  	if (!name)
  		goto out_alloc;
adb5c2473   Jeff Layton   audit: make audit...
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
  	/*
  	 * 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...
1924
  	list_for_each_entry_reverse(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
  		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...
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
  			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
1947
  	}
5195d8e21   Eric Paris   audit: dynamicall...
1948

9cec9d68a   Jeff Layton   audit: no need to...
1949
  out_alloc:
4a9284360   Paul Moore   audit: correctly ...
1950
1951
  	/* 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...
1952
1953
  	if (!n)
  		return;
fcf22d826   Paul Moore   audit: create pri...
1954
  	if (name) {
fd3522fdc   Paul Moore   audit: enable fil...
1955
  		n->name = name;
55422d0bd   Paul Moore   audit: replace ge...
1956
  		name->refcnt++;
fcf22d826   Paul Moore   audit: create pri...
1957
  	}
4a9284360   Paul Moore   audit: correctly ...
1958

5195d8e21   Eric Paris   audit: dynamicall...
1959
  out:
bfcec7087   Jeff Layton   audit: set the na...
1960
  	if (parent) {
91a27b2a7   Jeff Layton   vfs: define struc...
1961
  		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
bfcec7087   Jeff Layton   audit: set the na...
1962
  		n->type = AUDIT_TYPE_PARENT;
79f6530cb   Jeff Layton   audit: fix mq_ope...
1963
1964
  		if (flags & AUDIT_INODE_HIDDEN)
  			n->hidden = true;
bfcec7087   Jeff Layton   audit: set the na...
1965
1966
1967
1968
  	} else {
  		n->name_len = AUDIT_NAME_FULL;
  		n->type = AUDIT_TYPE_NORMAL;
  	}
74c3cbe33   Al Viro   [PATCH] audit: wa...
1969
  	handle_path(dentry);
57d465771   Richard Guy Briggs   audit: ignore fca...
1970
  	audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL);
73241ccca   Amy Griffis   [PATCH] Collect m...
1971
  }
9f45f5bf3   Al Viro   new helper: audit...
1972
1973
1974
1975
  void __audit_file(const struct file *file)
  {
  	__audit_inode(NULL, file->f_path.dentry, 0);
  }
73241ccca   Amy Griffis   [PATCH] Collect m...
1976
  /**
c43a25abb   Jeff Layton   audit: reverse ar...
1977
   * __audit_inode_child - collect inode info for created/removed objects
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
1978
   * @parent: inode of dentry parent
c43a25abb   Jeff Layton   audit: reverse ar...
1979
   * @dentry: dentry being audited
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1980
   * @type:   AUDIT_TYPE_* value that we're looking for
73241ccca   Amy Griffis   [PATCH] Collect m...
1981
1982
1983
1984
1985
1986
1987
1988
1989
   *
   * 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...
1990
  void __audit_inode_child(struct inode *parent,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1991
1992
  			 const struct dentry *dentry,
  			 const unsigned char type)
73241ccca   Amy Griffis   [PATCH] Collect m...
1993
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
1994
  	struct audit_context *context = audit_context();
d6335d77a   Andreas Gruenbacher   security: Make in...
1995
  	struct inode *inode = d_backing_inode(dentry);
795d673af   Al Viro   audit_compare_dna...
1996
  	const struct qstr *dname = &dentry->d_name;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
1997
  	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
42d5e3765   Richard Guy Briggs   audit: filter PAT...
1998
1999
2000
  	struct audit_entry *e;
  	struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
  	int i;
73241ccca   Amy Griffis   [PATCH] Collect m...
2001
2002
2003
  
  	if (!context->in_syscall)
  		return;
42d5e3765   Richard Guy Briggs   audit: filter PAT...
2004
  	rcu_read_lock();
699c1868a   Richard Guy Briggs   audit: purge unne...
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
  	list_for_each_entry_rcu(e, list, list) {
  		for (i = 0; i < e->rule.field_count; i++) {
  			struct audit_field *f = &e->rule.fields[i];
  
  			if (f->type == AUDIT_FSTYPE
  			    && audit_comparator(parent->i_sb->s_magic,
  						f->op, f->val)
  			    && e->rule.action == AUDIT_NEVER) {
  				rcu_read_unlock();
  				return;
42d5e3765   Richard Guy Briggs   audit: filter PAT...
2015
2016
2017
2018
  			}
  		}
  	}
  	rcu_read_unlock();
74c3cbe33   Al Viro   [PATCH] audit: wa...
2019
2020
  	if (inode)
  		handle_one(inode);
73241ccca   Amy Griffis   [PATCH] Collect m...
2021

4fa6b5ecb   Jeff Layton   audit: overhaul _...
2022
  	/* look for a parent entry first */
5195d8e21   Eric Paris   audit: dynamicall...
2023
  	list_for_each_entry(n, &context->names_list, list) {
57c59f583   Paul Moore   audit: fix filena...
2024
2025
2026
  		if (!n->name ||
  		    (n->type != AUDIT_TYPE_PARENT &&
  		     n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
2027
  			continue;
57c59f583   Paul Moore   audit: fix filena...
2028
2029
2030
2031
2032
  		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 _...
2033
2034
  			found_parent = n;
  			break;
f368c07d7   Amy Griffis   [PATCH] audit: pa...
2035
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
2036
  	}
73241ccca   Amy Griffis   [PATCH] Collect m...
2037

4fa6b5ecb   Jeff Layton   audit: overhaul _...
2038
  	/* is there a matching child entry? */
5195d8e21   Eric Paris   audit: dynamicall...
2039
  	list_for_each_entry(n, &context->names_list, list) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2040
  		/* can only match entries that have a name */
57c59f583   Paul Moore   audit: fix filena...
2041
2042
  		if (!n->name ||
  		    (n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
5712e88f2   Amy Griffis   [PATCH] match aud...
2043
  			continue;
795d673af   Al Viro   audit_compare_dna...
2044
  		if (!strcmp(dname->name, n->name->name) ||
91a27b2a7   Jeff Layton   vfs: define struc...
2045
  		    !audit_compare_dname_path(dname, n->name->name,
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2046
2047
  						found_parent ?
  						found_parent->name_len :
e3d6b07b8   Jeff Layton   audit: optimize a...
2048
  						AUDIT_NAME_FULL)) {
57c59f583   Paul Moore   audit: fix filena...
2049
2050
  			if (n->type == AUDIT_TYPE_UNKNOWN)
  				n->type = type;
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2051
2052
  			found_child = n;
  			break;
5712e88f2   Amy Griffis   [PATCH] match aud...
2053
  		}
ac9910ce0   Steve Grubb   [PATCH] name_coun...
2054
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
2055

5712e88f2   Amy Griffis   [PATCH] match aud...
2056
  	if (!found_parent) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2057
2058
  		/* create a new, "anonymous" parent record */
  		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
5195d8e21   Eric Paris   audit: dynamicall...
2059
  		if (!n)
ac9910ce0   Steve Grubb   [PATCH] name_coun...
2060
  			return;
57d465771   Richard Guy Briggs   audit: ignore fca...
2061
  		audit_copy_inode(n, NULL, parent, 0);
73d3ec5ab   Amy Griffis   [PATCH] fix misse...
2062
  	}
5712e88f2   Amy Griffis   [PATCH] match aud...
2063
2064
  
  	if (!found_child) {
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2065
2066
  		found_child = audit_alloc_name(context, type);
  		if (!found_child)
5712e88f2   Amy Griffis   [PATCH] match aud...
2067
  			return;
5712e88f2   Amy Griffis   [PATCH] match aud...
2068
2069
2070
2071
2072
  
  		/* 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 _...
2073
2074
  			found_child->name = found_parent->name;
  			found_child->name_len = AUDIT_NAME_FULL;
55422d0bd   Paul Moore   audit: replace ge...
2075
  			found_child->name->refcnt++;
5712e88f2   Amy Griffis   [PATCH] match aud...
2076
  		}
5712e88f2   Amy Griffis   [PATCH] match aud...
2077
  	}
57c59f583   Paul Moore   audit: fix filena...
2078

4fa6b5ecb   Jeff Layton   audit: overhaul _...
2079
  	if (inode)
57d465771   Richard Guy Briggs   audit: ignore fca...
2080
  		audit_copy_inode(found_child, dentry, inode, 0);
4fa6b5ecb   Jeff Layton   audit: overhaul _...
2081
  	else
84cb777e6   Richard Guy Briggs   audit: use macros...
2082
  		found_child->ino = AUDIT_INO_UNSET;
3e2efce06   Amy Griffis   [PATCH] fix fault...
2083
  }
50e437d52   Trond Myklebust   SUNRPC: Convert r...
2084
  EXPORT_SYMBOL_GPL(__audit_inode_child);
3e2efce06   Amy Griffis   [PATCH] fix fault...
2085
2086
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2087
2088
   * auditsc_get_stamp - get local copies of audit_context values
   * @ctx: audit_context for the task
2115bb250   Deepa Dinamani   audit: Use timesp...
2089
   * @t: timespec64 to store time recorded in the audit_context
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2090
2091
2092
2093
   * @serial: serial value that is recorded in the audit_context
   *
   * Also sets the context as auditable.
   */
48887e63d   Al Viro   [PATCH] fix broke...
2094
  int auditsc_get_stamp(struct audit_context *ctx,
2115bb250   Deepa Dinamani   audit: Use timesp...
2095
  		       struct timespec64 *t, unsigned int *serial)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2096
  {
48887e63d   Al Viro   [PATCH] fix broke...
2097
2098
  	if (!ctx->in_syscall)
  		return 0;
ce625a801   David Woodhouse   AUDIT: Reduce con...
2099
2100
  	if (!ctx->serial)
  		ctx->serial = audit_serial();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
2101
2102
2103
  	t->tv_sec  = ctx->ctime.tv_sec;
  	t->tv_nsec = ctx->ctime.tv_nsec;
  	*serial    = ctx->serial;
0590b9335   Al Viro   fixing audit rule...
2104
2105
2106
2107
  	if (!ctx->prio) {
  		ctx->prio = 1;
  		ctx->current_state = AUDIT_RECORD_CONTEXT;
  	}
48887e63d   Al Viro   [PATCH] fix broke...
2108
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2109
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2110
  /**
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2111
2112
2113
   * __audit_mq_open - record audit data for a POSIX MQ open
   * @oflag: open flag
   * @mode: mode bits
6b9625599   Randy Dunlap   auditsc: fix kern...
2114
   * @attr: queue attributes
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2115
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2116
   */
df0a42837   Al Viro   switch mq_open() ...
2117
  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2118
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2119
  	struct audit_context *context = audit_context();
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2120

564f6993f   Al Viro   sanitize audit_mq...
2121
2122
2123
2124
  	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 ...
2125

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

564f6993f   Al Viro   sanitize audit_mq...
2129
  	context->type = AUDIT_MQ_OPEN;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2130
2131
2132
  }
  
  /**
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2133
   * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2134
2135
2136
   * @mqdes: MQ descriptor
   * @msg_len: Message length
   * @msg_prio: Message priority
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2137
   * @abs_timeout: Message timeout in absolute time
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2138
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2139
   */
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2140
  void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2141
  			const struct timespec64 *abs_timeout)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2142
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2143
  	struct audit_context *context = audit_context();
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2144
  	struct timespec64 *p = &context->mq_sendrecv.abs_timeout;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2145

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2146
  	if (abs_timeout)
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2147
  		memcpy(p, abs_timeout, sizeof(*p));
c32c8af43   Al Viro   sanitize AUDIT_MQ...
2148
  	else
b90477263   Deepa Dinamani   ipc: mqueue: Repl...
2149
  		memset(p, 0, sizeof(*p));
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2150

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2151
2152
2153
  	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 ...
2154

c32c8af43   Al Viro   sanitize AUDIT_MQ...
2155
  	context->type = AUDIT_MQ_SENDRECV;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2156
2157
2158
2159
2160
  }
  
  /**
   * __audit_mq_notify - record audit data for a POSIX MQ notify
   * @mqdes: MQ descriptor
6b9625599   Randy Dunlap   auditsc: fix kern...
2161
   * @notification: Notification event
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2162
   *
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2163
   */
20114f71b   Al Viro   sanitize audit_mq...
2164
  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2165
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2166
  	struct audit_context *context = audit_context();
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2167

20114f71b   Al Viro   sanitize audit_mq...
2168
2169
2170
2171
  	if (notification)
  		context->mq_notify.sigev_signo = notification->sigev_signo;
  	else
  		context->mq_notify.sigev_signo = 0;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2172

20114f71b   Al Viro   sanitize audit_mq...
2173
2174
  	context->mq_notify.mqdes = mqdes;
  	context->type = AUDIT_MQ_NOTIFY;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2175
2176
2177
2178
2179
2180
2181
  }
  
  /**
   * __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 ...
2182
   */
7392906ea   Al Viro   sanitize audit_mq...
2183
  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2184
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2185
  	struct audit_context *context = audit_context();
7392906ea   Al Viro   sanitize audit_mq...
2186
2187
2188
  	context->mq_getsetattr.mqdes = mqdes;
  	context->mq_getsetattr.mqstat = *mqstat;
  	context->type = AUDIT_MQ_GETSETATTR;
20ca73bc7   George C. Wilson   [PATCH] Audit of ...
2189
2190
2191
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
2192
   * __audit_ipc_obj - record audit data for ipc object
073115d6b   Steve Grubb   [PATCH] Rework of...
2193
2194
   * @ipcp: ipc permissions
   *
073115d6b   Steve Grubb   [PATCH] Rework of...
2195
   */
a33e67510   Al Viro   sanitize audit_ip...
2196
  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
073115d6b   Steve Grubb   [PATCH] Rework of...
2197
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2198
  	struct audit_context *context = audit_context();
a33e67510   Al Viro   sanitize audit_ip...
2199
2200
2201
  	context->ipc.uid = ipcp->uid;
  	context->ipc.gid = ipcp->gid;
  	context->ipc.mode = ipcp->mode;
e816f370c   Al Viro   sanitize audit_ip...
2202
  	context->ipc.has_perm = 0;
a33e67510   Al Viro   sanitize audit_ip...
2203
2204
  	security_ipc_getsecid(ipcp, &context->ipc.osid);
  	context->type = AUDIT_IPC;
073115d6b   Steve Grubb   [PATCH] Rework of...
2205
2206
2207
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
2208
   * __audit_ipc_set_perm - record audit data for new ipc permissions
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2209
2210
2211
2212
2213
   * @qbytes: msgq bytes
   * @uid: msgq user id
   * @gid: msgq group id
   * @mode: msgq mode (permissions)
   *
e816f370c   Al Viro   sanitize audit_ip...
2214
   * Called only after audit_ipc_obj().
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2215
   */
2570ebbd1   Al Viro   switch kern_ipc_p...
2216
  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
2217
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2218
  	struct audit_context *context = audit_context();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2219

e816f370c   Al Viro   sanitize audit_ip...
2220
2221
2222
2223
2224
  	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
2225
  }
c2f0c7c35   Steve Grubb   The attached patc...
2226

d9cfea91e   Richard Guy Briggs   audit: move audit...
2227
  void __audit_bprm(struct linux_binprm *bprm)
473ae30bc   Al Viro   [PATCH] execve ar...
2228
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2229
  	struct audit_context *context = audit_context();
473ae30bc   Al Viro   [PATCH] execve ar...
2230

d9cfea91e   Richard Guy Briggs   audit: move audit...
2231
2232
  	context->type = AUDIT_EXECVE;
  	context->execve.argc = bprm->argc;
473ae30bc   Al Viro   [PATCH] execve ar...
2233
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2234
  /**
196a50855   Geliang Tang   audit: update the...
2235
   * __audit_socketcall - record audit data for sys_socketcall
2950fa9d3   Chen Gang   kernel: audit: be...
2236
   * @nargs: number of args, which should not be more than AUDITSC_ARGS.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2237
2238
   * @args: args array
   *
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2239
   */
2950fa9d3   Chen Gang   kernel: audit: be...
2240
  int __audit_socketcall(int nargs, unsigned long *args)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2241
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2242
  	struct audit_context *context = audit_context();
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2243

2950fa9d3   Chen Gang   kernel: audit: be...
2244
2245
  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
  		return -EINVAL;
f3298dc4f   Al Viro   sanitize audit_so...
2246
2247
2248
  	context->type = AUDIT_SOCKETCALL;
  	context->socketcall.nargs = nargs;
  	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
2950fa9d3   Chen Gang   kernel: audit: be...
2249
  	return 0;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2250
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2251
  /**
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2252
2253
2254
2255
   * __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_...
2256
   */
157cf649a   Al Viro   sanitize audit_fd...
2257
  void __audit_fd_pair(int fd1, int fd2)
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2258
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2259
  	struct audit_context *context = audit_context();
157cf649a   Al Viro   sanitize audit_fd...
2260
2261
  	context->fds[0] = fd1;
  	context->fds[1] = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
2262
2263
2264
  }
  
  /**
196a50855   Geliang Tang   audit: update the...
2265
   * __audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2266
2267
2268
2269
2270
   * @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...
2271
  int __audit_sockaddr(int len, void *a)
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2272
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2273
  	struct audit_context *context = audit_context();
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2274

4f6b434fe   Al Viro   don't reallocate ...
2275
2276
2277
2278
2279
2280
  	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...
2281

4f6b434fe   Al Viro   don't reallocate ...
2282
2283
  	context->sockaddr_len = len;
  	memcpy(context->sockaddr, a, len);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2284
2285
  	return 0;
  }
a5cb013da   Al Viro   [PATCH] auditing ...
2286
2287
  void __audit_ptrace(struct task_struct *t)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2288
  	struct audit_context *context = audit_context();
a5cb013da   Al Viro   [PATCH] auditing ...
2289

fa2bea2f5   Paul Moore   audit: consistent...
2290
  	context->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2291
  	context->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2292
  	context->target_uid = task_uid(t);
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2293
  	context->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2294
  	security_task_getsecid(t, &context->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2295
  	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
a5cb013da   Al Viro   [PATCH] auditing ...
2296
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2297
  /**
b48345aaf   Richard Guy Briggs   audit: deliver si...
2298
   * audit_signal_info_syscall - record signal info for syscalls
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2299
2300
2301
2302
2303
   * @t: task being signaled
   *
   * If the audit subsystem is being terminated, record the task (pid)
   * and uid that is doing that.
   */
b48345aaf   Richard Guy Briggs   audit: deliver si...
2304
  int audit_signal_info_syscall(struct task_struct *t)
c2f0c7c35   Steve Grubb   The attached patc...
2305
  {
e54dc2431   Amy Griffis   [PATCH] audit sig...
2306
  	struct audit_aux_data_pids *axp;
cdfb6b341   Richard Guy Briggs   audit: use inline...
2307
  	struct audit_context *ctx = audit_context();
b48345aaf   Richard Guy Briggs   audit: deliver si...
2308
  	kuid_t t_uid = task_uid(t);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2309

ab6434a13   Paul Moore   audit: move audit...
2310
2311
  	if (!audit_signals || audit_dummy_context())
  		return 0;
e54dc2431   Amy Griffis   [PATCH] audit sig...
2312
2313
2314
  	/* optimize the common case by putting first signal recipient directly
  	 * in audit_context */
  	if (!ctx->target_pid) {
f1dc4867f   Richard Guy Briggs   audit: anchor all...
2315
  		ctx->target_pid = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2316
  		ctx->target_auid = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2317
  		ctx->target_uid = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2318
  		ctx->target_sessionid = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2319
  		security_task_getsecid(t, &ctx->target_sid);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2320
  		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
  		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:...
2334
  	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2335

f1dc4867f   Richard Guy Briggs   audit: anchor all...
2336
  	axp->target_pid[axp->pid_count] = task_tgid_nr(t);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2337
  	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
c69e8d9c0   David Howells   CRED: Use RCU to ...
2338
  	axp->target_uid[axp->pid_count] = t_uid;
4746ec5b0   Eric Paris   [AUDIT] add sessi...
2339
  	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2a862b32f   Ahmed S. Darwish   Audit: use new LS...
2340
  	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
c2a7780ef   Eric Paris   [AUDIT] collect u...
2341
  	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
e54dc2431   Amy Griffis   [PATCH] audit sig...
2342
2343
2344
  	axp->pid_count++;
  
  	return 0;
c2f0c7c35   Steve Grubb   The attached patc...
2345
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2346
2347
  
  /**
3fc689e96   Eric Paris   Any time fcaps or...
2348
   * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
d84f4f992   David Howells   CRED: Inaugurate ...
2349
2350
2351
   * @bprm: pointer to the bprm being processed
   * @new: the proposed new credentials
   * @old: the old credentials
3fc689e96   Eric Paris   Any time fcaps or...
2352
2353
2354
2355
   *
   * 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...
2356
2357
   * -Eric
   */
d84f4f992   David Howells   CRED: Inaugurate ...
2358
2359
  int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  			   const struct cred *new, const struct cred *old)
3fc689e96   Eric Paris   Any time fcaps or...
2360
2361
  {
  	struct audit_aux_data_bprm_fcaps *ax;
cdfb6b341   Richard Guy Briggs   audit: use inline...
2362
  	struct audit_context *context = audit_context();
3fc689e96   Eric Paris   Any time fcaps or...
2363
  	struct cpu_vfs_cap_data vcaps;
3fc689e96   Eric Paris   Any time fcaps or...
2364
2365
2366
  
  	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
  	if (!ax)
d84f4f992   David Howells   CRED: Inaugurate ...
2367
  		return -ENOMEM;
3fc689e96   Eric Paris   Any time fcaps or...
2368
2369
2370
2371
  
  	ax->d.type = AUDIT_BPRM_FCAPS;
  	ax->d.next = context->aux;
  	context->aux = (void *)ax;
f4a4a8b12   Al Viro   file->f_path.dent...
2372
  	get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
3fc689e96   Eric Paris   Any time fcaps or...
2373
2374
2375
2376
  
  	ax->fcap.permitted = vcaps.permitted;
  	ax->fcap.inheritable = vcaps.inheritable;
  	ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
2fec30e24   Richard Guy Briggs   audit: add suppor...
2377
  	ax->fcap.rootid = vcaps.rootid;
3fc689e96   Eric Paris   Any time fcaps or...
2378
  	ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
d84f4f992   David Howells   CRED: Inaugurate ...
2379
2380
2381
  	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...
2382
  	ax->old_pcap.ambient     = old->cap_ambient;
3fc689e96   Eric Paris   Any time fcaps or...
2383

d84f4f992   David Howells   CRED: Inaugurate ...
2384
2385
2386
  	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...
2387
  	ax->new_pcap.ambient     = new->cap_ambient;
d84f4f992   David Howells   CRED: Inaugurate ...
2388
  	return 0;
3fc689e96   Eric Paris   Any time fcaps or...
2389
2390
2391
  }
  
  /**
e68b75a02   Eric Paris   When the capset s...
2392
   * __audit_log_capset - store information about the arguments to the capset syscall
d84f4f992   David Howells   CRED: Inaugurate ...
2393
2394
   * @new: the new credentials
   * @old: the old (current) credentials
e68b75a02   Eric Paris   When the capset s...
2395
   *
da3dae54e   Masanari Iida   Documentation: Do...
2396
   * Record the arguments userspace sent to sys_capset for later printing by the
e68b75a02   Eric Paris   When the capset s...
2397
2398
   * audit system if applicable
   */
ca24a23eb   Eric W. Biederman   audit: Simplify a...
2399
  void __audit_log_capset(const struct cred *new, const struct cred *old)
e68b75a02   Eric Paris   When the capset s...
2400
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2401
  	struct audit_context *context = audit_context();
fa2bea2f5   Paul Moore   audit: consistent...
2402
  	context->capset.pid = task_tgid_nr(current);
57f71a0af   Al Viro   sanitize audit_lo...
2403
2404
2405
  	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...
2406
  	context->capset.cap.ambient     = new->cap_ambient;
57f71a0af   Al Viro   sanitize audit_lo...
2407
  	context->type = AUDIT_CAPSET;
e68b75a02   Eric Paris   When the capset s...
2408
  }
120a795da   Al Viro   audit mmap
2409
2410
  void __audit_mmap_fd(int fd, int flags)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2411
  	struct audit_context *context = audit_context();
120a795da   Al Viro   audit mmap
2412
2413
2414
2415
  	context->mmap.fd = fd;
  	context->mmap.flags = flags;
  	context->type = AUDIT_MMAP;
  }
ca86cad73   Richard Guy Briggs   audit: log module...
2416
2417
  void __audit_log_kern_module(char *name)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2418
  	struct audit_context *context = audit_context();
ca86cad73   Richard Guy Briggs   audit: log module...
2419

b305f7ed0   Yi Wang   audit: fix potent...
2420
2421
2422
  	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...
2423
2424
  	context->type = AUDIT_KERN_MODULE;
  }
de8cd83e9   Steve Grubb   audit: Record fan...
2425
2426
  void __audit_fanotify(unsigned int response)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2427
  	audit_log(audit_context(), GFP_KERNEL,
de8cd83e9   Steve Grubb   audit: Record fan...
2428
2429
  		AUDIT_FANOTIFY,	"resp=%u", response);
  }
2d87a0674   Ondrej Mosnacek   timekeeping: Audi...
2430
2431
2432
2433
2434
2435
  void __audit_tk_injoffset(struct timespec64 offset)
  {
  	audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_INJOFFSET,
  		  "sec=%lli nsec=%li",
  		  (long long)offset.tv_sec, offset.tv_nsec);
  }
7e8eda734   Ondrej Mosnacek   ntp: Audit NTP pa...
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
  static void audit_log_ntp_val(const struct audit_ntp_data *ad,
  			      const char *op, enum audit_ntp_type type)
  {
  	const struct audit_ntp_val *val = &ad->vals[type];
  
  	if (val->newval == val->oldval)
  		return;
  
  	audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_ADJNTPVAL,
  		  "op=%s old=%lli new=%lli", op, val->oldval, val->newval);
  }
  
  void __audit_ntp_log(const struct audit_ntp_data *ad)
  {
  	audit_log_ntp_val(ad, "offset",	AUDIT_NTP_OFFSET);
  	audit_log_ntp_val(ad, "freq",	AUDIT_NTP_FREQ);
  	audit_log_ntp_val(ad, "status",	AUDIT_NTP_STATUS);
  	audit_log_ntp_val(ad, "tai",	AUDIT_NTP_TAI);
  	audit_log_ntp_val(ad, "tick",	AUDIT_NTP_TICK);
  	audit_log_ntp_val(ad, "adjust",	AUDIT_NTP_ADJUST);
  }
7b9205bd7   Kees Cook   audit: create exp...
2457
  static void audit_log_task(struct audit_buffer *ab)
85e7bac33   Eric Paris   seccomp: audit ab...
2458
  {
cca080d9b   Eric W. Biederman   userns: Convert a...
2459
2460
  	kuid_t auid, uid;
  	kgid_t gid;
85e7bac33   Eric Paris   seccomp: audit ab...
2461
  	unsigned int sessionid;
9eab339b1   Richard Guy Briggs   audit: get comm u...
2462
  	char comm[sizeof(current->comm)];
85e7bac33   Eric Paris   seccomp: audit ab...
2463
2464
2465
2466
2467
2468
  
  	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...
2469
2470
2471
2472
  			 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...
2473
  	audit_log_task_context(ab);
fa2bea2f5   Paul Moore   audit: consistent...
2474
  	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
9eab339b1   Richard Guy Briggs   audit: get comm u...
2475
  	audit_log_untrustedstring(ab, get_task_comm(comm, current));
4766b199e   Davidlohr Bueso   audit: consolidat...
2476
  	audit_log_d_path_exe(ab, current->mm);
7b9205bd7   Kees Cook   audit: create exp...
2477
  }
e68b75a02   Eric Paris   When the capset s...
2478
  /**
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2479
   * audit_core_dumps - record information about processes that end abnormally
6d9525b52   Henrik Kretzschmar   kerneldoc fix in ...
2480
   * @signr: signal value
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2481
2482
2483
2484
2485
2486
2487
   *
   * 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 ...
2488
2489
2490
2491
2492
2493
  
  	if (!audit_enabled)
  		return;
  
  	if (signr == SIGQUIT)	/* don't care for those */
  		return;
d87de4a87   Richard Guy Briggs   audit: tie ANOM_A...
2494
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND);
0644ec0cc   Kees Cook   audit: catch poss...
2495
2496
  	if (unlikely(!ab))
  		return;
61c0ee879   Paul Davies C   audit: drop audit...
2497
  	audit_log_task(ab);
89670affa   Steve Grubb   audit: Make AUDIT...
2498
  	audit_log_format(ab, " sig=%ld res=1", signr);
85e7bac33   Eric Paris   seccomp: audit ab...
2499
2500
  	audit_log_end(ab);
  }
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2501

326bee028   Tyler Hicks   seccomp: Don't sp...
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
  /**
   * audit_seccomp - record information about a seccomp action
   * @syscall: syscall number
   * @signr: signal value
   * @code: the seccomp action
   *
   * Record the information associated with a seccomp action. Event filtering for
   * seccomp actions that are not to be logged is done in seccomp_log().
   * Therefore, this function forces auditing independent of the audit_enabled
   * and dummy context state because seccomp actions should be logged even when
   * audit is not in use.
   */
  void audit_seccomp(unsigned long syscall, long signr, int code)
85e7bac33   Eric Paris   seccomp: audit ab...
2515
2516
  {
  	struct audit_buffer *ab;
9b8753fff   Richard Guy Briggs   audit: tie SECCOM...
2517
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_SECCOMP);
7b9205bd7   Kees Cook   audit: create exp...
2518
2519
2520
  	if (unlikely(!ab))
  		return;
  	audit_log_task(ab);
84db564aa   Richard Guy Briggs   audit: add arch f...
2521
  	audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
16add4116   Dmitry V. Levin   syscall_get_arch:...
2522
  			 signr, syscall_get_arch(current), syscall,
efbc0fbf3   Andy Lutomirski   auditsc: for secc...
2523
  			 in_compat_syscall(), KSTK_EIP(current), code);
0a4ff8c25   Steve Grubb   [PATCH] Abnormal ...
2524
2525
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2526

ea6eca778   Tyler Hicks   seccomp: Audit at...
2527
2528
2529
2530
2531
2532
2533
  void audit_seccomp_actions_logged(const char *names, const char *old_names,
  				  int res)
  {
  	struct audit_buffer *ab;
  
  	if (!audit_enabled)
  		return;
8982a1fbe   Richard Guy Briggs   audit: use new au...
2534
  	ab = audit_log_start(audit_context(), GFP_KERNEL,
ea6eca778   Tyler Hicks   seccomp: Audit at...
2535
2536
2537
  			     AUDIT_CONFIG_CHANGE);
  	if (unlikely(!ab))
  		return;
d0a3f18a7   Paul Moore   audit: minimize o...
2538
2539
2540
  	audit_log_format(ab,
  			 "op=seccomp-logging actions=%s old-actions=%s res=%d",
  			 names, old_names, res);
ea6eca778   Tyler Hicks   seccomp: Audit at...
2541
2542
  	audit_log_end(ab);
  }
916d75761   Al Viro   Fix rule eviction...
2543
2544
  struct list_head *audit_killed_trees(void)
  {
cdfb6b341   Richard Guy Briggs   audit: use inline...
2545
  	struct audit_context *ctx = audit_context();
916d75761   Al Viro   Fix rule eviction...
2546
2547
2548
2549
  	if (likely(!ctx || !ctx->in_syscall))
  		return NULL;
  	return &ctx->killed_trees;
  }