Blame view

kernel/audit.c 64.8 KB
1a59d1b8e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
85c8721ff   David Woodhouse   audit: update poi...
2
  /* audit.c -- Auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
   * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
   * System-call specific features have moved to auditsc.c
   *
6a01b07fa   Steve Grubb   [PATCH] audit con...
6
   * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * All Rights Reserved.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
11
   * Goals: 1) Integrate fully with Security Modules.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   *	  2) Minimal run-time overhead:
   *	     a) Minimal when syscall auditing is disabled (audit_enable=0).
   *	     b) Small when syscall auditing is enabled and no audit record
   *		is generated (defer as much work as possible to record
   *		generation time):
   *		i) context is allocated,
   *		ii) names from getname are stored without a copy, and
   *		iii) inode information stored from path_lookup.
   *	  3) Ability to disable syscall auditing at boot time (audit=0).
   *	  4) Usable by other parts of the kernel (if audit_log* is called,
   *	     then a syscall record will be generated automatically for the
   *	     current syscall).
   *	  5) Netlink interface to user-space.
   *	  6) Support low-overhead kernel-based filtering to minimize the
   *	     information that must be passed to user-space.
   *
d590dca62   Richard Guy Briggs   audit: update bug...
28
29
   * Audit userspace, documentation, tests, and bug/issue trackers:
   * 	https://github.com/linux-audit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
   */
d957f7b72   Joe Perches   audit: Use more c...
31
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5b2825527   Davidlohr Bueso   audit: reduce mma...
32
  #include <linux/file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  #include <linux/init.h>
7153e4027   Paul McQuade   ipc, kernel: use ...
34
  #include <linux/types.h>
60063497a   Arun Sharma   atomic: use <linu...
35
  #include <linux/atomic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
37
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
38
  #include <linux/slab.h>
b7d112581   David Woodhouse   AUDIT: Send netli...
39
40
  #include <linux/err.h>
  #include <linux/kthread.h>
46e959ea2   Richard Guy Briggs   audit: add an opt...
41
  #include <linux/kernel.h>
b24a30a73   Eric Paris   audit: fix event ...
42
  #include <linux/syscalls.h>
5b52330bb   Paul Moore   audit: fix auditd...
43
44
45
46
  #include <linux/spinlock.h>
  #include <linux/rcupdate.h>
  #include <linux/mutex.h>
  #include <linux/gfp.h>
b6c7c115c   Paul Moore   audit: store the ...
47
  #include <linux/pid.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
51
  
  #include <linux/audit.h>
  
  #include <net/sock.h>
93315ed6d   Amy Griffis   [PATCH] audit str...
52
  #include <net/netlink.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  #include <linux/skbuff.h>
131ad62d8   Mr Dash Four   netfilter: add SE...
54
55
56
  #ifdef CONFIG_SECURITY
  #include <linux/security.h>
  #endif
7dfb71030   Nigel Cunningham   [PATCH] Add inclu...
57
  #include <linux/freezer.h>
34e36d8ec   Eric W. Biederman   audit: Limit audi...
58
  #include <linux/pid_namespace.h>
33faba7fa   Richard Guy Briggs   audit: listen in ...
59
  #include <net/netns/generic.h>
3dc7e3153   Darrel Goeddel   [PATCH] support f...
60
61
  
  #include "audit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62

a3f07114e   Eric Paris   [PATCH] Audit: ma...
63
  /* No auditing will take place until audit_initialized == AUDIT_INITIALIZED.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
   * (Initialization happens after skb_init is called.) */
a3f07114e   Eric Paris   [PATCH] Audit: ma...
65
66
67
  #define AUDIT_DISABLED		-1
  #define AUDIT_UNINITIALIZED	0
  #define AUDIT_INITIALIZED	1
ba59eae72   Alex Shi   audit: fix macros...
68
  static int	audit_initialized = AUDIT_UNINITIALIZED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

173743dd9   Paul Moore   audit: ensure tha...
70
  u32		audit_enabled = AUDIT_OFF;
b3b4fdf6a   Paul Moore   audit: convert au...
71
  bool		audit_ever_enabled = !!AUDIT_OFF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72

ae9d67aff   Jan Engelhardt   audit: export sym...
73
  EXPORT_SYMBOL_GPL(audit_enabled);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  /* Default state when kernel boots without any parameters. */
173743dd9   Paul Moore   audit: ensure tha...
75
  static u32	audit_default = AUDIT_OFF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
  
  /* If auditing cannot proceed, audit_failure selects what happens. */
3e1d0bb62   Joe Perches   audit: Convert in...
78
  static u32	audit_failure = AUDIT_FAIL_PRINTK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

5b52330bb   Paul Moore   audit: fix auditd...
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  /* private audit network namespace index */
  static unsigned int audit_net_id;
  
  /**
   * struct audit_net - audit private network namespace data
   * @sk: communication socket
   */
  struct audit_net {
  	struct sock *sk;
  };
  
  /**
   * struct auditd_connection - kernel/auditd connection state
   * @pid: auditd PID
   * @portid: netlink portid
   * @net: the associated network namespace
48d0e023a   Paul Moore   audit: fix the RC...
96
   * @rcu: RCU head
5b52330bb   Paul Moore   audit: fix auditd...
97
98
99
   *
   * Description:
   * This struct is RCU protected; you must either hold the RCU lock for reading
48d0e023a   Paul Moore   audit: fix the RC...
100
   * or the associated spinlock for writing.
75c0371a2   Pavel Emelyanov   audit: netlink so...
101
   */
cb5172d96   Amol Grover   audit: Add __rcu ...
102
  struct auditd_connection {
b6c7c115c   Paul Moore   audit: store the ...
103
  	struct pid *pid;
5b52330bb   Paul Moore   audit: fix auditd...
104
105
  	u32 portid;
  	struct net *net;
48d0e023a   Paul Moore   audit: fix the RC...
106
  	struct rcu_head rcu;
cb5172d96   Amol Grover   audit: Add __rcu ...
107
108
  };
  static struct auditd_connection __rcu *auditd_conn;
48d0e023a   Paul Moore   audit: fix the RC...
109
  static DEFINE_SPINLOCK(auditd_conn_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
111
  /* If audit_rate_limit is non-zero, limit the rate of sending audit records
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
   * to that number per second.  This prevents DoS attacks, but results in
   * audit records being dropped. */
3e1d0bb62   Joe Perches   audit: Convert in...
114
  static u32	audit_rate_limit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115

40c0775e5   Richard Guy Briggs   audit: allow unli...
116
117
  /* Number of outstanding audit_buffers allowed.
   * When set to zero, this means unlimited. */
3e1d0bb62   Joe Perches   audit: Convert in...
118
  static u32	audit_backlog_limit = 64;
e789e561a   Richard Guy Briggs   audit: reset audi...
119
  #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ)
3e1d0bb62   Joe Perches   audit: Convert in...
120
  static u32	audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121

c2f0c7c35   Steve Grubb   The attached patc...
122
  /* The identity of the user shutting down the audit system. */
6b87024f7   Jules Irenge   audit: change unn...
123
124
  static kuid_t		audit_sig_uid = INVALID_UID;
  static pid_t		audit_sig_pid = -1;
265c32072   Jules Irenge   audit: uninitiali...
125
  static u32		audit_sig_sid;
c2f0c7c35   Steve Grubb   The attached patc...
126

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
131
132
133
  /* Records can be lost in several ways:
     0) [suppressed in audit_alloc]
     1) out of memory in audit_log_start [kmalloc of struct audit_buffer]
     2) out of memory in audit_log_move [alloc_skb]
     3) suppressed due to audit_rate_limit
     4) suppressed due to audit_backlog_limit
  */
92c82e8a3   Richard Guy Briggs   audit: add featur...
134
  static atomic_t	audit_lost = ATOMIC_INIT(0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

b43870c74   Max Englander   audit: report aud...
136
137
138
139
  /* Monotonically increasing sum of time the kernel has spent
   * waiting while the backlog limit is exceeded.
   */
  static atomic_t audit_backlog_wait_time_actual = ATOMIC_INIT(0);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
140
141
  /* Hash for inode-based rules */
  struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
8cc96382d   Paul Moore   audit: use kmem_c...
142
  static struct kmem_cache *audit_buffer_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143

c6480207f   Paul Moore   audit: rework the...
144
  /* queue msgs to send via kauditd_task */
af8b824f2   Paul Moore   audit: rename the...
145
  static struct sk_buff_head audit_queue;
c6480207f   Paul Moore   audit: rework the...
146
147
148
  /* queue msgs due to temporary unicast send problems */
  static struct sk_buff_head audit_retry_queue;
  /* queue msgs waiting for new auditd connection */
af8b824f2   Paul Moore   audit: rename the...
149
  static struct sk_buff_head audit_hold_queue;
c6480207f   Paul Moore   audit: rework the...
150
151
  
  /* queue servicing thread */
b7d112581   David Woodhouse   AUDIT: Send netli...
152
153
  static struct task_struct *kauditd_task;
  static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
c6480207f   Paul Moore   audit: rework the...
154
155
  
  /* waitqueue for callers who are blocked on the audit backlog */
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
156
  static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

b0fed4021   Eric Paris   audit: implement ...
158
159
160
161
  static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
  				   .mask = -1,
  				   .features = 0,
  				   .lock = 0,};
21b85c31d   Eric Paris   audit: audit feat...
162
  static char *audit_feature_names[2] = {
d040e5af3   Eric Paris   audit: audit feat...
163
  	"only_unset_loginuid",
21b85c31d   Eric Paris   audit: audit feat...
164
  	"loginuid_immutable",
b0fed4021   Eric Paris   audit: implement ...
165
  };
ce423631c   Paul Moore   audit: track the ...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  /**
   * struct audit_ctl_mutex - serialize requests from userspace
   * @lock: the mutex used for locking
   * @owner: the task which owns the lock
   *
   * Description:
   * This is the lock struct used to ensure we only process userspace requests
   * in an orderly fashion.  We can't simply use a mutex/lock here because we
   * need to track lock ownership so we don't end up blocking the lock owner in
   * audit_log_start() or similar.
   */
  static struct audit_ctl_mutex {
  	struct mutex lock;
  	void *owner;
  } audit_cmd_mutex;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
185
  
  /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
   * audit records.  Since printk uses a 1024 byte buffer, this buffer
   * should be at least that large. */
  #define AUDIT_BUFSIZ 1024
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
190
191
  /* The audit_buffer is used when formatting an audit record.  The caller
   * locks briefly to get the record off the freelist or to allocate the
   * buffer, and locks briefly to send the buffer to the netlink layer or
   * to place it on a transmit queue.  Multiple audit_buffers can be in
   * use simultaneously. */
  struct audit_buffer {
8fc6115c2   Chris Wright   AUDIT: expand aud...
192
  	struct sk_buff       *skb;	/* formatted skb ready to send */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
  	struct audit_context *ctx;	/* NULL or associated context */
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
194
  	gfp_t		     gfp_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  };
f09ac9db2   Eric Paris   Audit: stop deadl...
196
  struct audit_reply {
f9441639e   Richard Guy Briggs   audit: fix netlin...
197
  	__u32 portid;
638a0fd2a   Eric W. Biederman   audit: Use struct...
198
  	struct net *net;
f09ac9db2   Eric Paris   Audit: stop deadl...
199
200
  	struct sk_buff *skb;
  };
5b52330bb   Paul Moore   audit: fix auditd...
201
202
203
204
205
206
207
  /**
   * auditd_test_task - Check to see if a given task is an audit daemon
   * @task: the task to check
   *
   * Description:
   * Return 1 if the task is a registered audit daemon, 0 otherwise.
   */
b6c7c115c   Paul Moore   audit: store the ...
208
  int auditd_test_task(struct task_struct *task)
5b52330bb   Paul Moore   audit: fix auditd...
209
210
  {
  	int rc;
48d0e023a   Paul Moore   audit: fix the RC...
211
  	struct auditd_connection *ac;
5b52330bb   Paul Moore   audit: fix auditd...
212
213
  
  	rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
214
215
  	ac = rcu_dereference(auditd_conn);
  	rc = (ac && ac->pid == task_tgid(task) ? 1 : 0);
5b52330bb   Paul Moore   audit: fix auditd...
216
217
218
219
220
221
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
ce423631c   Paul Moore   audit: track the ...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
   * audit_ctl_lock - Take the audit control lock
   */
  void audit_ctl_lock(void)
  {
  	mutex_lock(&audit_cmd_mutex.lock);
  	audit_cmd_mutex.owner = current;
  }
  
  /**
   * audit_ctl_unlock - Drop the audit control lock
   */
  void audit_ctl_unlock(void)
  {
  	audit_cmd_mutex.owner = NULL;
  	mutex_unlock(&audit_cmd_mutex.lock);
  }
  
  /**
   * audit_ctl_owner_current - Test to see if the current task owns the lock
   *
   * Description:
   * Return true if the current task owns the audit control lock, false if it
   * doesn't own the lock.
   */
  static bool audit_ctl_owner_current(void)
  {
  	return (current == audit_cmd_mutex.owner);
  }
  
  /**
b6c7c115c   Paul Moore   audit: store the ...
252
   * auditd_pid_vnr - Return the auditd PID relative to the namespace
b6c7c115c   Paul Moore   audit: store the ...
253
254
   *
   * Description:
48d0e023a   Paul Moore   audit: fix the RC...
255
   * Returns the PID in relation to the namespace, 0 on failure.
b6c7c115c   Paul Moore   audit: store the ...
256
   */
48d0e023a   Paul Moore   audit: fix the RC...
257
  static pid_t auditd_pid_vnr(void)
b6c7c115c   Paul Moore   audit: store the ...
258
259
  {
  	pid_t pid;
48d0e023a   Paul Moore   audit: fix the RC...
260
  	const struct auditd_connection *ac;
b6c7c115c   Paul Moore   audit: store the ...
261
262
  
  	rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
263
264
  	ac = rcu_dereference(auditd_conn);
  	if (!ac || !ac->pid)
b6c7c115c   Paul Moore   audit: store the ...
265
266
  		pid = 0;
  	else
48d0e023a   Paul Moore   audit: fix the RC...
267
  		pid = pid_vnr(ac->pid);
b6c7c115c   Paul Moore   audit: store the ...
268
269
270
271
272
273
  	rcu_read_unlock();
  
  	return pid;
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
   * audit_get_sk - Return the audit socket for the given network namespace
   * @net: the destination network namespace
   *
   * Description:
   * Returns the sock pointer if valid, NULL otherwise.  The caller must ensure
   * that a reference is held for the network namespace while the sock is in use.
   */
  static struct sock *audit_get_sk(const struct net *net)
  {
  	struct audit_net *aunet;
  
  	if (!net)
  		return NULL;
  
  	aunet = net_generic(net, audit_net_id);
  	return aunet->sk;
  }
8c8570fb8   Dustin Kirkland   [PATCH] Capture s...
291
  void audit_panic(const char *message)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  {
d957f7b72   Joe Perches   audit: Use more c...
293
  	switch (audit_failure) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
  	case AUDIT_FAIL_SILENT:
  		break;
  	case AUDIT_FAIL_PRINTK:
320f1b1ed   Eric Paris   [AUDIT] ratelimit...
297
  		if (printk_ratelimit())
d957f7b72   Joe Perches   audit: Use more c...
298
299
  			pr_err("%s
  ", message);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
  		break;
  	case AUDIT_FAIL_PANIC:
5b52330bb   Paul Moore   audit: fix auditd...
302
303
  		panic("audit: %s
  ", message);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  		break;
  	}
  }
  
  static inline int audit_rate_check(void)
  {
  	static unsigned long	last_check = 0;
  	static int		messages   = 0;
  	static DEFINE_SPINLOCK(lock);
  	unsigned long		flags;
  	unsigned long		now;
  	unsigned long		elapsed;
  	int			retval	   = 0;
  
  	if (!audit_rate_limit) return 1;
  
  	spin_lock_irqsave(&lock, flags);
  	if (++messages < audit_rate_limit) {
  		retval = 1;
  	} else {
  		now     = jiffies;
  		elapsed = now - last_check;
  		if (elapsed > HZ) {
  			last_check = now;
  			messages   = 0;
  			retval     = 1;
  		}
  	}
  	spin_unlock_irqrestore(&lock, flags);
  
  	return retval;
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
336
337
338
339
340
341
342
343
  /**
   * audit_log_lost - conditionally log lost audit message event
   * @message: the message stating reason for lost audit message
   *
   * Emit at least 1 message per second, even if audit_rate_check is
   * throttling.
   * Always increment the lost messages counter.
  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  void audit_log_lost(const char *message)
  {
  	static unsigned long	last_msg = 0;
  	static DEFINE_SPINLOCK(lock);
  	unsigned long		flags;
  	unsigned long		now;
  	int			print;
  
  	atomic_inc(&audit_lost);
  
  	print = (audit_failure == AUDIT_FAIL_PANIC || !audit_rate_limit);
  
  	if (!print) {
  		spin_lock_irqsave(&lock, flags);
  		now = jiffies;
  		if (now - last_msg > HZ) {
  			print = 1;
  			last_msg = now;
  		}
  		spin_unlock_irqrestore(&lock, flags);
  	}
  
  	if (print) {
320f1b1ed   Eric Paris   [AUDIT] ratelimit...
367
  		if (printk_ratelimit())
3e1d0bb62   Joe Perches   audit: Convert in...
368
369
  			pr_warn("audit_lost=%u audit_rate_limit=%u audit_backlog_limit=%u
  ",
320f1b1ed   Eric Paris   [AUDIT] ratelimit...
370
371
372
  				atomic_read(&audit_lost),
  				audit_rate_limit,
  				audit_backlog_limit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
  		audit_panic(message);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
  }
3e1d0bb62   Joe Perches   audit: Convert in...
376
  static int audit_log_config_change(char *function_name, u32 new, u32 old,
2532386f4   Eric Paris   Audit: collect se...
377
  				   int allow_changes)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  {
1a6b9f231   Eric Paris   [AUDIT] make audi...
379
380
  	struct audit_buffer *ab;
  	int rc = 0;
ce29b682e   Steve Grubb   [PATCH] More user...
381

626abcd13   Richard Guy Briggs   audit: add syscal...
382
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE);
0644ec0cc   Kees Cook   audit: catch poss...
383
384
  	if (unlikely(!ab))
  		return rc;
53fc7a01d   Richard Guy Briggs   audit: give a clu...
385
  	audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old);
4d3fb709b   Eric Paris   helper for some s...
386
  	audit_log_session_info(ab);
b122c3767   Eric Paris   audit: use a cons...
387
388
389
  	rc = audit_log_task_context(ab);
  	if (rc)
  		allow_changes = 0; /* Something weird, deny request */
1a6b9f231   Eric Paris   [AUDIT] make audi...
390
391
  	audit_log_format(ab, " res=%d", allow_changes);
  	audit_log_end(ab);
6a01b07fa   Steve Grubb   [PATCH] audit con...
392
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  }
3e1d0bb62   Joe Perches   audit: Convert in...
394
  static int audit_do_config_change(char *function_name, u32 *to_change, u32 new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  {
3e1d0bb62   Joe Perches   audit: Convert in...
396
397
  	int allow_changes, rc = 0;
  	u32 old = *to_change;
6a01b07fa   Steve Grubb   [PATCH] audit con...
398
399
  
  	/* check if we are locked */
1a6b9f231   Eric Paris   [AUDIT] make audi...
400
401
  	if (audit_enabled == AUDIT_LOCKED)
  		allow_changes = 0;
6a01b07fa   Steve Grubb   [PATCH] audit con...
402
  	else
1a6b9f231   Eric Paris   [AUDIT] make audi...
403
  		allow_changes = 1;
ce29b682e   Steve Grubb   [PATCH] More user...
404

1a6b9f231   Eric Paris   [AUDIT] make audi...
405
  	if (audit_enabled != AUDIT_OFF) {
dc9eb698f   Eric Paris   audit: stop pushi...
406
  		rc = audit_log_config_change(function_name, new, old, allow_changes);
1a6b9f231   Eric Paris   [AUDIT] make audi...
407
408
  		if (rc)
  			allow_changes = 0;
6a01b07fa   Steve Grubb   [PATCH] audit con...
409
  	}
6a01b07fa   Steve Grubb   [PATCH] audit con...
410
411
  
  	/* If we are allowed, make the change */
1a6b9f231   Eric Paris   [AUDIT] make audi...
412
413
  	if (allow_changes == 1)
  		*to_change = new;
6a01b07fa   Steve Grubb   [PATCH] audit con...
414
415
416
417
  	/* Not allowed, update reason */
  	else if (rc == 0)
  		rc = -EPERM;
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
  }
3e1d0bb62   Joe Perches   audit: Convert in...
419
  static int audit_set_rate_limit(u32 limit)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  {
dc9eb698f   Eric Paris   audit: stop pushi...
421
  	return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit);
1a6b9f231   Eric Paris   [AUDIT] make audi...
422
  }
ce29b682e   Steve Grubb   [PATCH] More user...
423

3e1d0bb62   Joe Perches   audit: Convert in...
424
  static int audit_set_backlog_limit(u32 limit)
1a6b9f231   Eric Paris   [AUDIT] make audi...
425
  {
dc9eb698f   Eric Paris   audit: stop pushi...
426
  	return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit);
1a6b9f231   Eric Paris   [AUDIT] make audi...
427
  }
6a01b07fa   Steve Grubb   [PATCH] audit con...
428

3e1d0bb62   Joe Perches   audit: Convert in...
429
  static int audit_set_backlog_wait_time(u32 timeout)
51cc83f02   Richard Guy Briggs   audit: add audit_...
430
431
  {
  	return audit_do_config_change("audit_backlog_wait_time",
319754248   Paul Moore   audit: rework aud...
432
  				      &audit_backlog_wait_time, timeout);
51cc83f02   Richard Guy Briggs   audit: add audit_...
433
  }
3e1d0bb62   Joe Perches   audit: Convert in...
434
  static int audit_set_enabled(u32 state)
1a6b9f231   Eric Paris   [AUDIT] make audi...
435
  {
b593d384e   Eric Paris   [AUDIT] create co...
436
  	int rc;
724e7bfcc   Pranith Kumar   audit: Remove con...
437
  	if (state > AUDIT_LOCKED)
1a6b9f231   Eric Paris   [AUDIT] make audi...
438
  		return -EINVAL;
6a01b07fa   Steve Grubb   [PATCH] audit con...
439

dc9eb698f   Eric Paris   audit: stop pushi...
440
  	rc =  audit_do_config_change("audit_enabled", &audit_enabled, state);
b593d384e   Eric Paris   [AUDIT] create co...
441
442
443
444
  	if (!rc)
  		audit_ever_enabled |= !!state;
  
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  }
3e1d0bb62   Joe Perches   audit: Convert in...
446
  static int audit_set_failure(u32 state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
451
  	if (state != AUDIT_FAIL_SILENT
  	    && state != AUDIT_FAIL_PRINTK
  	    && state != AUDIT_FAIL_PANIC)
  		return -EINVAL;
ce29b682e   Steve Grubb   [PATCH] More user...
452

dc9eb698f   Eric Paris   audit: stop pushi...
453
  	return audit_do_config_change("audit_failure", &audit_failure, state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  }
5b52330bb   Paul Moore   audit: fix auditd...
455
  /**
48d0e023a   Paul Moore   audit: fix the RC...
456
457
458
459
460
461
462
   * auditd_conn_free - RCU helper to release an auditd connection struct
   * @rcu: RCU head
   *
   * Description:
   * Drop any references inside the auditd connection tracking struct and free
   * the memory.
   */
447a5647c   Joe Perches   treewide: Align f...
463
464
  static void auditd_conn_free(struct rcu_head *rcu)
  {
48d0e023a   Paul Moore   audit: fix the RC...
465
466
467
468
469
470
  	struct auditd_connection *ac;
  
  	ac = container_of(rcu, struct auditd_connection, rcu);
  	put_pid(ac->pid);
  	put_net(ac->net);
  	kfree(ac);
447a5647c   Joe Perches   treewide: Align f...
471
  }
48d0e023a   Paul Moore   audit: fix the RC...
472
473
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
474
475
476
477
478
479
480
   * auditd_set - Set/Reset the auditd connection state
   * @pid: auditd PID
   * @portid: auditd netlink portid
   * @net: auditd network namespace pointer
   *
   * Description:
   * This function will obtain and drop network namespace references as
48d0e023a   Paul Moore   audit: fix the RC...
481
   * necessary.  Returns zero on success, negative values on failure.
5b52330bb   Paul Moore   audit: fix auditd...
482
   */
48d0e023a   Paul Moore   audit: fix the RC...
483
  static int auditd_set(struct pid *pid, u32 portid, struct net *net)
5b52330bb   Paul Moore   audit: fix auditd...
484
485
  {
  	unsigned long flags;
48d0e023a   Paul Moore   audit: fix the RC...
486
  	struct auditd_connection *ac_old, *ac_new;
5b52330bb   Paul Moore   audit: fix auditd...
487

48d0e023a   Paul Moore   audit: fix the RC...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
  	if (!pid || !net)
  		return -EINVAL;
  
  	ac_new = kzalloc(sizeof(*ac_new), GFP_KERNEL);
  	if (!ac_new)
  		return -ENOMEM;
  	ac_new->pid = get_pid(pid);
  	ac_new->portid = portid;
  	ac_new->net = get_net(net);
  
  	spin_lock_irqsave(&auditd_conn_lock, flags);
  	ac_old = rcu_dereference_protected(auditd_conn,
  					   lockdep_is_held(&auditd_conn_lock));
  	rcu_assign_pointer(auditd_conn, ac_new);
  	spin_unlock_irqrestore(&auditd_conn_lock, flags);
  
  	if (ac_old)
  		call_rcu(&ac_old->rcu, auditd_conn_free);
  
  	return 0;
5b52330bb   Paul Moore   audit: fix auditd...
508
509
510
  }
  
  /**
cbb526219   Mauro Carvalho Chehab   audit: fix a kern...
511
   * kauditd_printk_skb - Print the audit record to the ring buffer
5b52330bb   Paul Moore   audit: fix auditd...
512
513
514
515
   * @skb: audit record
   *
   * Whatever the reason, this packet may not make it to the auditd connection
   * so write it via printk so the information isn't completely lost.
038cbcf65   Eric Paris   Audit: unify the ...
516
   */
af8b824f2   Paul Moore   audit: rename the...
517
  static void kauditd_printk_skb(struct sk_buff *skb)
038cbcf65   Eric Paris   Audit: unify the ...
518
519
  {
  	struct nlmsghdr *nlh = nlmsg_hdr(skb);
c64e66c67   David S. Miller   audit: netlink: M...
520
  	char *data = nlmsg_data(nlh);
038cbcf65   Eric Paris   Audit: unify the ...
521

5b52330bb   Paul Moore   audit: fix auditd...
522
523
524
525
526
527
528
529
  	if (nlh->nlmsg_type != AUDIT_EOE && printk_ratelimit())
  		pr_notice("type=%d %s
  ", nlh->nlmsg_type, data);
  }
  
  /**
   * kauditd_rehold_skb - Handle a audit record send failure in the hold queue
   * @skb: audit record
b8d9e0aec   Paul Moore   audit: improve au...
530
   * @error: error code (unused)
5b52330bb   Paul Moore   audit: fix auditd...
531
532
533
534
535
   *
   * Description:
   * This should only be used by the kauditd_thread when it fails to flush the
   * hold queue.
   */
b8d9e0aec   Paul Moore   audit: improve au...
536
  static void kauditd_rehold_skb(struct sk_buff *skb, __always_unused int error)
5b52330bb   Paul Moore   audit: fix auditd...
537
  {
b8d9e0aec   Paul Moore   audit: improve au...
538
539
  	/* put the record back in the queue */
  	skb_queue_tail(&audit_hold_queue, skb);
c6480207f   Paul Moore   audit: rework the...
540
541
542
543
544
  }
  
  /**
   * kauditd_hold_skb - Queue an audit record, waiting for auditd
   * @skb: audit record
b8d9e0aec   Paul Moore   audit: improve au...
545
   * @error: error code
c6480207f   Paul Moore   audit: rework the...
546
547
548
549
550
551
552
553
554
   *
   * Description:
   * Queue the audit record, waiting for an instance of auditd.  When this
   * function is called we haven't given up yet on sending the record, but things
   * are not looking good.  The first thing we want to do is try to write the
   * record via printk and then see if we want to try and hold on to the record
   * and queue it, if we have room.  If we want to hold on to the record, but we
   * don't have room, record a record lost message.
   */
b8d9e0aec   Paul Moore   audit: improve au...
555
  static void kauditd_hold_skb(struct sk_buff *skb, int error)
c6480207f   Paul Moore   audit: rework the...
556
557
558
559
560
561
  {
  	/* at this point it is uncertain if we will ever send this to auditd so
  	 * try to send the message via printk before we go any further */
  	kauditd_printk_skb(skb);
  
  	/* can we just silently drop the message? */
b8d9e0aec   Paul Moore   audit: improve au...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  	if (!audit_default)
  		goto drop;
  
  	/* the hold queue is only for when the daemon goes away completely,
  	 * not -EAGAIN failures; if we are in a -EAGAIN state requeue the
  	 * record on the retry queue unless it's full, in which case drop it
  	 */
  	if (error == -EAGAIN) {
  		if (!audit_backlog_limit ||
  		    skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
  			skb_queue_tail(&audit_retry_queue, skb);
  			return;
  		}
  		audit_log_lost("kauditd retry queue overflow");
  		goto drop;
c6480207f   Paul Moore   audit: rework the...
577
  	}
b8d9e0aec   Paul Moore   audit: improve au...
578
  	/* if we have room in the hold queue, queue the message */
c6480207f   Paul Moore   audit: rework the...
579
580
581
582
583
  	if (!audit_backlog_limit ||
  	    skb_queue_len(&audit_hold_queue) < audit_backlog_limit) {
  		skb_queue_tail(&audit_hold_queue, skb);
  		return;
  	}
038cbcf65   Eric Paris   Audit: unify the ...
584

c6480207f   Paul Moore   audit: rework the...
585
586
  	/* we have no other options - drop the message */
  	audit_log_lost("kauditd hold queue overflow");
b8d9e0aec   Paul Moore   audit: improve au...
587
  drop:
c6480207f   Paul Moore   audit: rework the...
588
  	kfree_skb(skb);
038cbcf65   Eric Paris   Audit: unify the ...
589
  }
c6480207f   Paul Moore   audit: rework the...
590
591
592
  /**
   * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
   * @skb: audit record
b8d9e0aec   Paul Moore   audit: improve au...
593
   * @error: error code (unused)
c6480207f   Paul Moore   audit: rework the...
594
595
596
597
598
599
   *
   * Description:
   * Not as serious as kauditd_hold_skb() as we still have a connected auditd,
   * but for some reason we are having problems sending it audit records so
   * queue the given record and attempt to resend.
   */
b8d9e0aec   Paul Moore   audit: improve au...
600
  static void kauditd_retry_skb(struct sk_buff *skb, __always_unused int error)
f3d357b09   Eric Paris   Audit: save audit...
601
  {
b8d9e0aec   Paul Moore   audit: improve au...
602
603
604
605
606
607
608
609
610
611
  	if (!audit_backlog_limit ||
  	    skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
  		skb_queue_tail(&audit_retry_queue, skb);
  		return;
  	}
  
  	/* we have to drop the record, send it via printk as a last effort */
  	kauditd_printk_skb(skb);
  	audit_log_lost("kauditd retry queue overflow");
  	kfree_skb(skb);
c6480207f   Paul Moore   audit: rework the...
612
  }
32a1dbaec   Richard Guy Briggs   audit: try harder...
613

c6480207f   Paul Moore   audit: rework the...
614
  /**
264d50963   Paul Moore   audit: make sure ...
615
   * auditd_reset - Disconnect the auditd connection
c81be52a3   Paul Moore   audit: fix a race...
616
   * @ac: auditd connection state
264d50963   Paul Moore   audit: make sure ...
617
618
619
   *
   * Description:
   * Break the auditd/kauditd connection and move all the queued records into the
c81be52a3   Paul Moore   audit: fix a race...
620
621
622
623
   * hold queue in case auditd reconnects.  It is important to note that the @ac
   * pointer should never be dereferenced inside this function as it may be NULL
   * or invalid, you can only compare the memory address!  If @ac is NULL then
   * the connection will always be reset.
264d50963   Paul Moore   audit: make sure ...
624
   */
c81be52a3   Paul Moore   audit: fix a race...
625
  static void auditd_reset(const struct auditd_connection *ac)
264d50963   Paul Moore   audit: make sure ...
626
  {
48d0e023a   Paul Moore   audit: fix the RC...
627
  	unsigned long flags;
264d50963   Paul Moore   audit: make sure ...
628
  	struct sk_buff *skb;
48d0e023a   Paul Moore   audit: fix the RC...
629
  	struct auditd_connection *ac_old;
264d50963   Paul Moore   audit: make sure ...
630
631
  
  	/* if it isn't already broken, break the connection */
48d0e023a   Paul Moore   audit: fix the RC...
632
633
634
  	spin_lock_irqsave(&auditd_conn_lock, flags);
  	ac_old = rcu_dereference_protected(auditd_conn,
  					   lockdep_is_held(&auditd_conn_lock));
c81be52a3   Paul Moore   audit: fix a race...
635
636
637
638
639
  	if (ac && ac != ac_old) {
  		/* someone already registered a new auditd connection */
  		spin_unlock_irqrestore(&auditd_conn_lock, flags);
  		return;
  	}
48d0e023a   Paul Moore   audit: fix the RC...
640
641
642
643
644
  	rcu_assign_pointer(auditd_conn, NULL);
  	spin_unlock_irqrestore(&auditd_conn_lock, flags);
  
  	if (ac_old)
  		call_rcu(&ac_old->rcu, auditd_conn_free);
264d50963   Paul Moore   audit: make sure ...
645

cd33f5f2c   Paul Moore   audit: make sure ...
646
647
  	/* flush the retry queue to the hold queue, but don't touch the main
  	 * queue since we need to process that normally for multicast */
264d50963   Paul Moore   audit: make sure ...
648
  	while ((skb = skb_dequeue(&audit_retry_queue)))
b8d9e0aec   Paul Moore   audit: improve au...
649
  		kauditd_hold_skb(skb, -ECONNREFUSED);
264d50963   Paul Moore   audit: make sure ...
650
651
652
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
653
654
   * auditd_send_unicast_skb - Send a record via unicast to auditd
   * @skb: audit record
c6480207f   Paul Moore   audit: rework the...
655
656
   *
   * Description:
5b52330bb   Paul Moore   audit: fix auditd...
657
658
659
660
661
   * Send a skb to the audit daemon, returns positive/zero values on success and
   * negative values on failure; in all cases the skb will be consumed by this
   * function.  If the send results in -ECONNREFUSED the connection with auditd
   * will be reset.  This function may sleep so callers should not hold any locks
   * where this would cause a problem.
c6480207f   Paul Moore   audit: rework the...
662
   */
5b52330bb   Paul Moore   audit: fix auditd...
663
  static int auditd_send_unicast_skb(struct sk_buff *skb)
c6480207f   Paul Moore   audit: rework the...
664
  {
5b52330bb   Paul Moore   audit: fix auditd...
665
666
667
668
  	int rc;
  	u32 portid;
  	struct net *net;
  	struct sock *sk;
48d0e023a   Paul Moore   audit: fix the RC...
669
  	struct auditd_connection *ac;
5b52330bb   Paul Moore   audit: fix auditd...
670
671
672
673
674
675
676
677
678
  
  	/* NOTE: we can't call netlink_unicast while in the RCU section so
  	 *       take a reference to the network namespace and grab local
  	 *       copies of the namespace, the sock, and the portid; the
  	 *       namespace and sock aren't going to go away while we hold a
  	 *       reference and if the portid does become invalid after the RCU
  	 *       section netlink_unicast() should safely return an error */
  
  	rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
679
680
  	ac = rcu_dereference(auditd_conn);
  	if (!ac) {
5b52330bb   Paul Moore   audit: fix auditd...
681
  		rcu_read_unlock();
b0659ae5e   Shu Wang   audit: fix memlea...
682
  		kfree_skb(skb);
5b52330bb   Paul Moore   audit: fix auditd...
683
684
  		rc = -ECONNREFUSED;
  		goto err;
533c7b69c   Richard Guy Briggs   audit: use proper...
685
  	}
48d0e023a   Paul Moore   audit: fix the RC...
686
  	net = get_net(ac->net);
5b52330bb   Paul Moore   audit: fix auditd...
687
  	sk = audit_get_sk(net);
48d0e023a   Paul Moore   audit: fix the RC...
688
  	portid = ac->portid;
5b52330bb   Paul Moore   audit: fix auditd...
689
  	rcu_read_unlock();
c6480207f   Paul Moore   audit: rework the...
690

5b52330bb   Paul Moore   audit: fix auditd...
691
692
693
694
695
696
697
698
  	rc = netlink_unicast(sk, skb, portid, 0);
  	put_net(net);
  	if (rc < 0)
  		goto err;
  
  	return rc;
  
  err:
c81be52a3   Paul Moore   audit: fix a race...
699
700
  	if (ac && rc == -ECONNREFUSED)
  		auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
701
  	return rc;
c6480207f   Paul Moore   audit: rework the...
702
703
704
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
705
706
707
708
709
710
711
712
713
714
715
716
717
   * kauditd_send_queue - Helper for kauditd_thread to flush skb queues
   * @sk: the sending sock
   * @portid: the netlink destination
   * @queue: the skb queue to process
   * @retry_limit: limit on number of netlink unicast failures
   * @skb_hook: per-skb hook for additional processing
   * @err_hook: hook called if the skb fails the netlink unicast send
   *
   * Description:
   * Run through the given queue and attempt to send the audit records to auditd,
   * returns zero on success, negative values on failure.  It is up to the caller
   * to ensure that the @sk is valid for the duration of this function.
   *
c6480207f   Paul Moore   audit: rework the...
718
   */
5b52330bb   Paul Moore   audit: fix auditd...
719
720
721
722
  static int kauditd_send_queue(struct sock *sk, u32 portid,
  			      struct sk_buff_head *queue,
  			      unsigned int retry_limit,
  			      void (*skb_hook)(struct sk_buff *skb),
b8d9e0aec   Paul Moore   audit: improve au...
723
  			      void (*err_hook)(struct sk_buff *skb, int error))
c6480207f   Paul Moore   audit: rework the...
724
  {
5b52330bb   Paul Moore   audit: fix auditd...
725
  	int rc = 0;
b8d9e0aec   Paul Moore   audit: improve au...
726
727
  	struct sk_buff *skb = NULL;
  	struct sk_buff *skb_tail;
a5f4d17da   Paul Moore   audit: improve ro...
728
  	unsigned int failed = 0;
32a1dbaec   Richard Guy Briggs   audit: try harder...
729

5b52330bb   Paul Moore   audit: fix auditd...
730
731
  	/* NOTE: kauditd_thread takes care of all our locking, we just use
  	 *       the netlink info passed to us (e.g. sk and portid) */
b8d9e0aec   Paul Moore   audit: improve au...
732
733
  	skb_tail = skb_peek_tail(queue);
  	while ((skb != skb_tail) && (skb = skb_dequeue(queue))) {
5b52330bb   Paul Moore   audit: fix auditd...
734
735
736
737
738
739
740
  		/* call the skb_hook for each skb we touch */
  		if (skb_hook)
  			(*skb_hook)(skb);
  
  		/* can we send to anyone via unicast? */
  		if (!sk) {
  			if (err_hook)
b8d9e0aec   Paul Moore   audit: improve au...
741
  				(*err_hook)(skb, -ECONNREFUSED);
5b52330bb   Paul Moore   audit: fix auditd...
742
743
  			continue;
  		}
6c54e7899   Paul Moore   audit: handle a c...
744

a5f4d17da   Paul Moore   audit: improve ro...
745
  retry:
5b52330bb   Paul Moore   audit: fix auditd...
746
747
748
749
  		/* grab an extra skb reference in case of error */
  		skb_get(skb);
  		rc = netlink_unicast(sk, skb, portid, 0);
  		if (rc < 0) {
a5f4d17da   Paul Moore   audit: improve ro...
750
  			/* send failed - try a few times unless fatal error */
5b52330bb   Paul Moore   audit: fix auditd...
751
752
  			if (++failed >= retry_limit ||
  			    rc == -ECONNREFUSED || rc == -EPERM) {
5b52330bb   Paul Moore   audit: fix auditd...
753
754
  				sk = NULL;
  				if (err_hook)
b8d9e0aec   Paul Moore   audit: improve au...
755
  					(*err_hook)(skb, rc);
a5f4d17da   Paul Moore   audit: improve ro...
756
757
758
  				if (rc == -EAGAIN)
  					rc = 0;
  				/* continue to drain the queue */
5b52330bb   Paul Moore   audit: fix auditd...
759
760
  				continue;
  			} else
a5f4d17da   Paul Moore   audit: improve ro...
761
  				goto retry;
5b52330bb   Paul Moore   audit: fix auditd...
762
  		} else {
a5f4d17da   Paul Moore   audit: improve ro...
763
  			/* skb sent - drop the extra reference and continue */
5b52330bb   Paul Moore   audit: fix auditd...
764
765
766
  			consume_skb(skb);
  			failed = 0;
  		}
c6480207f   Paul Moore   audit: rework the...
767
  	}
5b52330bb   Paul Moore   audit: fix auditd...
768
  	return (rc >= 0 ? 0 : rc);
f3d357b09   Eric Paris   Audit: save audit...
769
  }
b551d1d98   Richard Guy Briggs   audit: refactor h...
770
  /*
c6480207f   Paul Moore   audit: rework the...
771
772
   * kauditd_send_multicast_skb - Send a record to any multicast listeners
   * @skb: audit record
451f92163   Richard Guy Briggs   audit: add netlin...
773
   *
c6480207f   Paul Moore   audit: rework the...
774
   * Description:
5b52330bb   Paul Moore   audit: fix auditd...
775
776
777
   * Write a multicast message to anyone listening in the initial network
   * namespace.  This function doesn't consume an skb as might be expected since
   * it has to copy it anyways.
451f92163   Richard Guy Briggs   audit: add netlin...
778
   */
c6480207f   Paul Moore   audit: rework the...
779
  static void kauditd_send_multicast_skb(struct sk_buff *skb)
451f92163   Richard Guy Briggs   audit: add netlin...
780
  {
c6480207f   Paul Moore   audit: rework the...
781
  	struct sk_buff *copy;
5b52330bb   Paul Moore   audit: fix auditd...
782
  	struct sock *sock = audit_get_sk(&init_net);
c6480207f   Paul Moore   audit: rework the...
783
  	struct nlmsghdr *nlh;
451f92163   Richard Guy Briggs   audit: add netlin...
784

5b52330bb   Paul Moore   audit: fix auditd...
785
786
  	/* NOTE: we are not taking an additional reference for init_net since
  	 *       we don't have to worry about it going away */
7f74ecd78   Richard Guy Briggs   audit: send multi...
787
788
  	if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
  		return;
451f92163   Richard Guy Briggs   audit: add netlin...
789
790
791
792
793
794
795
796
797
798
  	/*
  	 * The seemingly wasteful skb_copy() rather than bumping the refcount
  	 * using skb_get() is necessary because non-standard mods are made to
  	 * the skb by the original kaudit unicast socket send routine.  The
  	 * existing auditd daemon assumes this breakage.  Fixing this would
  	 * require co-ordinating a change in the established protocol between
  	 * the kaudit kernel subsystem and the auditd userspace code.  There is
  	 * no reason for new multicast clients to continue with this
  	 * non-compliance.
  	 */
c6480207f   Paul Moore   audit: rework the...
799
  	copy = skb_copy(skb, GFP_KERNEL);
451f92163   Richard Guy Briggs   audit: add netlin...
800
801
  	if (!copy)
  		return;
c6480207f   Paul Moore   audit: rework the...
802
803
  	nlh = nlmsg_hdr(copy);
  	nlh->nlmsg_len = skb->len;
451f92163   Richard Guy Briggs   audit: add netlin...
804

c6480207f   Paul Moore   audit: rework the...
805
  	nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
451f92163   Richard Guy Briggs   audit: add netlin...
806
  }
c6480207f   Paul Moore   audit: rework the...
807
  /**
5b52330bb   Paul Moore   audit: fix auditd...
808
809
   * kauditd_thread - Worker thread to send audit records to userspace
   * @dummy: unused
b551d1d98   Richard Guy Briggs   audit: refactor h...
810
   */
97a41e261   Adrian Bunk   [PATCH] kernel/: ...
811
  static int kauditd_thread(void *dummy)
b7d112581   David Woodhouse   AUDIT: Send netli...
812
  {
c6480207f   Paul Moore   audit: rework the...
813
  	int rc;
5b52330bb   Paul Moore   audit: fix auditd...
814
815
816
  	u32 portid = 0;
  	struct net *net = NULL;
  	struct sock *sk = NULL;
48d0e023a   Paul Moore   audit: fix the RC...
817
  	struct auditd_connection *ac;
4aa83872d   Paul Moore   audit: queue netl...
818

c6480207f   Paul Moore   audit: rework the...
819
  #define UNICAST_RETRIES 5
c6480207f   Paul Moore   audit: rework the...
820

831441862   Rafael J. Wysocki   Freezer: make ker...
821
  	set_freezable();
4899b8b16   Andrew Morton   [PATCH] kauditd_t...
822
  	while (!kthread_should_stop()) {
5b52330bb   Paul Moore   audit: fix auditd...
823
824
  		/* NOTE: see the lock comments in auditd_send_unicast_skb() */
  		rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
825
826
  		ac = rcu_dereference(auditd_conn);
  		if (!ac) {
5b52330bb   Paul Moore   audit: fix auditd...
827
828
829
  			rcu_read_unlock();
  			goto main_queue;
  		}
48d0e023a   Paul Moore   audit: fix the RC...
830
  		net = get_net(ac->net);
5b52330bb   Paul Moore   audit: fix auditd...
831
  		sk = audit_get_sk(net);
48d0e023a   Paul Moore   audit: fix the RC...
832
  		portid = ac->portid;
5b52330bb   Paul Moore   audit: fix auditd...
833
  		rcu_read_unlock();
c6480207f   Paul Moore   audit: rework the...
834
835
  
  		/* attempt to flush the hold queue */
5b52330bb   Paul Moore   audit: fix auditd...
836
837
838
  		rc = kauditd_send_queue(sk, portid,
  					&audit_hold_queue, UNICAST_RETRIES,
  					NULL, kauditd_rehold_skb);
c34c78dfc   Yunfeng Ye   audit: remove red...
839
  		if (rc < 0) {
5b52330bb   Paul Moore   audit: fix auditd...
840
  			sk = NULL;
c81be52a3   Paul Moore   audit: fix a race...
841
  			auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
842
  			goto main_queue;
c6480207f   Paul Moore   audit: rework the...
843
  		}
f3d357b09   Eric Paris   Audit: save audit...
844

c6480207f   Paul Moore   audit: rework the...
845
  		/* attempt to flush the retry queue */
5b52330bb   Paul Moore   audit: fix auditd...
846
847
848
  		rc = kauditd_send_queue(sk, portid,
  					&audit_retry_queue, UNICAST_RETRIES,
  					NULL, kauditd_hold_skb);
c34c78dfc   Yunfeng Ye   audit: remove red...
849
  		if (rc < 0) {
5b52330bb   Paul Moore   audit: fix auditd...
850
  			sk = NULL;
c81be52a3   Paul Moore   audit: fix a race...
851
  			auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
852
  			goto main_queue;
c6480207f   Paul Moore   audit: rework the...
853
  		}
db8973194   Dan Duval   audit: efficiency...
854

5b52330bb   Paul Moore   audit: fix auditd...
855
856
857
858
  main_queue:
  		/* process the main queue - do the multicast send and attempt
  		 * unicast, dump failed record sends to the retry queue; if
  		 * sk == NULL due to previous failures we will just do the
c81be52a3   Paul Moore   audit: fix a race...
859
  		 * multicast send and move the record to the hold queue */
264d50963   Paul Moore   audit: make sure ...
860
861
  		rc = kauditd_send_queue(sk, portid, &audit_queue, 1,
  					kauditd_send_multicast_skb,
c81be52a3   Paul Moore   audit: fix a race...
862
863
864
865
  					(sk ?
  					 kauditd_retry_skb : kauditd_hold_skb));
  		if (ac && rc < 0)
  			auditd_reset(ac);
264d50963   Paul Moore   audit: make sure ...
866
  		sk = NULL;
5b52330bb   Paul Moore   audit: fix auditd...
867
868
869
870
871
  
  		/* drop our netns reference, no auditd sends past this line */
  		if (net) {
  			put_net(net);
  			net = NULL;
3320c5133   Richard Guy Briggs   audit: flatten ka...
872
  		}
5b52330bb   Paul Moore   audit: fix auditd...
873
874
875
876
877
878
879
880
881
882
  
  		/* we have processed all the queues so wake everyone */
  		wake_up(&audit_backlog_wait);
  
  		/* NOTE: we want to wake up if there is anything on the queue,
  		 *       regardless of if an auditd is connected, as we need to
  		 *       do the multicast send and rotate records from the
  		 *       main queue to the retry/hold queues */
  		wait_event_freezable(kauditd_wait,
  				     (skb_queue_len(&audit_queue) ? 1 : 0));
b7d112581   David Woodhouse   AUDIT: Send netli...
883
  	}
c6480207f   Paul Moore   audit: rework the...
884

4899b8b16   Andrew Morton   [PATCH] kauditd_t...
885
  	return 0;
b7d112581   David Woodhouse   AUDIT: Send netli...
886
  }
3054d0671   Paul Moore   audit: fix a net ...
887
  int audit_send_list_thread(void *_dest)
9044e6bca   Al Viro   [PATCH] fix deadl...
888
889
  {
  	struct audit_netlink_list *dest = _dest;
9044e6bca   Al Viro   [PATCH] fix deadl...
890
  	struct sk_buff *skb;
5b52330bb   Paul Moore   audit: fix auditd...
891
  	struct sock *sk = audit_get_sk(dest->net);
9044e6bca   Al Viro   [PATCH] fix deadl...
892
893
  
  	/* wait for parent to finish and send an ACK */
ce423631c   Paul Moore   audit: track the ...
894
895
  	audit_ctl_lock();
  	audit_ctl_unlock();
9044e6bca   Al Viro   [PATCH] fix deadl...
896
897
  
  	while ((skb = __skb_dequeue(&dest->q)) != NULL)
5b52330bb   Paul Moore   audit: fix auditd...
898
  		netlink_unicast(sk, skb, dest->portid, 0);
9044e6bca   Al Viro   [PATCH] fix deadl...
899

5b52330bb   Paul Moore   audit: fix auditd...
900
  	put_net(dest->net);
9044e6bca   Al Viro   [PATCH] fix deadl...
901
902
903
904
  	kfree(dest);
  
  	return 0;
  }
45a0642b4   Paul Moore   audit: kernel gen...
905
  struct sk_buff *audit_make_reply(int seq, int type, int done,
b8800aa5d   Stephen Hemminger   audit: make funct...
906
  				 int multi, const void *payload, int size)
9044e6bca   Al Viro   [PATCH] fix deadl...
907
908
909
  {
  	struct sk_buff	*skb;
  	struct nlmsghdr	*nlh;
9044e6bca   Al Viro   [PATCH] fix deadl...
910
911
912
  	void		*data;
  	int		flags = multi ? NLM_F_MULTI : 0;
  	int		t     = done  ? NLMSG_DONE  : type;
ee080e6ce   Eric Paris   Audit: cleanup ne...
913
  	skb = nlmsg_new(size, GFP_KERNEL);
9044e6bca   Al Viro   [PATCH] fix deadl...
914
915
  	if (!skb)
  		return NULL;
45a0642b4   Paul Moore   audit: kernel gen...
916
  	nlh	= nlmsg_put(skb, 0, seq, t, size, flags);
c64e66c67   David S. Miller   audit: netlink: M...
917
918
919
  	if (!nlh)
  		goto out_kfree_skb;
  	data = nlmsg_data(nlh);
9044e6bca   Al Viro   [PATCH] fix deadl...
920
921
  	memcpy(data, payload, size);
  	return skb;
c64e66c67   David S. Miller   audit: netlink: M...
922
923
  out_kfree_skb:
  	kfree_skb(skb);
9044e6bca   Al Viro   [PATCH] fix deadl...
924
925
  	return NULL;
  }
a48b284b4   Paul Moore   audit: fix a net ...
926
927
928
929
  static void audit_free_reply(struct audit_reply *reply)
  {
  	if (!reply)
  		return;
c07203516   Xu Wang   audit: Remove red...
930
  	kfree_skb(reply->skb);
a48b284b4   Paul Moore   audit: fix a net ...
931
932
933
934
  	if (reply->net)
  		put_net(reply->net);
  	kfree(reply);
  }
f09ac9db2   Eric Paris   Audit: stop deadl...
935
936
937
  static int audit_send_reply_thread(void *arg)
  {
  	struct audit_reply *reply = (struct audit_reply *)arg;
ce423631c   Paul Moore   audit: track the ...
938
939
  	audit_ctl_lock();
  	audit_ctl_unlock();
f09ac9db2   Eric Paris   Audit: stop deadl...
940
941
942
  
  	/* Ignore failure. It'll only happen if the sender goes away,
  	   because our timeout is set to infinite. */
a48b284b4   Paul Moore   audit: fix a net ...
943
944
945
  	netlink_unicast(audit_get_sk(reply->net), reply->skb, reply->portid, 0);
  	reply->skb = NULL;
  	audit_free_reply(reply);
f09ac9db2   Eric Paris   Audit: stop deadl...
946
947
  	return 0;
  }
c6480207f   Paul Moore   audit: rework the...
948

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
949
950
  /**
   * audit_send_reply - send an audit reply message via netlink
d211f177b   Eric W. Biederman   audit: Update kdo...
951
   * @request_skb: skb of request we are replying to (used to target the reply)
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
952
953
954
955
956
957
958
   * @seq: sequence number
   * @type: audit message type
   * @done: done (last) flag
   * @multi: multi-part message flag
   * @payload: payload data
   * @size: payload size
   *
a48b284b4   Paul Moore   audit: fix a net ...
959
   * Allocates a skb, builds the netlink message, and sends it to the port id.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
960
   */
6f285b19d   Eric W. Biederman   audit: Send repli...
961
  static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
f9441639e   Richard Guy Briggs   audit: fix netlin...
962
  			     int multi, const void *payload, int size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
  {
f09ac9db2   Eric Paris   Audit: stop deadl...
964
  	struct task_struct *tsk;
a48b284b4   Paul Moore   audit: fix a net ...
965
  	struct audit_reply *reply;
f09ac9db2   Eric Paris   Audit: stop deadl...
966

a48b284b4   Paul Moore   audit: fix a net ...
967
  	reply = kzalloc(sizeof(*reply), GFP_KERNEL);
f09ac9db2   Eric Paris   Audit: stop deadl...
968
969
  	if (!reply)
  		return;
a48b284b4   Paul Moore   audit: fix a net ...
970
971
972
973
  	reply->skb = audit_make_reply(seq, type, done, multi, payload, size);
  	if (!reply->skb)
  		goto err;
  	reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
45a0642b4   Paul Moore   audit: kernel gen...
974
  	reply->portid = NETLINK_CB(request_skb).portid;
f09ac9db2   Eric Paris   Audit: stop deadl...
975
976
  
  	tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
a48b284b4   Paul Moore   audit: fix a net ...
977
978
979
980
981
982
983
  	if (IS_ERR(tsk))
  		goto err;
  
  	return;
  
  err:
  	audit_free_reply(reply);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984
985
986
987
988
989
  }
  
  /*
   * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
   * control messages.
   */
c7bdb545d   Darrel Goeddel   [NETLINK]: Encaps...
990
  static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991
992
  {
  	int err = 0;
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
993
  	/* Only support initial user namespace for now. */
aa4af831b   Eric Paris   AUDIT: Allow logi...
994
995
996
997
998
999
1000
1001
1002
1003
  	/*
  	 * We return ECONNREFUSED because it tricks userspace into thinking
  	 * that audit was not configured into the kernel.  Lots of users
  	 * configure their PAM stack (because that's what the distro does)
  	 * to reject login if unable to send messages to audit.  If we return
  	 * ECONNREFUSED the PAM stack thinks the kernel does not have audit
  	 * configured in and will let login proceed.  If we return EPERM
  	 * userspace will reject all logins.  This should be removed when we
  	 * support non init namespaces!!
  	 */
0b747172d   Linus Torvalds   Merge git://git.i...
1004
  	if (current_user_ns() != &init_user_ns)
aa4af831b   Eric Paris   AUDIT: Allow logi...
1005
  		return -ECONNREFUSED;
34e36d8ec   Eric W. Biederman   audit: Limit audi...
1006

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
  	switch (msg_type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1008
  	case AUDIT_LIST:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
1010
  	case AUDIT_ADD:
  	case AUDIT_DEL:
189009091   Eric Paris   audit: remove the...
1011
1012
1013
  		return -EOPNOTSUPP;
  	case AUDIT_GET:
  	case AUDIT_SET:
b0fed4021   Eric Paris   audit: implement ...
1014
1015
  	case AUDIT_GET_FEATURE:
  	case AUDIT_SET_FEATURE:
189009091   Eric Paris   audit: remove the...
1016
1017
  	case AUDIT_LIST_RULES:
  	case AUDIT_ADD_RULE:
93315ed6d   Amy Griffis   [PATCH] audit str...
1018
  	case AUDIT_DEL_RULE:
c2f0c7c35   Steve Grubb   The attached patc...
1019
  	case AUDIT_SIGNAL_INFO:
522ed7767   Miloslav Trmac   Audit: add TTY in...
1020
1021
  	case AUDIT_TTY_GET:
  	case AUDIT_TTY_SET:
74c3cbe33   Al Viro   [PATCH] audit: wa...
1022
1023
  	case AUDIT_TRIM:
  	case AUDIT_MAKE_EQUIV:
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
1024
1025
  		/* Only support auditd and auditctl in initial pid namespace
  		 * for now. */
5985de675   Ameen Ali   audit: code clean up
1026
  		if (task_active_pid_ns(current) != &init_pid_ns)
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
1027
  			return -EPERM;
90f62cf30   Eric W. Biederman   net: Use netlink_...
1028
  		if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
  			err = -EPERM;
  		break;
05474106a   Steve Grubb   AUDIT: Fix AVC_US...
1031
  	case AUDIT_USER:
039b6b3ed   Robert P. J. Day   audit: add spaces...
1032
1033
  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
  	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
90f62cf30   Eric W. Biederman   net: Use netlink_...
1034
  		if (!netlink_capable(skb, CAP_AUDIT_WRITE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
1036
1037
1038
1039
1040
1041
1042
  			err = -EPERM;
  		break;
  	default:  /* bad msg */
  		err = -EINVAL;
  	}
  
  	return err;
  }
626abcd13   Richard Guy Briggs   audit: add syscal...
1043
1044
  static void audit_log_common_recv_msg(struct audit_context *context,
  					struct audit_buffer **ab, u16 msg_type)
50397bd1e   Eric Paris   [AUDIT] clean up ...
1045
  {
dc9eb698f   Eric Paris   audit: stop pushi...
1046
  	uid_t uid = from_kuid(&init_user_ns, current_uid());
f1dc4867f   Richard Guy Briggs   audit: anchor all...
1047
  	pid_t pid = task_tgid_nr(current);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1048

0868a5e15   Tyler Hicks   audit: printk USE...
1049
  	if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
50397bd1e   Eric Paris   [AUDIT] clean up ...
1050
  		*ab = NULL;
233a68667   Paul Moore   audit: make audit...
1051
  		return;
50397bd1e   Eric Paris   [AUDIT] clean up ...
1052
  	}
626abcd13   Richard Guy Briggs   audit: add syscal...
1053
  	*ab = audit_log_start(context, GFP_KERNEL, msg_type);
0644ec0cc   Kees Cook   audit: catch poss...
1054
  	if (unlikely(!*ab))
233a68667   Paul Moore   audit: make audit...
1055
  		return;
a2c97da11   Richard Guy Briggs   audit: use sessio...
1056
  	audit_log_format(*ab, "pid=%d uid=%u ", pid, uid);
4d3fb709b   Eric Paris   helper for some s...
1057
  	audit_log_session_info(*ab);
b122c3767   Eric Paris   audit: use a cons...
1058
  	audit_log_task_context(*ab);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1059
  }
626abcd13   Richard Guy Briggs   audit: add syscal...
1060
1061
1062
1063
1064
  static inline void audit_log_user_recv_msg(struct audit_buffer **ab,
  					   u16 msg_type)
  {
  	audit_log_common_recv_msg(NULL, ab, msg_type);
  }
b0fed4021   Eric Paris   audit: implement ...
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
  int is_audit_feature_set(int i)
  {
  	return af.features & AUDIT_FEATURE_TO_MASK(i);
  }
  
  
  static int audit_get_feature(struct sk_buff *skb)
  {
  	u32 seq;
  
  	seq = nlmsg_hdr(skb)->nlmsg_seq;
9ef915147   Richard Guy Briggs   audit: correct AU...
1076
  	audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
b0fed4021   Eric Paris   audit: implement ...
1077
1078
1079
1080
1081
1082
1083
1084
  
  	return 0;
  }
  
  static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature,
  				     u32 old_lock, u32 new_lock, int res)
  {
  	struct audit_buffer *ab;
b6c50fe0b   Gao feng   audit: don't gene...
1085
1086
  	if (audit_enabled == AUDIT_OFF)
  		return;
2a1fe215e   Paul Moore   audit: use curren...
1087

cdfb6b341   Richard Guy Briggs   audit: use inline...
1088
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_FEATURE_CHANGE);
23138ead2   Richard Guy Briggs   audit: return on ...
1089
1090
  	if (!ab)
  		return;
2a1fe215e   Paul Moore   audit: use curren...
1091
  	audit_log_task_info(ab);
897f1acbb   Richard Guy Briggs   audit: AUDIT_FEAT...
1092
  	audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d",
b0fed4021   Eric Paris   audit: implement ...
1093
1094
1095
1096
  			 audit_feature_names[which], !!old_feature, !!new_feature,
  			 !!old_lock, !!new_lock, res);
  	audit_log_end(ab);
  }
756125289   Paul Moore   audit: always che...
1097
  static int audit_set_feature(struct audit_features *uaf)
b0fed4021   Eric Paris   audit: implement ...
1098
  {
b0fed4021   Eric Paris   audit: implement ...
1099
  	int i;
6eed9b261   Fabian Frederick   kernel/audit.c: u...
1100
  	BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
b0fed4021   Eric Paris   audit: implement ...
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
  
  	/* if there is ever a version 2 we should handle that here */
  
  	for (i = 0; i <= AUDIT_LAST_FEATURE; i++) {
  		u32 feature = AUDIT_FEATURE_TO_MASK(i);
  		u32 old_feature, new_feature, old_lock, new_lock;
  
  		/* if we are not changing this feature, move along */
  		if (!(feature & uaf->mask))
  			continue;
  
  		old_feature = af.features & feature;
  		new_feature = uaf->features & feature;
  		new_lock = (uaf->lock | af.lock) & feature;
  		old_lock = af.lock & feature;
  
  		/* are we changing a locked feature? */
4547b3bc4   Gao feng   audit: use old_lo...
1118
  		if (old_lock && (new_feature != old_feature)) {
b0fed4021   Eric Paris   audit: implement ...
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  			audit_log_feature_change(i, old_feature, new_feature,
  						 old_lock, new_lock, 0);
  			return -EPERM;
  		}
  	}
  	/* nothing invalid, do the changes */
  	for (i = 0; i <= AUDIT_LAST_FEATURE; i++) {
  		u32 feature = AUDIT_FEATURE_TO_MASK(i);
  		u32 old_feature, new_feature, old_lock, new_lock;
  
  		/* if we are not changing this feature, move along */
  		if (!(feature & uaf->mask))
  			continue;
  
  		old_feature = af.features & feature;
  		new_feature = uaf->features & feature;
  		old_lock = af.lock & feature;
  		new_lock = (uaf->lock | af.lock) & feature;
  
  		if (new_feature != old_feature)
  			audit_log_feature_change(i, old_feature, new_feature,
  						 old_lock, new_lock, 1);
  
  		if (new_feature)
  			af.features |= feature;
  		else
  			af.features &= ~feature;
  		af.lock |= new_lock;
  	}
  
  	return 0;
  }
b6c7c115c   Paul Moore   audit: store the ...
1151
  static int audit_replace(struct pid *pid)
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1152
  {
b6c7c115c   Paul Moore   audit: store the ...
1153
  	pid_t pvnr;
5b52330bb   Paul Moore   audit: fix auditd...
1154
  	struct sk_buff *skb;
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1155

b6c7c115c   Paul Moore   audit: store the ...
1156
1157
  	pvnr = pid_vnr(pid);
  	skb = audit_make_reply(0, AUDIT_REPLACE, 0, 0, &pvnr, sizeof(pvnr));
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1158
1159
  	if (!skb)
  		return -ENOMEM;
5b52330bb   Paul Moore   audit: fix auditd...
1160
  	return auditd_send_unicast_skb(skb);
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1161
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
1163
  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  {
dc9eb698f   Eric Paris   audit: stop pushi...
1164
  	u32			seq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1165
  	void			*data;
756125289   Paul Moore   audit: always che...
1166
  	int			data_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167
  	int			err;
c04049939   Steve Grubb   AUDIT: Add messag...
1168
  	struct audit_buffer	*ab;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
  	u16			msg_type = nlh->nlmsg_type;
e1396065e   Al Viro   [PATCH] collect s...
1170
  	struct audit_sig_info   *sig_data;
50397bd1e   Eric Paris   [AUDIT] clean up ...
1171
  	char			*ctx = NULL;
e1396065e   Al Viro   [PATCH] collect s...
1172
  	u32			len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173

c7bdb545d   Darrel Goeddel   [NETLINK]: Encaps...
1174
  	err = audit_netlink_ok(skb, msg_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
1176
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177
  	seq  = nlh->nlmsg_seq;
c64e66c67   David S. Miller   audit: netlink: M...
1178
  	data = nlmsg_data(nlh);
756125289   Paul Moore   audit: always che...
1179
  	data_len = nlmsg_len(nlh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1180
1181
  
  	switch (msg_type) {
09f883a90   Richard Guy Briggs   audit: clean up A...
1182
1183
1184
  	case AUDIT_GET: {
  		struct audit_status	s;
  		memset(&s, 0, sizeof(s));
b43870c74   Max Englander   audit: report aud...
1185
1186
  		s.enabled		   = audit_enabled;
  		s.failure		   = audit_failure;
b6c7c115c   Paul Moore   audit: store the ...
1187
1188
  		/* NOTE: use pid_vnr() so the PID is relative to the current
  		 *       namespace */
b43870c74   Max Englander   audit: report aud...
1189
1190
1191
1192
1193
1194
1195
1196
  		s.pid			   = auditd_pid_vnr();
  		s.rate_limit		   = audit_rate_limit;
  		s.backlog_limit		   = audit_backlog_limit;
  		s.lost			   = atomic_read(&audit_lost);
  		s.backlog		   = skb_queue_len(&audit_queue);
  		s.feature_bitmap	   = AUDIT_FEATURE_BITMAP_ALL;
  		s.backlog_wait_time	   = audit_backlog_wait_time;
  		s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
6f285b19d   Eric W. Biederman   audit: Send repli...
1197
  		audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198
  		break;
09f883a90   Richard Guy Briggs   audit: clean up A...
1199
1200
1201
1202
1203
  	}
  	case AUDIT_SET: {
  		struct audit_status	s;
  		memset(&s, 0, sizeof(s));
  		/* guard against past and future API changes */
756125289   Paul Moore   audit: always che...
1204
  		memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
09f883a90   Richard Guy Briggs   audit: clean up A...
1205
1206
  		if (s.mask & AUDIT_STATUS_ENABLED) {
  			err = audit_set_enabled(s.enabled);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1207
1208
  			if (err < 0)
  				return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1209
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1210
1211
  		if (s.mask & AUDIT_STATUS_FAILURE) {
  			err = audit_set_failure(s.failure);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1212
1213
  			if (err < 0)
  				return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1214
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1215
  		if (s.mask & AUDIT_STATUS_PID) {
b6c7c115c   Paul Moore   audit: store the ...
1216
1217
1218
1219
1220
1221
1222
  			/* NOTE: we are using the vnr PID functions below
  			 *       because the s.pid value is relative to the
  			 *       namespace of the caller; at present this
  			 *       doesn't matter much since you can really only
  			 *       run auditd from the initial pid namespace, but
  			 *       something to keep in mind if this changes */
  			pid_t new_pid = s.pid;
5b52330bb   Paul Moore   audit: fix auditd...
1223
  			pid_t auditd_pid;
b6c7c115c   Paul Moore   audit: store the ...
1224
  			struct pid *req_pid = task_tgid(current);
33e8a9078   Steve Grubb   audit: Allow audi...
1225
1226
1227
  			/* Sanity check - PID values must match. Setting
  			 * pid to 0 is how auditd ends auditing. */
  			if (new_pid && (new_pid != pid_vnr(req_pid)))
b6c7c115c   Paul Moore   audit: store the ...
1228
  				return -EINVAL;
1a6b9f231   Eric Paris   [AUDIT] make audi...
1229

5b52330bb   Paul Moore   audit: fix auditd...
1230
  			/* test the auditd connection */
b6c7c115c   Paul Moore   audit: store the ...
1231
  			audit_replace(req_pid);
5b52330bb   Paul Moore   audit: fix auditd...
1232

48d0e023a   Paul Moore   audit: fix the RC...
1233
  			auditd_pid = auditd_pid_vnr();
33e8a9078   Steve Grubb   audit: Allow audi...
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
  			if (auditd_pid) {
  				/* replacing a healthy auditd is not allowed */
  				if (new_pid) {
  					audit_log_config_change("audit_pid",
  							new_pid, auditd_pid, 0);
  					return -EEXIST;
  				}
  				/* only current auditd can unregister itself */
  				if (pid_vnr(req_pid) != auditd_pid) {
  					audit_log_config_change("audit_pid",
  							new_pid, auditd_pid, 0);
  					return -EACCES;
  				}
935c9e7ff   Richard Guy Briggs   audit: log failed...
1247
  			}
5b52330bb   Paul Moore   audit: fix auditd...
1248

533c7b69c   Richard Guy Briggs   audit: use proper...
1249
  			if (new_pid) {
5b52330bb   Paul Moore   audit: fix auditd...
1250
  				/* register a new auditd connection */
48d0e023a   Paul Moore   audit: fix the RC...
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
  				err = auditd_set(req_pid,
  						 NETLINK_CB(skb).portid,
  						 sock_net(NETLINK_CB(skb).sk));
  				if (audit_enabled != AUDIT_OFF)
  					audit_log_config_change("audit_pid",
  								new_pid,
  								auditd_pid,
  								err ? 0 : 1);
  				if (err)
  					return err;
5b52330bb   Paul Moore   audit: fix auditd...
1261
1262
  				/* try to process any backlog */
  				wake_up_interruptible(&kauditd_wait);
48d0e023a   Paul Moore   audit: fix the RC...
1263
1264
1265
1266
1267
  			} else {
  				if (audit_enabled != AUDIT_OFF)
  					audit_log_config_change("audit_pid",
  								new_pid,
  								auditd_pid, 1);
5b52330bb   Paul Moore   audit: fix auditd...
1268
  				/* unregister the auditd connection */
c81be52a3   Paul Moore   audit: fix a race...
1269
  				auditd_reset(NULL);
48d0e023a   Paul Moore   audit: fix the RC...
1270
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1271
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1272
1273
  		if (s.mask & AUDIT_STATUS_RATE_LIMIT) {
  			err = audit_set_rate_limit(s.rate_limit);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1274
1275
1276
  			if (err < 0)
  				return err;
  		}
51cc83f02   Richard Guy Briggs   audit: add audit_...
1277
  		if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) {
09f883a90   Richard Guy Briggs   audit: clean up A...
1278
  			err = audit_set_backlog_limit(s.backlog_limit);
51cc83f02   Richard Guy Briggs   audit: add audit_...
1279
1280
1281
  			if (err < 0)
  				return err;
  		}
3f0c5fad8   Eric Paris   audit: remove nee...
1282
1283
1284
  		if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) {
  			if (sizeof(s) > (size_t)nlh->nlmsg_len)
  				return -EINVAL;
724e7bfcc   Pranith Kumar   audit: Remove con...
1285
  			if (s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME)
3f0c5fad8   Eric Paris   audit: remove nee...
1286
1287
1288
1289
  				return -EINVAL;
  			err = audit_set_backlog_wait_time(s.backlog_wait_time);
  			if (err < 0)
  				return err;
51cc83f02   Richard Guy Briggs   audit: add audit_...
1290
  		}
92c82e8a3   Richard Guy Briggs   audit: add featur...
1291
1292
1293
1294
1295
1296
  		if (s.mask == AUDIT_STATUS_LOST) {
  			u32 lost = atomic_xchg(&audit_lost, 0);
  
  			audit_log_config_change("lost", 0, lost, 1);
  			return lost;
  		}
b43870c74   Max Englander   audit: report aud...
1297
1298
1299
1300
1301
1302
  		if (s.mask == AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL) {
  			u32 actual = atomic_xchg(&audit_backlog_wait_time_actual, 0);
  
  			audit_log_config_change("backlog_wait_time_actual", 0, actual, 1);
  			return actual;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
  		break;
09f883a90   Richard Guy Briggs   audit: clean up A...
1304
  	}
b0fed4021   Eric Paris   audit: implement ...
1305
1306
1307
1308
1309
1310
  	case AUDIT_GET_FEATURE:
  		err = audit_get_feature(skb);
  		if (err)
  			return err;
  		break;
  	case AUDIT_SET_FEATURE:
756125289   Paul Moore   audit: always che...
1311
1312
1313
  		if (data_len < sizeof(struct audit_features))
  			return -EINVAL;
  		err = audit_set_feature(data);
b0fed4021   Eric Paris   audit: implement ...
1314
1315
1316
  		if (err)
  			return err;
  		break;
05474106a   Steve Grubb   AUDIT: Fix AVC_US...
1317
  	case AUDIT_USER:
039b6b3ed   Robert P. J. Day   audit: add spaces...
1318
1319
  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
  	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1320
1321
  		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
  			return 0;
763dafc52   Paul Moore   audit: check the ...
1322
1323
1324
  		/* exit early if there isn't at least one character to print */
  		if (data_len < 2)
  			return -EINVAL;
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1325

86b2efbe3   Richard Guy Briggs   audit: add fields...
1326
  		err = audit_filter(msg_type, AUDIT_FILTER_USER);
724e4fcc8   Richard Guy Briggs   audit: log on err...
1327
  		if (err == 1) { /* match or error */
756125289   Paul Moore   audit: always che...
1328
  			char *str = data;
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1329
  			err = 0;
522ed7767   Miloslav Trmac   Audit: add TTY in...
1330
  			if (msg_type == AUDIT_USER_TTY) {
37282a779   Peter Hurley   tty: audit: Combi...
1331
  				err = tty_audit_push();
522ed7767   Miloslav Trmac   Audit: add TTY in...
1332
1333
1334
  				if (err)
  					break;
  			}
626abcd13   Richard Guy Briggs   audit: add syscal...
1335
  			audit_log_user_recv_msg(&ab, msg_type);
756125289   Paul Moore   audit: always che...
1336
1337
1338
  			if (msg_type != AUDIT_USER_TTY) {
  				/* ensure NULL termination */
  				str[data_len - 1] = '\0';
b50eba7e2   Richard Guy Briggs   audit: format use...
1339
1340
  				audit_log_format(ab, " msg='%.*s'",
  						 AUDIT_MESSAGE_TEXT_MAX,
756125289   Paul Moore   audit: always che...
1341
1342
  						 str);
  			} else {
f7616102d   Eric Paris   audit: use data= ...
1343
  				audit_log_format(ab, " data=");
756125289   Paul Moore   audit: always che...
1344
1345
1346
  				if (data_len > 0 && str[data_len - 1] == '\0')
  					data_len--;
  				audit_log_n_untrustedstring(ab, str, data_len);
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1347
  			}
50397bd1e   Eric Paris   [AUDIT] clean up ...
1348
  			audit_log_end(ab);
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1349
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350
  		break;
93315ed6d   Amy Griffis   [PATCH] audit str...
1351
1352
  	case AUDIT_ADD_RULE:
  	case AUDIT_DEL_RULE:
756125289   Paul Moore   audit: always che...
1353
  		if (data_len < sizeof(struct audit_rule_data))
93315ed6d   Amy Griffis   [PATCH] audit str...
1354
  			return -EINVAL;
1a6b9f231   Eric Paris   [AUDIT] make audi...
1355
  		if (audit_enabled == AUDIT_LOCKED) {
626abcd13   Richard Guy Briggs   audit: add syscal...
1356
1357
  			audit_log_common_recv_msg(audit_context(), &ab,
  						  AUDIT_CONFIG_CHANGE);
53fc7a01d   Richard Guy Briggs   audit: give a clu...
1358
1359
1360
1361
  			audit_log_format(ab, " op=%s audit_enabled=%d res=0",
  					 msg_type == AUDIT_ADD_RULE ?
  						"add_rule" : "remove_rule",
  					 audit_enabled);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1362
  			audit_log_end(ab);
6a01b07fa   Steve Grubb   [PATCH] audit con...
1363
1364
  			return -EPERM;
  		}
756125289   Paul Moore   audit: always che...
1365
  		err = audit_rule_change(msg_type, seq, data, data_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1366
  		break;
ce0d9f046   Richard Guy Briggs   audit: refactor a...
1367
  	case AUDIT_LIST_RULES:
6f285b19d   Eric W. Biederman   audit: Send repli...
1368
  		err = audit_list_rules_send(skb, seq);
ce0d9f046   Richard Guy Briggs   audit: refactor a...
1369
  		break;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1370
1371
  	case AUDIT_TRIM:
  		audit_trim_trees();
626abcd13   Richard Guy Briggs   audit: add syscal...
1372
1373
  		audit_log_common_recv_msg(audit_context(), &ab,
  					  AUDIT_CONFIG_CHANGE);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1374
1375
1376
1377
1378
1379
  		audit_log_format(ab, " op=trim res=1");
  		audit_log_end(ab);
  		break;
  	case AUDIT_MAKE_EQUIV: {
  		void *bufp = data;
  		u32 sizes[2];
756125289   Paul Moore   audit: always che...
1380
  		size_t msglen = data_len;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1381
1382
1383
  		char *old, *new;
  
  		err = -EINVAL;
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1384
  		if (msglen < 2 * sizeof(u32))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1385
1386
1387
  			break;
  		memcpy(sizes, bufp, 2 * sizeof(u32));
  		bufp += 2 * sizeof(u32);
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1388
1389
  		msglen -= 2 * sizeof(u32);
  		old = audit_unpack_string(&bufp, &msglen, sizes[0]);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1390
1391
1392
1393
  		if (IS_ERR(old)) {
  			err = PTR_ERR(old);
  			break;
  		}
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1394
  		new = audit_unpack_string(&bufp, &msglen, sizes[1]);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1395
1396
1397
1398
1399
1400
1401
  		if (IS_ERR(new)) {
  			err = PTR_ERR(new);
  			kfree(old);
  			break;
  		}
  		/* OK, here comes... */
  		err = audit_tag_tree(old, new);
626abcd13   Richard Guy Briggs   audit: add syscal...
1402
1403
  		audit_log_common_recv_msg(audit_context(), &ab,
  					  AUDIT_CONFIG_CHANGE);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
  		audit_log_format(ab, " op=make_equiv old=");
  		audit_log_untrustedstring(ab, old);
  		audit_log_format(ab, " new=");
  		audit_log_untrustedstring(ab, new);
  		audit_log_format(ab, " res=%d", !err);
  		audit_log_end(ab);
  		kfree(old);
  		kfree(new);
  		break;
  	}
c2f0c7c35   Steve Grubb   The attached patc...
1414
  	case AUDIT_SIGNAL_INFO:
939cbf260   Eric Paris   Audit: send signa...
1415
1416
1417
1418
1419
1420
  		len = 0;
  		if (audit_sig_sid) {
  			err = security_secid_to_secctx(audit_sig_sid, &ctx, &len);
  			if (err)
  				return err;
  		}
e1396065e   Al Viro   [PATCH] collect s...
1421
1422
  		sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
  		if (!sig_data) {
939cbf260   Eric Paris   Audit: send signa...
1423
1424
  			if (audit_sig_sid)
  				security_release_secctx(ctx, len);
e1396065e   Al Viro   [PATCH] collect s...
1425
1426
  			return -ENOMEM;
  		}
cca080d9b   Eric W. Biederman   userns: Convert a...
1427
  		sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
e1396065e   Al Viro   [PATCH] collect s...
1428
  		sig_data->pid = audit_sig_pid;
939cbf260   Eric Paris   Audit: send signa...
1429
1430
1431
1432
  		if (audit_sig_sid) {
  			memcpy(sig_data->ctx, ctx, len);
  			security_release_secctx(ctx, len);
  		}
6f285b19d   Eric W. Biederman   audit: Send repli...
1433
1434
  		audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
  				 sig_data, sizeof(*sig_data) + len);
e1396065e   Al Viro   [PATCH] collect s...
1435
  		kfree(sig_data);
c2f0c7c35   Steve Grubb   The attached patc...
1436
  		break;
522ed7767   Miloslav Trmac   Audit: add TTY in...
1437
1438
  	case AUDIT_TTY_GET: {
  		struct audit_tty_status s;
2e28d38ae   Peter Hurley   tty: audit: Handl...
1439
  		unsigned int t;
8aa14b649   Eric W. Biederman   audit: Simply AUD...
1440

2e28d38ae   Peter Hurley   tty: audit: Handl...
1441
1442
1443
  		t = READ_ONCE(current->signal->audit_tty);
  		s.enabled = t & AUDIT_TTY_ENABLE;
  		s.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
8aa14b649   Eric W. Biederman   audit: Simply AUD...
1444

6f285b19d   Eric W. Biederman   audit: Send repli...
1445
  		audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
522ed7767   Miloslav Trmac   Audit: add TTY in...
1446
1447
1448
  		break;
  	}
  	case AUDIT_TTY_SET: {
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1449
  		struct audit_tty_status s, old;
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1450
  		struct audit_buffer	*ab;
2e28d38ae   Peter Hurley   tty: audit: Handl...
1451
  		unsigned int t;
0e23bacca   Eric Paris   audit: rework AUD...
1452
1453
1454
  
  		memset(&s, 0, sizeof(s));
  		/* guard against past and future API changes */
756125289   Paul Moore   audit: always che...
1455
  		memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
0e23bacca   Eric Paris   audit: rework AUD...
1456
1457
1458
1459
  		/* check if new data is valid */
  		if ((s.enabled != 0 && s.enabled != 1) ||
  		    (s.log_passwd != 0 && s.log_passwd != 1))
  			err = -EINVAL;
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1460

2e28d38ae   Peter Hurley   tty: audit: Handl...
1461
1462
1463
1464
1465
  		if (err)
  			t = READ_ONCE(current->signal->audit_tty);
  		else {
  			t = s.enabled | (-s.log_passwd & AUDIT_TTY_LOG_PASSWD);
  			t = xchg(&current->signal->audit_tty, t);
0e23bacca   Eric Paris   audit: rework AUD...
1466
  		}
2e28d38ae   Peter Hurley   tty: audit: Handl...
1467
1468
  		old.enabled = t & AUDIT_TTY_ENABLE;
  		old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
522ed7767   Miloslav Trmac   Audit: add TTY in...
1469

626abcd13   Richard Guy Briggs   audit: add syscal...
1470
1471
  		audit_log_common_recv_msg(audit_context(), &ab,
  					  AUDIT_CONFIG_CHANGE);
1ce319f11   Eric Paris   audit: reorder AU...
1472
1473
1474
1475
  		audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d"
  				 " old-log_passwd=%d new-log_passwd=%d res=%d",
  				 old.enabled, s.enabled, old.log_passwd,
  				 s.log_passwd, !err);
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1476
  		audit_log_end(ab);
522ed7767   Miloslav Trmac   Audit: add TTY in...
1477
1478
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1479
1480
1481
1482
1483
1484
1485
  	default:
  		err = -EINVAL;
  		break;
  	}
  
  	return err < 0 ? err : 0;
  }
a9d162087   Paul Moore   audit: combine au...
1486
1487
1488
1489
1490
1491
  /**
   * audit_receive - receive messages from a netlink control socket
   * @skb: the message buffer
   *
   * Parse the provided skb and deal with any messages that may be present,
   * malformed skbs are discarded.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1492
   */
a9d162087   Paul Moore   audit: combine au...
1493
  static void audit_receive(struct sk_buff  *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
  {
ea7ae60bf   Eric Paris   Audit: clean up a...
1495
1496
  	struct nlmsghdr *nlh;
  	/*
941912133   Hong zhi guo   audit: replace ob...
1497
  	 * len MUST be signed for nlmsg_next to be able to dec it below 0
ea7ae60bf   Eric Paris   Audit: clean up a...
1498
1499
1500
1501
1502
1503
1504
  	 * if the nlmsg_len was not aligned
  	 */
  	int len;
  	int err;
  
  	nlh = nlmsg_hdr(skb);
  	len = skb->len;
ce423631c   Paul Moore   audit: track the ...
1505
  	audit_ctl_lock();
941912133   Hong zhi guo   audit: replace ob...
1506
  	while (nlmsg_ok(nlh, len)) {
ea7ae60bf   Eric Paris   Audit: clean up a...
1507
1508
1509
  		err = audit_receive_msg(skb, nlh);
  		/* if err or if this message says it wants a response */
  		if (err || (nlh->nlmsg_flags & NLM_F_ACK))
2d4bc9336   Johannes Berg   netlink: extended...
1510
  			netlink_ack(skb, nlh, err, NULL);
ea7ae60bf   Eric Paris   Audit: clean up a...
1511

2851da570   Alexandru Copot   audit: pass int* ...
1512
  		nlh = nlmsg_next(nlh, &len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  	}
ce423631c   Paul Moore   audit: track the ...
1514
  	audit_ctl_unlock();
d978295bb   Paul Moore   audit: ensure use...
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
  
  	/* can't block with the ctrl lock, so penalize the sender now */
  	if (audit_backlog_limit &&
  	    (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
  		DECLARE_WAITQUEUE(wait, current);
  
  		/* wake kauditd to try and flush the queue */
  		wake_up_interruptible(&kauditd_wait);
  
  		add_wait_queue_exclusive(&audit_backlog_wait, &wait);
  		set_current_state(TASK_UNINTERRUPTIBLE);
  		schedule_timeout(audit_backlog_wait_time);
  		remove_wait_queue(&audit_backlog_wait, &wait);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
  }
9d2161bed   Richard Guy Briggs   audit: log audit ...
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
  /* Log information about who is connecting to the audit multicast socket */
  static void audit_log_multicast(int group, const char *op, int err)
  {
  	const struct cred *cred;
  	struct tty_struct *tty;
  	char comm[sizeof(current->comm)];
  	struct audit_buffer *ab;
  
  	if (!audit_enabled)
  		return;
  
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER);
  	if (!ab)
  		return;
  
  	cred = current_cred();
  	tty = audit_get_tty();
  	audit_log_format(ab, "pid=%u uid=%u auid=%u tty=%s ses=%u",
  			 task_pid_nr(current),
  			 from_kuid(&init_user_ns, cred->uid),
  			 from_kuid(&init_user_ns, audit_get_loginuid(current)),
  			 tty ? tty_name(tty) : "(none)",
  			 audit_get_sessionid(current));
  	audit_put_tty(tty);
  	audit_log_task_context(ab); /* subj= */
  	audit_log_format(ab, " comm=");
  	audit_log_untrustedstring(ab, get_task_comm(comm, current));
  	audit_log_d_path_exe(ab, current->mm); /* exe= */
  	audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err);
  	audit_log_end(ab);
  }
3a101b8de   Richard Guy Briggs   audit: add netlin...
1561
  /* Run custom bind function on netlink socket group connect or bind requests. */
9d2161bed   Richard Guy Briggs   audit: log audit ...
1562
  static int audit_multicast_bind(struct net *net, int group)
3a101b8de   Richard Guy Briggs   audit: add netlin...
1563
  {
9d2161bed   Richard Guy Briggs   audit: log audit ...
1564
  	int err = 0;
3a101b8de   Richard Guy Briggs   audit: add netlin...
1565
  	if (!capable(CAP_AUDIT_READ))
9d2161bed   Richard Guy Briggs   audit: log audit ...
1566
1567
1568
1569
  		err = -EPERM;
  	audit_log_multicast(group, "connect", err);
  	return err;
  }
3a101b8de   Richard Guy Briggs   audit: add netlin...
1570

9d2161bed   Richard Guy Briggs   audit: log audit ...
1571
1572
1573
  static void audit_multicast_unbind(struct net *net, int group)
  {
  	audit_log_multicast(group, "disconnect", 0);
3a101b8de   Richard Guy Briggs   audit: add netlin...
1574
  }
33faba7fa   Richard Guy Briggs   audit: listen in ...
1575
  static int __net_init audit_net_init(struct net *net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
  {
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
1577
1578
  	struct netlink_kernel_cfg cfg = {
  		.input	= audit_receive,
9d2161bed   Richard Guy Briggs   audit: log audit ...
1579
1580
  		.bind	= audit_multicast_bind,
  		.unbind	= audit_multicast_unbind,
451f92163   Richard Guy Briggs   audit: add netlin...
1581
1582
  		.flags	= NL_CFG_F_NONROOT_RECV,
  		.groups	= AUDIT_NLGRP_MAX,
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
1583
  	};
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1584

33faba7fa   Richard Guy Briggs   audit: listen in ...
1585
  	struct audit_net *aunet = net_generic(net, audit_net_id);
5b52330bb   Paul Moore   audit: fix auditd...
1586
1587
  	aunet->sk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
  	if (aunet->sk == NULL) {
33faba7fa   Richard Guy Briggs   audit: listen in ...
1588
  		audit_panic("cannot initialize netlink socket in namespace");
11ee39ebf   Gao feng   audit: print erro...
1589
1590
  		return -ENOMEM;
  	}
a5f4d17da   Paul Moore   audit: improve ro...
1591
1592
  	/* limit the timeout in case auditd is blocked/stopped */
  	aunet->sk->sk_sndtimeo = HZ / 10;
5b52330bb   Paul Moore   audit: fix auditd...
1593

33faba7fa   Richard Guy Briggs   audit: listen in ...
1594
1595
1596
1597
1598
1599
  	return 0;
  }
  
  static void __net_exit audit_net_exit(struct net *net)
  {
  	struct audit_net *aunet = net_generic(net, audit_net_id);
5b52330bb   Paul Moore   audit: fix auditd...
1600

48d0e023a   Paul Moore   audit: fix the RC...
1601
1602
1603
1604
1605
  	/* NOTE: you would think that we would want to check the auditd
  	 * connection and potentially reset it here if it lives in this
  	 * namespace, but since the auditd connection tracking struct holds a
  	 * reference to this namespace (see auditd_set()) we are only ever
  	 * going to get here after that connection has been released */
33faba7fa   Richard Guy Briggs   audit: listen in ...
1606

5b52330bb   Paul Moore   audit: fix auditd...
1607
  	netlink_kernel_release(aunet->sk);
33faba7fa   Richard Guy Briggs   audit: listen in ...
1608
  }
8626877b5   Richard Guy Briggs   audit: fix locati...
1609
  static struct pernet_operations audit_net_ops __net_initdata = {
33faba7fa   Richard Guy Briggs   audit: listen in ...
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
  	.init = audit_net_init,
  	.exit = audit_net_exit,
  	.id = &audit_net_id,
  	.size = sizeof(struct audit_net),
  };
  
  /* Initialize audit support at boot time. */
  static int __init audit_init(void)
  {
  	int i;
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1620
1621
  	if (audit_initialized == AUDIT_DISABLED)
  		return 0;
8cc96382d   Paul Moore   audit: use kmem_c...
1622
1623
1624
  	audit_buffer_cache = kmem_cache_create("audit_buffer",
  					       sizeof(struct audit_buffer),
  					       0, SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625

af8b824f2   Paul Moore   audit: rename the...
1626
  	skb_queue_head_init(&audit_queue);
c6480207f   Paul Moore   audit: rework the...
1627
  	skb_queue_head_init(&audit_retry_queue);
af8b824f2   Paul Moore   audit: rename the...
1628
  	skb_queue_head_init(&audit_hold_queue);
3dc7e3153   Darrel Goeddel   [PATCH] support f...
1629

f368c07d7   Amy Griffis   [PATCH] audit: pa...
1630
1631
  	for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
  		INIT_LIST_HEAD(&audit_inode_hash[i]);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1632

ce423631c   Paul Moore   audit: track the ...
1633
1634
  	mutex_init(&audit_cmd_mutex.lock);
  	audit_cmd_mutex.owner = NULL;
5b52330bb   Paul Moore   audit: fix auditd...
1635
1636
1637
1638
1639
1640
  	pr_info("initializing netlink subsys (%s)
  ",
  		audit_default ? "enabled" : "disabled");
  	register_pernet_subsys(&audit_net_ops);
  
  	audit_initialized = AUDIT_INITIALIZED;
5b52330bb   Paul Moore   audit: fix auditd...
1641

6c9255645   Paul Moore   audit: fixup audi...
1642
1643
1644
1645
1646
1647
  	kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
  	if (IS_ERR(kauditd_task)) {
  		int err = PTR_ERR(kauditd_task);
  		panic("audit: failed to start the kauditd thread (%d)
  ", err);
  	}
7c397d01e   Steve Grubb   audit: Make AUDIT...
1648
1649
1650
  	audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL,
  		"state=initialized audit_enabled=%u res=1",
  		 audit_enabled);
6c9255645   Paul Moore   audit: fixup audi...
1651

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1652
1653
  	return 0;
  }
be4104abf   Paul Moore   audit: initialize...
1654
  postcore_initcall(audit_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1655

11dd26663   Greg Edwards   audit: do not pan...
1656
1657
1658
1659
  /*
   * Process kernel command-line parameter at boot time.
   * audit={0|off} or audit={1|on}.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1660
1661
  static int __init audit_enable(char *str)
  {
11dd26663   Greg Edwards   audit: do not pan...
1662
1663
1664
1665
1666
1667
1668
1669
1670
  	if (!strcasecmp(str, "off") || !strcmp(str, "0"))
  		audit_default = AUDIT_OFF;
  	else if (!strcasecmp(str, "on") || !strcmp(str, "1"))
  		audit_default = AUDIT_ON;
  	else {
  		pr_err("audit: invalid 'audit' parameter value (%s)
  ", str);
  		audit_default = AUDIT_ON;
  	}
80ab4df62   Paul Moore   audit: don't use ...
1671
1672
  
  	if (audit_default == AUDIT_OFF)
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1673
  		audit_initialized = AUDIT_DISABLED;
5d842a5b7   Paul Moore   audit: use audit_...
1674
  	if (audit_set_enabled(audit_default))
11dd26663   Greg Edwards   audit: do not pan...
1675
1676
1677
  		pr_err("audit: error setting audit state (%d)
  ",
  		       audit_default);
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1678

d957f7b72   Joe Perches   audit: Use more c...
1679
1680
  	pr_info("%s
  ", audit_default ?
d3ca0344b   Gao feng   audit: remove use...
1681
  		"enabled (after initialization)" : "disabled (until reboot)");
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1682

9b41046cd   OGAWA Hirofumi   [PATCH] Don't pas...
1683
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1684
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1685
  __setup("audit=", audit_enable);
f910fde73   Richard Guy Briggs   audit: add kernel...
1686
1687
1688
1689
  /* Process kernel command-line parameter at boot time.
   * audit_backlog_limit=<n> */
  static int __init audit_backlog_limit_set(char *str)
  {
3e1d0bb62   Joe Perches   audit: Convert in...
1690
  	u32 audit_backlog_limit_arg;
d957f7b72   Joe Perches   audit: Use more c...
1691

f910fde73   Richard Guy Briggs   audit: add kernel...
1692
  	pr_info("audit_backlog_limit: ");
3e1d0bb62   Joe Perches   audit: Convert in...
1693
1694
1695
  	if (kstrtouint(str, 0, &audit_backlog_limit_arg)) {
  		pr_cont("using default of %u, unable to parse %s
  ",
d957f7b72   Joe Perches   audit: Use more c...
1696
  			audit_backlog_limit, str);
f910fde73   Richard Guy Briggs   audit: add kernel...
1697
1698
  		return 1;
  	}
3e1d0bb62   Joe Perches   audit: Convert in...
1699
1700
  
  	audit_backlog_limit = audit_backlog_limit_arg;
d957f7b72   Joe Perches   audit: Use more c...
1701
1702
  	pr_cont("%d
  ", audit_backlog_limit);
f910fde73   Richard Guy Briggs   audit: add kernel...
1703
1704
1705
1706
  
  	return 1;
  }
  __setup("audit_backlog_limit=", audit_backlog_limit_set);
16e1904e6   Chris Wright   AUDIT: Add helper...
1707
1708
  static void audit_buffer_free(struct audit_buffer *ab)
  {
8fc6115c2   Chris Wright   AUDIT: expand aud...
1709
1710
  	if (!ab)
  		return;
d865e573b   Markus Elfring   audit: Delete unn...
1711
  	kfree_skb(ab->skb);
8cc96382d   Paul Moore   audit: use kmem_c...
1712
  	kmem_cache_free(audit_buffer_cache, ab);
16e1904e6   Chris Wright   AUDIT: Add helper...
1713
  }
8cc96382d   Paul Moore   audit: use kmem_c...
1714
1715
  static struct audit_buffer *audit_buffer_alloc(struct audit_context *ctx,
  					       gfp_t gfp_mask, int type)
16e1904e6   Chris Wright   AUDIT: Add helper...
1716
  {
8cc96382d   Paul Moore   audit: use kmem_c...
1717
  	struct audit_buffer *ab;
8fc6115c2   Chris Wright   AUDIT: expand aud...
1718

8cc96382d   Paul Moore   audit: use kmem_c...
1719
1720
1721
  	ab = kmem_cache_alloc(audit_buffer_cache, gfp_mask);
  	if (!ab)
  		return NULL;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1722
1723
1724
  
  	ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask);
  	if (!ab->skb)
c64e66c67   David S. Miller   audit: netlink: M...
1725
  		goto err;
8cc96382d   Paul Moore   audit: use kmem_c...
1726
1727
  	if (!nlmsg_put(ab->skb, 0, 0, type, 0, 0))
  		goto err;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1728

8cc96382d   Paul Moore   audit: use kmem_c...
1729
1730
  	ab->ctx = ctx;
  	ab->gfp_mask = gfp_mask;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1731

16e1904e6   Chris Wright   AUDIT: Add helper...
1732
  	return ab;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1733

8fc6115c2   Chris Wright   AUDIT: expand aud...
1734
1735
1736
  err:
  	audit_buffer_free(ab);
  	return NULL;
16e1904e6   Chris Wright   AUDIT: Add helper...
1737
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1739
1740
1741
1742
  /**
   * audit_serial - compute a serial number for the audit record
   *
   * Compute a serial number for the audit record.  Audit records are
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1743
1744
1745
1746
1747
1748
1749
   * written to user-space as soon as they are generated, so a complete
   * audit record may be written in several pieces.  The timestamp of the
   * record and this serial number are used by the user-space tools to
   * determine which pieces belong to the same audit record.  The
   * (timestamp,serial) tuple is unique for each syscall and is live from
   * syscall entry to syscall exit.
   *
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1750
1751
1752
1753
   * NOTE: Another possibility is to store the formatted records off the
   * audit context (for those records that have a context), and emit them
   * all at syscall exit.  However, this could delay the reporting of
   * significant errors until syscall exit (or never, if the system
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1754
1755
   * halts).
   */
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1756
1757
  unsigned int audit_serial(void)
  {
01478d7d6   Richard Guy Briggs   audit: use atomic...
1758
  	static atomic_t serial = ATOMIC_INIT(0);
d5b454f2c   David Woodhouse   AUDIT: Fix livelo...
1759

6b3211842   Yejune Deng   audit: replace at...
1760
  	return atomic_inc_return(&serial);
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1761
  }
5600b8927   Daniel Walker   whitespace fixes:...
1762
  static inline void audit_get_stamp(struct audit_context *ctx,
2115bb250   Deepa Dinamani   audit: Use timesp...
1763
  				   struct timespec64 *t, unsigned int *serial)
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1764
  {
48887e63d   Al Viro   [PATCH] fix broke...
1765
  	if (!ctx || !auditsc_get_stamp(ctx, t, serial)) {
290e44b7d   Paul Moore   audit: use ktime_...
1766
  		ktime_get_coarse_real_ts64(t);
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1767
1768
1769
  		*serial = audit_serial();
  	}
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
  /**
   * audit_log_start - obtain an audit buffer
   * @ctx: audit_context (may be NULL)
   * @gfp_mask: type of allocation
   * @type: audit message type
   *
   * Returns audit_buffer pointer on success or NULL on error.
   *
   * Obtain an audit buffer.  This routine does locking to obtain the
   * audit buffer, but then no locking is required for calls to
   * audit_log_*format.  If the task (ctx) is a task that is currently in a
   * syscall, then the syscall is marked as auditable and an audit record
   * will be written at syscall exit.  If there is no associated task, then
   * task context (ctx) should be NULL.
   */
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
1785
  struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1786
  				     int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1787
  {
319754248   Paul Moore   audit: rework aud...
1788
  	struct audit_buffer *ab;
2115bb250   Deepa Dinamani   audit: Use timesp...
1789
  	struct timespec64 t;
3f649ab72   Kees Cook   treewide: Remove ...
1790
  	unsigned int serial;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791

a3f07114e   Eric Paris   [PATCH] Audit: ma...
1792
  	if (audit_initialized != AUDIT_INITIALIZED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
  		return NULL;
d904ac032   Richard Guy Briggs   audit: rename FIL...
1794
  	if (unlikely(!audit_filter(type, AUDIT_FILTER_EXCLUDE)))
c8edc80c8   Dustin Kirkland   [PATCH] Exclude m...
1795
  		return NULL;
5b52330bb   Paul Moore   audit: fix auditd...
1796
  	/* NOTE: don't ever fail/sleep on these two conditions:
a09cfa470   Paul Moore   audit: don't ever...
1797
1798
1799
1800
  	 * 1. auditd generated record - since we need auditd to drain the
  	 *    queue; also, when we are checking for auditd, compare PIDs using
  	 *    task_tgid_vnr() since auditd_pid is set in audit_receive_msg()
  	 *    using a PID anchored in the caller's namespace
5b52330bb   Paul Moore   audit: fix auditd...
1801
  	 * 2. generator holding the audit_cmd_mutex - we don't want to block
d978295bb   Paul Moore   audit: ensure use...
1802
1803
1804
  	 *    while holding the mutex, although we do penalize the sender
  	 *    later in audit_receive() when it is safe to block
  	 */
ce423631c   Paul Moore   audit: track the ...
1805
  	if (!(auditd_test_task(current) || audit_ctl_owner_current())) {
5b52330bb   Paul Moore   audit: fix auditd...
1806
  		long stime = audit_backlog_wait_time;
319754248   Paul Moore   audit: rework aud...
1807
1808
1809
1810
1811
  
  		while (audit_backlog_limit &&
  		       (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
  			/* wake kauditd to try and flush the queue */
  			wake_up_interruptible(&kauditd_wait);
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1812

319754248   Paul Moore   audit: rework aud...
1813
1814
  			/* sleep if we are allowed and we haven't exhausted our
  			 * backlog wait limit */
5b52330bb   Paul Moore   audit: fix auditd...
1815
  			if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {
b43870c74   Max Englander   audit: report aud...
1816
  				long rtime = stime;
319754248   Paul Moore   audit: rework aud...
1817
1818
1819
1820
1821
  				DECLARE_WAITQUEUE(wait, current);
  
  				add_wait_queue_exclusive(&audit_backlog_wait,
  							 &wait);
  				set_current_state(TASK_UNINTERRUPTIBLE);
b43870c74   Max Englander   audit: report aud...
1822
1823
  				stime = schedule_timeout(rtime);
  				atomic_add(rtime - stime, &audit_backlog_wait_time_actual);
319754248   Paul Moore   audit: rework aud...
1824
1825
1826
1827
1828
1829
1830
1831
1832
  				remove_wait_queue(&audit_backlog_wait, &wait);
  			} else {
  				if (audit_rate_check() && printk_ratelimit())
  					pr_warn("audit_backlog=%d > audit_backlog_limit=%d
  ",
  						skb_queue_len(&audit_queue),
  						audit_backlog_limit);
  				audit_log_lost("backlog limit exceeded");
  				return NULL;
8ac1c8d5d   Konstantin Khlebnikov   audit: fix endles...
1833
  			}
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1834
  		}
fb19b4c6a   David Woodhouse   AUDIT: Honour aud...
1835
  	}
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1836
  	ab = audit_buffer_alloc(ctx, gfp_mask, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1837
1838
1839
1840
  	if (!ab) {
  		audit_log_lost("out of memory in audit_log_start");
  		return NULL;
  	}
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1841
  	audit_get_stamp(ab->ctx, &t, &serial);
6d915476e   Richard Guy Briggs   audit: trigger ac...
1842
1843
1844
  	/* cancel dummy context to enable supporting records */
  	if (ctx)
  		ctx->dummy = 0;
2115bb250   Deepa Dinamani   audit: Use timesp...
1845
1846
  	audit_log_format(ab, "audit(%llu.%03lu:%u): ",
  			 (unsigned long long)t.tv_sec, t.tv_nsec/1000000, serial);
319754248   Paul Moore   audit: rework aud...
1847

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1848
1849
  	return ab;
  }
8fc6115c2   Chris Wright   AUDIT: expand aud...
1850
  /**
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1851
   * audit_expand - expand skb in the audit buffer
8fc6115c2   Chris Wright   AUDIT: expand aud...
1852
   * @ab: audit_buffer
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1853
   * @extra: space to add at tail of the skb
8fc6115c2   Chris Wright   AUDIT: expand aud...
1854
1855
1856
1857
   *
   * Returns 0 (no space) on failed expansion, or available space if
   * successful.
   */
e3b926b4c   David Woodhouse   AUDIT: pass size ...
1858
  static inline int audit_expand(struct audit_buffer *ab, int extra)
8fc6115c2   Chris Wright   AUDIT: expand aud...
1859
  {
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1860
  	struct sk_buff *skb = ab->skb;
406a1d868   Herbert Xu   [AUDIT]: Increase...
1861
1862
1863
  	int oldtail = skb_tailroom(skb);
  	int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
  	int newtail = skb_tailroom(skb);
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1864
1865
  	if (ret < 0) {
  		audit_log_lost("out of memory in audit_expand");
8fc6115c2   Chris Wright   AUDIT: expand aud...
1866
  		return 0;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1867
  	}
406a1d868   Herbert Xu   [AUDIT]: Increase...
1868
1869
1870
  
  	skb->truesize += newtail - oldtail;
  	return newtail;
8fc6115c2   Chris Wright   AUDIT: expand aud...
1871
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1872

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1873
1874
  /*
   * Format an audit message into the audit buffer.  If there isn't enough
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
1876
   * room in the audit buffer, more room will be allocated and vsnprint
   * will be called a second time.  Currently, we assume that a printk
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1877
1878
   * can't format message larger than 1024 bytes, so we don't either.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1879
1880
1881
1882
  static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
  			      va_list args)
  {
  	int len, avail;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1883
  	struct sk_buff *skb;
eecb0a733   David Woodhouse   AUDIT: Fix abuse ...
1884
  	va_list args2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1885
1886
1887
  
  	if (!ab)
  		return;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1888
1889
1890
1891
  	BUG_ON(!ab->skb);
  	skb = ab->skb;
  	avail = skb_tailroom(skb);
  	if (avail == 0) {
e3b926b4c   David Woodhouse   AUDIT: pass size ...
1892
  		avail = audit_expand(ab, AUDIT_BUFSIZ);
8fc6115c2   Chris Wright   AUDIT: expand aud...
1893
1894
  		if (!avail)
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
  	}
eecb0a733   David Woodhouse   AUDIT: Fix abuse ...
1896
  	va_copy(args2, args);
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1897
  	len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1898
1899
1900
1901
  	if (len >= avail) {
  		/* The printk buffer is 1024 bytes long, so if we get
  		 * here and AUDIT_BUFSIZ is at least 1024, then we can
  		 * log everything that printk could have logged. */
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1902
1903
  		avail = audit_expand(ab,
  			max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
8fc6115c2   Chris Wright   AUDIT: expand aud...
1904
  		if (!avail)
a0e86bd42   Jesper Juhl   audit: always fol...
1905
  			goto out_va_end;
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1906
  		len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1907
  	}
168b71739   Steve Grubb   AUDIT: Clean up l...
1908
1909
  	if (len > 0)
  		skb_put(skb, len);
a0e86bd42   Jesper Juhl   audit: always fol...
1910
1911
  out_va_end:
  	va_end(args2);
8fc6115c2   Chris Wright   AUDIT: expand aud...
1912
1913
  out:
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1914
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1915
1916
1917
1918
1919
1920
1921
1922
  /**
   * audit_log_format - format a message into the audit buffer.
   * @ab: audit_buffer
   * @fmt: format string
   * @...: optional parameters matching @fmt string
   *
   * All the work is done in audit_log_vformat.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
  void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
  {
  	va_list args;
  
  	if (!ab)
  		return;
  	va_start(args, fmt);
  	audit_log_vformat(ab, fmt, args);
  	va_end(args);
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1933
  /**
196a50855   Geliang Tang   audit: update the...
1934
   * audit_log_n_hex - convert a buffer to hex and append it to the audit skb
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1935
1936
1937
1938
1939
1940
1941
1942
1943
   * @ab: the audit_buffer
   * @buf: buffer to convert to hex
   * @len: length of @buf to be converted
   *
   * No return value; failure to expand is silently ignored.
   *
   * This function will take the passed buf and convert it into a string of
   * ascii hex digits. The new string is placed onto the skb.
   */
b556f8ad5   Eric Paris   Audit: standardiz...
1944
  void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
168b71739   Steve Grubb   AUDIT: Clean up l...
1945
  		size_t len)
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1946
  {
168b71739   Steve Grubb   AUDIT: Clean up l...
1947
1948
1949
  	int i, avail, new_len;
  	unsigned char *ptr;
  	struct sk_buff *skb;
168b71739   Steve Grubb   AUDIT: Clean up l...
1950

8ef2d3040   Amy Griffis   [PATCH] sanity ch...
1951
1952
  	if (!ab)
  		return;
168b71739   Steve Grubb   AUDIT: Clean up l...
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
  	BUG_ON(!ab->skb);
  	skb = ab->skb;
  	avail = skb_tailroom(skb);
  	new_len = len<<1;
  	if (new_len >= avail) {
  		/* Round the buffer request up to the next multiple */
  		new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
  		avail = audit_expand(ab, new_len);
  		if (!avail)
  			return;
  	}
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1964

27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1965
  	ptr = skb_tail_pointer(skb);
b8dbc3241   Joe Perches   audit: Use hex_by...
1966
1967
  	for (i = 0; i < len; i++)
  		ptr = hex_byte_pack_upper(ptr, buf[i]);
168b71739   Steve Grubb   AUDIT: Clean up l...
1968
1969
  	*ptr = 0;
  	skb_put(skb, len << 1); /* new string is twice the old string */
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1970
  }
9c937dcc7   Amy Griffis   [PATCH] log more ...
1971
1972
1973
1974
  /*
   * Format a string of no more than slen characters into the audit buffer,
   * enclosed in quote marks.
   */
b556f8ad5   Eric Paris   Audit: standardiz...
1975
1976
  void audit_log_n_string(struct audit_buffer *ab, const char *string,
  			size_t slen)
9c937dcc7   Amy Griffis   [PATCH] log more ...
1977
1978
1979
1980
  {
  	int avail, new_len;
  	unsigned char *ptr;
  	struct sk_buff *skb;
8ef2d3040   Amy Griffis   [PATCH] sanity ch...
1981
1982
  	if (!ab)
  		return;
9c937dcc7   Amy Griffis   [PATCH] log more ...
1983
1984
1985
1986
1987
1988
1989
1990
1991
  	BUG_ON(!ab->skb);
  	skb = ab->skb;
  	avail = skb_tailroom(skb);
  	new_len = slen + 3;	/* enclosing quotes + null terminator */
  	if (new_len > avail) {
  		avail = audit_expand(ab, new_len);
  		if (!avail)
  			return;
  	}
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1992
  	ptr = skb_tail_pointer(skb);
9c937dcc7   Amy Griffis   [PATCH] log more ...
1993
1994
1995
1996
1997
1998
1999
  	*ptr++ = '"';
  	memcpy(ptr, string, slen);
  	ptr += slen;
  	*ptr++ = '"';
  	*ptr = 0;
  	skb_put(skb, slen + 2);	/* don't include null terminator */
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2000
  /**
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2001
   * audit_string_contains_control - does a string need to be logged in hex
f706d5d22   Dave Jones   audit: silence tw...
2002
2003
   * @string: string to be checked
   * @len: max length of the string to check
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2004
   */
9fcf836b2   Yaowei Bai   audit: audit_stri...
2005
  bool audit_string_contains_control(const char *string, size_t len)
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2006
2007
  {
  	const unsigned char *p;
b3897f567   Miloslav Trmac   Audit: fix handli...
2008
  	for (p = string; p < (const unsigned char *)string + len; p++) {
1d6c9649e   Vesa-Matti J Kari   kernel/audit.c co...
2009
  		if (*p == '"' || *p < 0x21 || *p > 0x7e)
9fcf836b2   Yaowei Bai   audit: audit_stri...
2010
  			return true;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2011
  	}
9fcf836b2   Yaowei Bai   audit: audit_stri...
2012
  	return false;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2013
2014
2015
  }
  
  /**
522ed7767   Miloslav Trmac   Audit: add TTY in...
2016
   * audit_log_n_untrustedstring - log a string that may contain random characters
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2017
   * @ab: audit_buffer
f706d5d22   Dave Jones   audit: silence tw...
2018
   * @len: length of string (not including trailing null)
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2019
2020
2021
2022
   * @string: string to be logged
   *
   * This code will escape a string that is passed to it if the string
   * contains a control character, unprintable character, double quote mark,
168b71739   Steve Grubb   AUDIT: Clean up l...
2023
   * or a space. Unescaped strings will start and end with a double quote mark.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2024
   * Strings that are escaped are printed in hex (2 digits per char).
9c937dcc7   Amy Griffis   [PATCH] log more ...
2025
2026
2027
   *
   * The caller specifies the number of characters in the string to log, which may
   * or may not be the entire string.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2028
   */
b556f8ad5   Eric Paris   Audit: standardiz...
2029
2030
  void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string,
  				 size_t len)
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
2031
  {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2032
  	if (audit_string_contains_control(string, len))
b556f8ad5   Eric Paris   Audit: standardiz...
2033
  		audit_log_n_hex(ab, string, len);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2034
  	else
b556f8ad5   Eric Paris   Audit: standardiz...
2035
  		audit_log_n_string(ab, string, len);
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
2036
  }
9c937dcc7   Amy Griffis   [PATCH] log more ...
2037
  /**
522ed7767   Miloslav Trmac   Audit: add TTY in...
2038
   * audit_log_untrustedstring - log a string that may contain random characters
9c937dcc7   Amy Griffis   [PATCH] log more ...
2039
2040
2041
   * @ab: audit_buffer
   * @string: string to be logged
   *
522ed7767   Miloslav Trmac   Audit: add TTY in...
2042
   * Same as audit_log_n_untrustedstring(), except that strlen is used to
9c937dcc7   Amy Griffis   [PATCH] log more ...
2043
2044
   * determine string length.
   */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
2045
  void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
9c937dcc7   Amy Griffis   [PATCH] log more ...
2046
  {
b556f8ad5   Eric Paris   Audit: standardiz...
2047
  	audit_log_n_untrustedstring(ab, string, strlen(string));
9c937dcc7   Amy Griffis   [PATCH] log more ...
2048
  }
168b71739   Steve Grubb   AUDIT: Clean up l...
2049
  /* This is a helper-function to print the escaped d_path */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2050
  void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
66b3fad3f   Al Viro   constify path arg...
2051
  		      const struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2052
  {
44707fdf5   Jan Blunck   d_path: Use struc...
2053
  	char *p, *pathname;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054

8fc6115c2   Chris Wright   AUDIT: expand aud...
2055
  	if (prefix)
c158a35c8   Kees Cook   audit: no leading...
2056
  		audit_log_format(ab, "%s", prefix);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2057

168b71739   Steve Grubb   AUDIT: Clean up l...
2058
  	/* We will allow 11 spaces for ' (deleted)' to be appended */
44707fdf5   Jan Blunck   d_path: Use struc...
2059
2060
  	pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
  	if (!pathname) {
f1d9b23ca   Richard Guy Briggs   audit: purge audi...
2061
  		audit_log_format(ab, "\"<no_memory>\"");
168b71739   Steve Grubb   AUDIT: Clean up l...
2062
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2063
  	}
cf28b4863   Jan Blunck   d_path: Make d_pa...
2064
  	p = d_path(path, pathname, PATH_MAX+11);
168b71739   Steve Grubb   AUDIT: Clean up l...
2065
2066
  	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
  		/* FIXME: can we save some information here? */
f1d9b23ca   Richard Guy Briggs   audit: purge audi...
2067
  		audit_log_format(ab, "\"<too_long>\"");
5600b8927   Daniel Walker   whitespace fixes:...
2068
  	} else
168b71739   Steve Grubb   AUDIT: Clean up l...
2069
  		audit_log_untrustedstring(ab, p);
44707fdf5   Jan Blunck   d_path: Use struc...
2070
  	kfree(pathname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2071
  }
4d3fb709b   Eric Paris   helper for some s...
2072
2073
  void audit_log_session_info(struct audit_buffer *ab)
  {
4440e8548   Eric Paris   audit: convert al...
2074
  	unsigned int sessionid = audit_get_sessionid(current);
4d3fb709b   Eric Paris   helper for some s...
2075
  	uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current));
a2c97da11   Richard Guy Briggs   audit: use sessio...
2076
  	audit_log_format(ab, "auid=%u ses=%u", auid, sessionid);
4d3fb709b   Eric Paris   helper for some s...
2077
  }
9d9609851   Eric Paris   Audit: clean up a...
2078
2079
2080
2081
2082
2083
2084
2085
  void audit_log_key(struct audit_buffer *ab, char *key)
  {
  	audit_log_format(ab, " key=");
  	if (key)
  		audit_log_untrustedstring(ab, key);
  	else
  		audit_log_format(ab, "(null)");
  }
b24a30a73   Eric Paris   audit: fix event ...
2086
2087
2088
2089
2090
2091
  int audit_log_task_context(struct audit_buffer *ab)
  {
  	char *ctx = NULL;
  	unsigned len;
  	int error;
  	u32 sid;
4ebd7651b   Paul Moore   lsm: separate sec...
2092
  	security_task_getsecid_subj(current, &sid);
b24a30a73   Eric Paris   audit: fix event ...
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
  	if (!sid)
  		return 0;
  
  	error = security_secid_to_secctx(sid, &ctx, &len);
  	if (error) {
  		if (error != -EINVAL)
  			goto error_path;
  		return 0;
  	}
  
  	audit_log_format(ab, " subj=%s", ctx);
  	security_release_secctx(ctx, len);
  	return 0;
  
  error_path:
  	audit_panic("error in audit_log_task_context");
  	return error;
  }
  EXPORT_SYMBOL(audit_log_task_context);
4766b199e   Davidlohr Bueso   audit: consolidat...
2112
2113
2114
  void audit_log_d_path_exe(struct audit_buffer *ab,
  			  struct mm_struct *mm)
  {
5b2825527   Davidlohr Bueso   audit: reduce mma...
2115
2116
2117
2118
  	struct file *exe_file;
  
  	if (!mm)
  		goto out_null;
4766b199e   Davidlohr Bueso   audit: consolidat...
2119

5b2825527   Davidlohr Bueso   audit: reduce mma...
2120
2121
2122
2123
2124
2125
2126
2127
2128
  	exe_file = get_mm_exe_file(mm);
  	if (!exe_file)
  		goto out_null;
  
  	audit_log_d_path(ab, " exe=", &exe_file->f_path);
  	fput(exe_file);
  	return;
  out_null:
  	audit_log_format(ab, " exe=(null)");
4766b199e   Davidlohr Bueso   audit: consolidat...
2129
  }
2a1fe215e   Paul Moore   audit: use curren...
2130
  struct tty_struct *audit_get_tty(void)
3f5be2da8   Richard Guy Briggs   audit: move audit...
2131
2132
2133
  {
  	struct tty_struct *tty = NULL;
  	unsigned long flags;
2a1fe215e   Paul Moore   audit: use curren...
2134
2135
2136
2137
  	spin_lock_irqsave(&current->sighand->siglock, flags);
  	if (current->signal)
  		tty = tty_kref_get(current->signal->tty);
  	spin_unlock_irqrestore(&current->sighand->siglock, flags);
3f5be2da8   Richard Guy Briggs   audit: move audit...
2138
2139
2140
2141
2142
2143
2144
  	return tty;
  }
  
  void audit_put_tty(struct tty_struct *tty)
  {
  	tty_kref_put(tty);
  }
2a1fe215e   Paul Moore   audit: use curren...
2145
  void audit_log_task_info(struct audit_buffer *ab)
b24a30a73   Eric Paris   audit: fix event ...
2146
2147
  {
  	const struct cred *cred;
2a1fe215e   Paul Moore   audit: use curren...
2148
  	char comm[sizeof(current->comm)];
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
2149
  	struct tty_struct *tty;
b24a30a73   Eric Paris   audit: fix event ...
2150
2151
2152
  
  	if (!ab)
  		return;
b24a30a73   Eric Paris   audit: fix event ...
2153
  	cred = current_cred();
2a1fe215e   Paul Moore   audit: use curren...
2154
  	tty = audit_get_tty();
b24a30a73   Eric Paris   audit: fix event ...
2155
  	audit_log_format(ab,
c92cdeb45   Richard Guy Briggs   audit: convert PP...
2156
  			 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
b24a30a73   Eric Paris   audit: fix event ...
2157
  			 " euid=%u suid=%u fsuid=%u"
2f2ad1013   Richard Guy Briggs   audit: restore or...
2158
  			 " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
2a1fe215e   Paul Moore   audit: use curren...
2159
2160
2161
  			 task_ppid_nr(current),
  			 task_tgid_nr(current),
  			 from_kuid(&init_user_ns, audit_get_loginuid(current)),
b24a30a73   Eric Paris   audit: fix event ...
2162
2163
2164
2165
2166
2167
2168
2169
  			 from_kuid(&init_user_ns, cred->uid),
  			 from_kgid(&init_user_ns, cred->gid),
  			 from_kuid(&init_user_ns, cred->euid),
  			 from_kuid(&init_user_ns, cred->suid),
  			 from_kuid(&init_user_ns, cred->fsuid),
  			 from_kgid(&init_user_ns, cred->egid),
  			 from_kgid(&init_user_ns, cred->sgid),
  			 from_kgid(&init_user_ns, cred->fsgid),
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
2170
  			 tty ? tty_name(tty) : "(none)",
2a1fe215e   Paul Moore   audit: use curren...
2171
  			 audit_get_sessionid(current));
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
2172
  	audit_put_tty(tty);
b24a30a73   Eric Paris   audit: fix event ...
2173
  	audit_log_format(ab, " comm=");
2a1fe215e   Paul Moore   audit: use curren...
2174
2175
  	audit_log_untrustedstring(ab, get_task_comm(comm, current));
  	audit_log_d_path_exe(ab, current->mm);
b24a30a73   Eric Paris   audit: fix event ...
2176
2177
2178
  	audit_log_task_context(ab);
  }
  EXPORT_SYMBOL(audit_log_task_info);
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2179
  /**
245d73698   Kees Cook   audit: Report sus...
2180
2181
2182
   * audit_log_path_denied - report a path restriction denial
   * @type: audit message type (AUDIT_ANOM_LINK, AUDIT_ANOM_CREAT, etc)
   * @operation: specific operation name
a51d9eaa4   Kees Cook   fs: add link rest...
2183
   */
245d73698   Kees Cook   audit: Report sus...
2184
  void audit_log_path_denied(int type, const char *operation)
a51d9eaa4   Kees Cook   fs: add link rest...
2185
2186
  {
  	struct audit_buffer *ab;
b24a30a73   Eric Paris   audit: fix event ...
2187

15564ff0a   Richard Guy Briggs   audit: make ANOM_...
2188
  	if (!audit_enabled || audit_dummy_context())
b24a30a73   Eric Paris   audit: fix event ...
2189
  		return;
a51d9eaa4   Kees Cook   fs: add link rest...
2190

245d73698   Kees Cook   audit: Report sus...
2191
2192
  	/* Generate log with subject, operation, outcome. */
  	ab = audit_log_start(audit_context(), GFP_KERNEL, type);
d1c7d97ad   Sasha Levin   fs: handle failed...
2193
  	if (!ab)
45b578fe4   Richard Guy Briggs   audit: link denie...
2194
  		return;
b24a30a73   Eric Paris   audit: fix event ...
2195
  	audit_log_format(ab, "op=%s", operation);
2a1fe215e   Paul Moore   audit: use curren...
2196
  	audit_log_task_info(ab);
b24a30a73   Eric Paris   audit: fix event ...
2197
  	audit_log_format(ab, " res=0");
a51d9eaa4   Kees Cook   fs: add link rest...
2198
2199
  	audit_log_end(ab);
  }
4b7d248b3   Richard Guy Briggs   audit: move login...
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
  /* global counter which is incremented every time something logs in */
  static atomic_t session_id = ATOMIC_INIT(0);
  
  static int audit_set_loginuid_perm(kuid_t loginuid)
  {
  	/* if we are unset, we don't need privs */
  	if (!audit_loginuid_set(current))
  		return 0;
  	/* if AUDIT_FEATURE_LOGINUID_IMMUTABLE means never ever allow a change*/
  	if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
  		return -EPERM;
  	/* it is set, you need permission */
  	if (!capable(CAP_AUDIT_CONTROL))
  		return -EPERM;
  	/* reject if this is not an unset and we don't allow that */
  	if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID)
  				 && uid_valid(loginuid))
  		return -EPERM;
  	return 0;
  }
  
  static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
  				   unsigned int oldsessionid,
  				   unsigned int sessionid, int rc)
  {
  	struct audit_buffer *ab;
  	uid_t uid, oldloginuid, loginuid;
  	struct tty_struct *tty;
  
  	if (!audit_enabled)
  		return;
73e65b88f   Richard Guy Briggs   audit: connect LO...
2231
  	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN);
4b7d248b3   Richard Guy Briggs   audit: move login...
2232
2233
2234
2235
2236
  	if (!ab)
  		return;
  
  	uid = from_kuid(&init_user_ns, task_uid(current));
  	oldloginuid = from_kuid(&init_user_ns, koldloginuid);
a1b861faa   Zheng Yongjun   kernel/audit: con...
2237
  	loginuid = from_kuid(&init_user_ns, kloginuid);
4b7d248b3   Richard Guy Briggs   audit: move login...
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
  	tty = audit_get_tty();
  
  	audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
  	audit_log_task_context(ab);
  	audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
  			 oldloginuid, loginuid, tty ? tty_name(tty) : "(none)",
  			 oldsessionid, sessionid, !rc);
  	audit_put_tty(tty);
  	audit_log_end(ab);
  }
  
  /**
   * audit_set_loginuid - set current task's loginuid
   * @loginuid: loginuid value
   *
   * Returns 0.
   *
   * Called (set) from fs/proc/base.c::proc_loginuid_write().
   */
  int audit_set_loginuid(kuid_t loginuid)
  {
  	unsigned int oldsessionid, sessionid = AUDIT_SID_UNSET;
  	kuid_t oldloginuid;
  	int rc;
  
  	oldloginuid = audit_get_loginuid(current);
  	oldsessionid = audit_get_sessionid(current);
  
  	rc = audit_set_loginuid_perm(loginuid);
  	if (rc)
  		goto out;
  
  	/* are we setting or clearing? */
  	if (uid_valid(loginuid)) {
  		sessionid = (unsigned int)atomic_inc_return(&session_id);
  		if (unlikely(sessionid == AUDIT_SID_UNSET))
  			sessionid = (unsigned int)atomic_inc_return(&session_id);
  	}
  
  	current->sessionid = sessionid;
  	current->loginuid = loginuid;
  out:
  	audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc);
  	return rc;
  }
a51d9eaa4   Kees Cook   fs: add link rest...
2283
  /**
b48345aaf   Richard Guy Briggs   audit: deliver si...
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
   * audit_signal_info - record signal info for shutting down audit subsystem
   * @sig: signal value
   * @t: task being signaled
   *
   * If the audit subsystem is being terminated, record the task (pid)
   * and uid that is doing that.
   */
  int audit_signal_info(int sig, struct task_struct *t)
  {
  	kuid_t uid = current_uid(), auid;
  
  	if (auditd_test_task(t) &&
  	    (sig == SIGTERM || sig == SIGHUP ||
  	     sig == SIGUSR1 || sig == SIGUSR2)) {
  		audit_sig_pid = task_tgid_nr(current);
  		auid = audit_get_loginuid(current);
  		if (uid_valid(auid))
  			audit_sig_uid = auid;
  		else
  			audit_sig_uid = uid;
4ebd7651b   Paul Moore   lsm: separate sec...
2304
  		security_task_getsecid_subj(current, &audit_sig_sid);
b48345aaf   Richard Guy Briggs   audit: deliver si...
2305
2306
2307
2308
2309
2310
  	}
  
  	return audit_signal_info_syscall(t);
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2311
2312
2313
   * audit_log_end - end one audit record
   * @ab: the audit_buffer
   *
4aa83872d   Paul Moore   audit: queue netl...
2314
2315
   * We can not do a netlink send inside an irq context because it blocks (last
   * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
c1de44631   Davidlohr Bueso   audit: Remove lef...
2316
   * queue and a kthread is scheduled to remove them from the queue outside the
4aa83872d   Paul Moore   audit: queue netl...
2317
   * irq context.  May be called in any context.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2318
   */
b7d112581   David Woodhouse   AUDIT: Send netli...
2319
  void audit_log_end(struct audit_buffer *ab)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2320
  {
5b52330bb   Paul Moore   audit: fix auditd...
2321
2322
  	struct sk_buff *skb;
  	struct nlmsghdr *nlh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2323
2324
  	if (!ab)
  		return;
5b52330bb   Paul Moore   audit: fix auditd...
2325
2326
2327
  
  	if (audit_rate_check()) {
  		skb = ab->skb;
f3d357b09   Eric Paris   Audit: save audit...
2328
  		ab->skb = NULL;
5b52330bb   Paul Moore   audit: fix auditd...
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  
  		/* setup the netlink header, see the comments in
  		 * kauditd_send_multicast_skb() for length quirks */
  		nlh = nlmsg_hdr(skb);
  		nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
  
  		/* queue the netlink packet and poke the kauditd thread */
  		skb_queue_tail(&audit_queue, skb);
  		wake_up_interruptible(&kauditd_wait);
  	} else
  		audit_log_lost("rate limit exceeded");
16e1904e6   Chris Wright   AUDIT: Add helper...
2340
  	audit_buffer_free(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2341
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
  /**
   * audit_log - Log an audit record
   * @ctx: audit context
   * @gfp_mask: type of allocation
   * @type: audit message type
   * @fmt: format string to use
   * @...: variable parameters matching the format string
   *
   * This is a convenience function that calls audit_log_start,
   * audit_log_vformat, and audit_log_end.  It may be called
   * in any context.
   */
5600b8927   Daniel Walker   whitespace fixes:...
2354
  void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
2355
  	       const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2356
2357
2358
  {
  	struct audit_buffer *ab;
  	va_list args;
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
2359
  	ab = audit_log_start(ctx, gfp_mask, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2360
2361
2362
2363
2364
2365
2366
  	if (ab) {
  		va_start(args, fmt);
  		audit_log_vformat(ab, fmt, args);
  		va_end(args);
  		audit_log_end(ab);
  	}
  }
bf45da97a   lorenzo@gnu.org   [PATCH] EXPORT_SY...
2367
2368
2369
2370
2371
  
  EXPORT_SYMBOL(audit_log_start);
  EXPORT_SYMBOL(audit_log_end);
  EXPORT_SYMBOL(audit_log_format);
  EXPORT_SYMBOL(audit_log);