Blame view

kernel/audit.c 62.2 KB
85c8721ff   David Woodhouse   audit: update poi...
1
  /* audit.c -- Auditing support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
   * 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...
5
   * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Written by Rickard E. (Rik) Faith <faith@redhat.com>
   *
d7a96f3a1   Ahmed S. Darwish   Audit: internally...
24
   * Goals: 1) Integrate fully with Security Modules.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   *	  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.
   *
85c8721ff   David Woodhouse   audit: update poi...
41
   * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
   */
d957f7b72   Joe Perches   audit: Use more c...
43
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5b2825527   Davidlohr Bueso   audit: reduce mma...
44
  #include <linux/file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  #include <linux/init.h>
7153e4027   Paul McQuade   ipc, kernel: use ...
46
  #include <linux/types.h>
60063497a   Arun Sharma   atomic: use <linu...
47
  #include <linux/atomic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
49
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
50
  #include <linux/slab.h>
b7d112581   David Woodhouse   AUDIT: Send netli...
51
52
  #include <linux/err.h>
  #include <linux/kthread.h>
46e959ea2   Richard Guy Briggs   audit: add an opt...
53
  #include <linux/kernel.h>
b24a30a73   Eric Paris   audit: fix event ...
54
  #include <linux/syscalls.h>
5b52330bb   Paul Moore   audit: fix auditd...
55
56
57
58
  #include <linux/spinlock.h>
  #include <linux/rcupdate.h>
  #include <linux/mutex.h>
  #include <linux/gfp.h>
b6c7c115c   Paul Moore   audit: store the ...
59
  #include <linux/pid.h>
8cc96382d   Paul Moore   audit: use kmem_c...
60
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
  
  #include <linux/audit.h>
  
  #include <net/sock.h>
93315ed6d   Amy Griffis   [PATCH] audit str...
65
  #include <net/netlink.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
  #include <linux/skbuff.h>
131ad62d8   Mr Dash Four   netfilter: add SE...
67
68
69
  #ifdef CONFIG_SECURITY
  #include <linux/security.h>
  #endif
7dfb71030   Nigel Cunningham   [PATCH] Add inclu...
70
  #include <linux/freezer.h>
34e36d8ec   Eric W. Biederman   audit: Limit audi...
71
  #include <linux/pid_namespace.h>
33faba7fa   Richard Guy Briggs   audit: listen in ...
72
  #include <net/netns/generic.h>
3dc7e3153   Darrel Goeddel   [PATCH] support f...
73
74
  
  #include "audit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

a3f07114e   Eric Paris   [PATCH] Audit: ma...
76
  /* No auditing will take place until audit_initialized == AUDIT_INITIALIZED.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
   * (Initialization happens after skb_init is called.) */
a3f07114e   Eric Paris   [PATCH] Audit: ma...
78
79
80
  #define AUDIT_DISABLED		-1
  #define AUDIT_UNINITIALIZED	0
  #define AUDIT_INITIALIZED	1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  static int	audit_initialized;
1a6b9f231   Eric Paris   [AUDIT] make audi...
82
83
84
  #define AUDIT_OFF	0
  #define AUDIT_ON	1
  #define AUDIT_LOCKED	2
0ad0bb601   Paul Moore   audit: ensure tha...
85
86
  u32		audit_enabled = AUDIT_OFF;
  u32		audit_ever_enabled = !!AUDIT_OFF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87

ae9d67aff   Jan Engelhardt   audit: export sym...
88
  EXPORT_SYMBOL_GPL(audit_enabled);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  /* Default state when kernel boots without any parameters. */
0ad0bb601   Paul Moore   audit: ensure tha...
90
  static u32	audit_default = AUDIT_OFF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
  
  /* If auditing cannot proceed, audit_failure selects what happens. */
3e1d0bb62   Joe Perches   audit: Convert in...
93
  static u32	audit_failure = AUDIT_FAIL_PRINTK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94

5b52330bb   Paul Moore   audit: fix auditd...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  /* 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...
111
   * @rcu: RCU head
5b52330bb   Paul Moore   audit: fix auditd...
112
113
114
   *
   * Description:
   * This struct is RCU protected; you must either hold the RCU lock for reading
48d0e023a   Paul Moore   audit: fix the RC...
115
   * or the associated spinlock for writing.
75c0371a2   Pavel Emelyanov   audit: netlink so...
116
   */
5b52330bb   Paul Moore   audit: fix auditd...
117
  static struct auditd_connection {
b6c7c115c   Paul Moore   audit: store the ...
118
  	struct pid *pid;
5b52330bb   Paul Moore   audit: fix auditd...
119
120
  	u32 portid;
  	struct net *net;
48d0e023a   Paul Moore   audit: fix the RC...
121
122
123
  	struct rcu_head rcu;
  } *auditd_conn = NULL;
  static DEFINE_SPINLOCK(auditd_conn_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

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

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

c2f0c7c35   Steve Grubb   The attached patc...
136
  /* The identity of the user shutting down the audit system. */
cca080d9b   Eric W. Biederman   userns: Convert a...
137
  kuid_t		audit_sig_uid = INVALID_UID;
c2f0c7c35   Steve Grubb   The attached patc...
138
  pid_t		audit_sig_pid = -1;
e1396065e   Al Viro   [PATCH] collect s...
139
  u32		audit_sig_sid = 0;
c2f0c7c35   Steve Grubb   The attached patc...
140

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
145
146
147
  /* 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...
148
  static atomic_t	audit_lost = ATOMIC_INIT(0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149

f368c07d7   Amy Griffis   [PATCH] audit: pa...
150
151
  /* Hash for inode-based rules */
  struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
8cc96382d   Paul Moore   audit: use kmem_c...
152
  static struct kmem_cache *audit_buffer_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153

c6480207f   Paul Moore   audit: rework the...
154
  /* queue msgs to send via kauditd_task */
af8b824f2   Paul Moore   audit: rename the...
155
  static struct sk_buff_head audit_queue;
c6480207f   Paul Moore   audit: rework the...
156
157
158
  /* 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...
159
  static struct sk_buff_head audit_hold_queue;
c6480207f   Paul Moore   audit: rework the...
160
161
  
  /* queue servicing thread */
b7d112581   David Woodhouse   AUDIT: Send netli...
162
163
  static struct task_struct *kauditd_task;
  static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
c6480207f   Paul Moore   audit: rework the...
164
165
  
  /* waitqueue for callers who are blocked on the audit backlog */
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
166
  static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

b0fed4021   Eric Paris   audit: implement ...
168
169
170
171
  static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
  				   .mask = -1,
  				   .features = 0,
  				   .lock = 0,};
21b85c31d   Eric Paris   audit: audit feat...
172
  static char *audit_feature_names[2] = {
d040e5af3   Eric Paris   audit: audit feat...
173
  	"only_unset_loginuid",
21b85c31d   Eric Paris   audit: audit feat...
174
  	"loginuid_immutable",
b0fed4021   Eric Paris   audit: implement ...
175
  };
f368c07d7   Amy Griffis   [PATCH] audit: pa...
176
  /* Serialize requests from userspace. */
916d75761   Al Viro   Fix rule eviction...
177
  DEFINE_MUTEX(audit_cmd_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
182
  
  /* 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
183
184
185
186
187
188
  /* 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...
189
  	struct sk_buff       *skb;	/* formatted skb ready to send */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  	struct audit_context *ctx;	/* NULL or associated context */
9796fdd82   Al Viro   [PATCH] gfp_t: ke...
191
  	gfp_t		     gfp_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  };
f09ac9db2   Eric Paris   Audit: stop deadl...
193
  struct audit_reply {
f9441639e   Richard Guy Briggs   audit: fix netlin...
194
  	__u32 portid;
638a0fd2a   Eric W. Biederman   audit: Use struct...
195
  	struct net *net;
f09ac9db2   Eric Paris   Audit: stop deadl...
196
197
  	struct sk_buff *skb;
  };
5b52330bb   Paul Moore   audit: fix auditd...
198
199
200
201
202
203
204
  /**
   * 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 ...
205
  int auditd_test_task(struct task_struct *task)
5b52330bb   Paul Moore   audit: fix auditd...
206
207
  {
  	int rc;
48d0e023a   Paul Moore   audit: fix the RC...
208
  	struct auditd_connection *ac;
5b52330bb   Paul Moore   audit: fix auditd...
209
210
  
  	rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
211
212
  	ac = rcu_dereference(auditd_conn);
  	rc = (ac && ac->pid == task_tgid(task) ? 1 : 0);
5b52330bb   Paul Moore   audit: fix auditd...
213
214
215
216
217
218
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
b6c7c115c   Paul Moore   audit: store the ...
219
   * auditd_pid_vnr - Return the auditd PID relative to the namespace
b6c7c115c   Paul Moore   audit: store the ...
220
221
   *
   * Description:
48d0e023a   Paul Moore   audit: fix the RC...
222
   * Returns the PID in relation to the namespace, 0 on failure.
b6c7c115c   Paul Moore   audit: store the ...
223
   */
48d0e023a   Paul Moore   audit: fix the RC...
224
  static pid_t auditd_pid_vnr(void)
b6c7c115c   Paul Moore   audit: store the ...
225
226
  {
  	pid_t pid;
48d0e023a   Paul Moore   audit: fix the RC...
227
  	const struct auditd_connection *ac;
b6c7c115c   Paul Moore   audit: store the ...
228
229
  
  	rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
230
231
  	ac = rcu_dereference(auditd_conn);
  	if (!ac || !ac->pid)
b6c7c115c   Paul Moore   audit: store the ...
232
233
  		pid = 0;
  	else
48d0e023a   Paul Moore   audit: fix the RC...
234
  		pid = pid_vnr(ac->pid);
b6c7c115c   Paul Moore   audit: store the ...
235
236
237
238
239
240
  	rcu_read_unlock();
  
  	return pid;
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
   * 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...
258
  void audit_panic(const char *message)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  {
d957f7b72   Joe Perches   audit: Use more c...
260
  	switch (audit_failure) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
  	case AUDIT_FAIL_SILENT:
  		break;
  	case AUDIT_FAIL_PRINTK:
320f1b1ed   Eric Paris   [AUDIT] ratelimit...
264
  		if (printk_ratelimit())
d957f7b72   Joe Perches   audit: Use more c...
265
266
  			pr_err("%s
  ", message);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
  		break;
  	case AUDIT_FAIL_PANIC:
5b52330bb   Paul Moore   audit: fix auditd...
269
270
  		panic("audit: %s
  ", message);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  		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...
303
304
305
306
307
308
309
310
  /**
   * 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
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  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...
334
  		if (printk_ratelimit())
3e1d0bb62   Joe Perches   audit: Convert in...
335
336
  			pr_warn("audit_lost=%u audit_rate_limit=%u audit_backlog_limit=%u
  ",
320f1b1ed   Eric Paris   [AUDIT] ratelimit...
337
338
339
  				atomic_read(&audit_lost),
  				audit_rate_limit,
  				audit_backlog_limit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
  		audit_panic(message);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
  }
3e1d0bb62   Joe Perches   audit: Convert in...
343
  static int audit_log_config_change(char *function_name, u32 new, u32 old,
2532386f4   Eric Paris   Audit: collect se...
344
  				   int allow_changes)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  {
1a6b9f231   Eric Paris   [AUDIT] make audi...
346
347
  	struct audit_buffer *ab;
  	int rc = 0;
ce29b682e   Steve Grubb   [PATCH] More user...
348

1a6b9f231   Eric Paris   [AUDIT] make audi...
349
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
0644ec0cc   Kees Cook   audit: catch poss...
350
351
  	if (unlikely(!ab))
  		return rc;
3e1d0bb62   Joe Perches   audit: Convert in...
352
  	audit_log_format(ab, "%s=%u old=%u", function_name, new, old);
4d3fb709b   Eric Paris   helper for some s...
353
  	audit_log_session_info(ab);
b122c3767   Eric Paris   audit: use a cons...
354
355
356
  	rc = audit_log_task_context(ab);
  	if (rc)
  		allow_changes = 0; /* Something weird, deny request */
1a6b9f231   Eric Paris   [AUDIT] make audi...
357
358
  	audit_log_format(ab, " res=%d", allow_changes);
  	audit_log_end(ab);
6a01b07fa   Steve Grubb   [PATCH] audit con...
359
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  }
3e1d0bb62   Joe Perches   audit: Convert in...
361
  static int audit_do_config_change(char *function_name, u32 *to_change, u32 new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  {
3e1d0bb62   Joe Perches   audit: Convert in...
363
364
  	int allow_changes, rc = 0;
  	u32 old = *to_change;
6a01b07fa   Steve Grubb   [PATCH] audit con...
365
366
  
  	/* check if we are locked */
1a6b9f231   Eric Paris   [AUDIT] make audi...
367
368
  	if (audit_enabled == AUDIT_LOCKED)
  		allow_changes = 0;
6a01b07fa   Steve Grubb   [PATCH] audit con...
369
  	else
1a6b9f231   Eric Paris   [AUDIT] make audi...
370
  		allow_changes = 1;
ce29b682e   Steve Grubb   [PATCH] More user...
371

1a6b9f231   Eric Paris   [AUDIT] make audi...
372
  	if (audit_enabled != AUDIT_OFF) {
dc9eb698f   Eric Paris   audit: stop pushi...
373
  		rc = audit_log_config_change(function_name, new, old, allow_changes);
1a6b9f231   Eric Paris   [AUDIT] make audi...
374
375
  		if (rc)
  			allow_changes = 0;
6a01b07fa   Steve Grubb   [PATCH] audit con...
376
  	}
6a01b07fa   Steve Grubb   [PATCH] audit con...
377
378
  
  	/* If we are allowed, make the change */
1a6b9f231   Eric Paris   [AUDIT] make audi...
379
380
  	if (allow_changes == 1)
  		*to_change = new;
6a01b07fa   Steve Grubb   [PATCH] audit con...
381
382
383
384
  	/* Not allowed, update reason */
  	else if (rc == 0)
  		rc = -EPERM;
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  }
3e1d0bb62   Joe Perches   audit: Convert in...
386
  static int audit_set_rate_limit(u32 limit)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
  {
dc9eb698f   Eric Paris   audit: stop pushi...
388
  	return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit);
1a6b9f231   Eric Paris   [AUDIT] make audi...
389
  }
ce29b682e   Steve Grubb   [PATCH] More user...
390

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

3e1d0bb62   Joe Perches   audit: Convert in...
396
  static int audit_set_backlog_wait_time(u32 timeout)
51cc83f02   Richard Guy Briggs   audit: add audit_...
397
398
  {
  	return audit_do_config_change("audit_backlog_wait_time",
319754248   Paul Moore   audit: rework aud...
399
  				      &audit_backlog_wait_time, timeout);
51cc83f02   Richard Guy Briggs   audit: add audit_...
400
  }
3e1d0bb62   Joe Perches   audit: Convert in...
401
  static int audit_set_enabled(u32 state)
1a6b9f231   Eric Paris   [AUDIT] make audi...
402
  {
b593d384e   Eric Paris   [AUDIT] create co...
403
  	int rc;
724e7bfcc   Pranith Kumar   audit: Remove con...
404
  	if (state > AUDIT_LOCKED)
1a6b9f231   Eric Paris   [AUDIT] make audi...
405
  		return -EINVAL;
6a01b07fa   Steve Grubb   [PATCH] audit con...
406

dc9eb698f   Eric Paris   audit: stop pushi...
407
  	rc =  audit_do_config_change("audit_enabled", &audit_enabled, state);
b593d384e   Eric Paris   [AUDIT] create co...
408
409
410
411
  	if (!rc)
  		audit_ever_enabled |= !!state;
  
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
  }
3e1d0bb62   Joe Perches   audit: Convert in...
413
  static int audit_set_failure(u32 state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
416
417
418
  	if (state != AUDIT_FAIL_SILENT
  	    && state != AUDIT_FAIL_PRINTK
  	    && state != AUDIT_FAIL_PANIC)
  		return -EINVAL;
ce29b682e   Steve Grubb   [PATCH] More user...
419

dc9eb698f   Eric Paris   audit: stop pushi...
420
  	return audit_do_config_change("audit_failure", &audit_failure, state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  }
5b52330bb   Paul Moore   audit: fix auditd...
422
  /**
48d0e023a   Paul Moore   audit: fix the RC...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
   * 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.
   */
   static void auditd_conn_free(struct rcu_head *rcu)
   {
  	struct auditd_connection *ac;
  
  	ac = container_of(rcu, struct auditd_connection, rcu);
  	put_pid(ac->pid);
  	put_net(ac->net);
  	kfree(ac);
   }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
441
442
443
444
445
446
447
   * 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...
448
   * necessary.  Returns zero on success, negative values on failure.
5b52330bb   Paul Moore   audit: fix auditd...
449
   */
48d0e023a   Paul Moore   audit: fix the RC...
450
  static int auditd_set(struct pid *pid, u32 portid, struct net *net)
5b52330bb   Paul Moore   audit: fix auditd...
451
452
  {
  	unsigned long flags;
48d0e023a   Paul Moore   audit: fix the RC...
453
  	struct auditd_connection *ac_old, *ac_new;
5b52330bb   Paul Moore   audit: fix auditd...
454

48d0e023a   Paul Moore   audit: fix the RC...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  	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...
475
476
477
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
478
479
480
481
482
   * kauditd_print_skb - Print the audit record to the ring buffer
   * @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 ...
483
   */
af8b824f2   Paul Moore   audit: rename the...
484
  static void kauditd_printk_skb(struct sk_buff *skb)
038cbcf65   Eric Paris   Audit: unify the ...
485
486
  {
  	struct nlmsghdr *nlh = nlmsg_hdr(skb);
c64e66c67   David S. Miller   audit: netlink: M...
487
  	char *data = nlmsg_data(nlh);
038cbcf65   Eric Paris   Audit: unify the ...
488

5b52330bb   Paul Moore   audit: fix auditd...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
  	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
   *
   * Description:
   * This should only be used by the kauditd_thread when it fails to flush the
   * hold queue.
   */
  static void kauditd_rehold_skb(struct sk_buff *skb)
  {
  	/* put the record back in the queue at the same place */
  	skb_queue_head(&audit_hold_queue, skb);
c6480207f   Paul Moore   audit: rework the...
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
  }
  
  /**
   * kauditd_hold_skb - Queue an audit record, waiting for auditd
   * @skb: audit record
   *
   * 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.
   */
  static void kauditd_hold_skb(struct sk_buff *skb)
  {
  	/* 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? */
  	if (!audit_default) {
  		kfree_skb(skb);
  		return;
  	}
  
  	/* if we have room, queue the message */
  	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 ...
538

c6480207f   Paul Moore   audit: rework the...
539
540
541
  	/* we have no other options - drop the message */
  	audit_log_lost("kauditd hold queue overflow");
  	kfree_skb(skb);
038cbcf65   Eric Paris   Audit: unify the ...
542
  }
c6480207f   Paul Moore   audit: rework the...
543
544
545
546
547
548
549
550
551
552
  /**
   * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
   * @skb: audit record
   *
   * 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.
   */
  static void kauditd_retry_skb(struct sk_buff *skb)
f3d357b09   Eric Paris   Audit: save audit...
553
  {
c6480207f   Paul Moore   audit: rework the...
554
555
556
557
558
  	/* NOTE: because records should only live in the retry queue for a
  	 * short period of time, before either being sent or moved to the hold
  	 * queue, we don't currently enforce a limit on this queue */
  	skb_queue_tail(&audit_retry_queue, skb);
  }
32a1dbaec   Richard Guy Briggs   audit: try harder...
559

c6480207f   Paul Moore   audit: rework the...
560
  /**
264d50963   Paul Moore   audit: make sure ...
561
   * auditd_reset - Disconnect the auditd connection
c81be52a3   Paul Moore   audit: fix a race...
562
   * @ac: auditd connection state
264d50963   Paul Moore   audit: make sure ...
563
564
565
   *
   * Description:
   * Break the auditd/kauditd connection and move all the queued records into the
c81be52a3   Paul Moore   audit: fix a race...
566
567
568
569
   * 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 ...
570
   */
c81be52a3   Paul Moore   audit: fix a race...
571
  static void auditd_reset(const struct auditd_connection *ac)
264d50963   Paul Moore   audit: make sure ...
572
  {
48d0e023a   Paul Moore   audit: fix the RC...
573
  	unsigned long flags;
264d50963   Paul Moore   audit: make sure ...
574
  	struct sk_buff *skb;
48d0e023a   Paul Moore   audit: fix the RC...
575
  	struct auditd_connection *ac_old;
264d50963   Paul Moore   audit: make sure ...
576
577
  
  	/* if it isn't already broken, break the connection */
48d0e023a   Paul Moore   audit: fix the RC...
578
579
580
  	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...
581
582
583
584
585
  	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...
586
587
588
589
590
  	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 ...
591

cd33f5f2c   Paul Moore   audit: make sure ...
592
593
  	/* 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 ...
594
595
  	while ((skb = skb_dequeue(&audit_retry_queue)))
  		kauditd_hold_skb(skb);
264d50963   Paul Moore   audit: make sure ...
596
597
598
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
599
600
   * auditd_send_unicast_skb - Send a record via unicast to auditd
   * @skb: audit record
c6480207f   Paul Moore   audit: rework the...
601
602
   *
   * Description:
5b52330bb   Paul Moore   audit: fix auditd...
603
604
605
606
607
   * 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...
608
   */
5b52330bb   Paul Moore   audit: fix auditd...
609
  static int auditd_send_unicast_skb(struct sk_buff *skb)
c6480207f   Paul Moore   audit: rework the...
610
  {
5b52330bb   Paul Moore   audit: fix auditd...
611
612
613
614
  	int rc;
  	u32 portid;
  	struct net *net;
  	struct sock *sk;
48d0e023a   Paul Moore   audit: fix the RC...
615
  	struct auditd_connection *ac;
5b52330bb   Paul Moore   audit: fix auditd...
616
617
618
619
620
621
622
623
624
  
  	/* 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...
625
626
  	ac = rcu_dereference(auditd_conn);
  	if (!ac) {
5b52330bb   Paul Moore   audit: fix auditd...
627
  		rcu_read_unlock();
b0659ae5e   Shu Wang   audit: fix memlea...
628
  		kfree_skb(skb);
5b52330bb   Paul Moore   audit: fix auditd...
629
630
  		rc = -ECONNREFUSED;
  		goto err;
533c7b69c   Richard Guy Briggs   audit: use proper...
631
  	}
48d0e023a   Paul Moore   audit: fix the RC...
632
  	net = get_net(ac->net);
5b52330bb   Paul Moore   audit: fix auditd...
633
  	sk = audit_get_sk(net);
48d0e023a   Paul Moore   audit: fix the RC...
634
  	portid = ac->portid;
5b52330bb   Paul Moore   audit: fix auditd...
635
  	rcu_read_unlock();
c6480207f   Paul Moore   audit: rework the...
636

5b52330bb   Paul Moore   audit: fix auditd...
637
638
639
640
641
642
643
644
  	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...
645
646
  	if (ac && rc == -ECONNREFUSED)
  		auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
647
  	return rc;
c6480207f   Paul Moore   audit: rework the...
648
649
650
  }
  
  /**
5b52330bb   Paul Moore   audit: fix auditd...
651
652
653
654
655
656
657
658
659
660
661
662
663
   * 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...
664
   */
5b52330bb   Paul Moore   audit: fix auditd...
665
666
667
668
669
  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),
  			      void (*err_hook)(struct sk_buff *skb))
c6480207f   Paul Moore   audit: rework the...
670
  {
5b52330bb   Paul Moore   audit: fix auditd...
671
672
673
  	int rc = 0;
  	struct sk_buff *skb;
  	static unsigned int failed = 0;
32a1dbaec   Richard Guy Briggs   audit: try harder...
674

5b52330bb   Paul Moore   audit: fix auditd...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  	/* NOTE: kauditd_thread takes care of all our locking, we just use
  	 *       the netlink info passed to us (e.g. sk and portid) */
  
  	while ((skb = skb_dequeue(queue))) {
  		/* 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)
  				(*err_hook)(skb);
  			continue;
  		}
6c54e7899   Paul Moore   audit: handle a c...
689

5b52330bb   Paul Moore   audit: fix auditd...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
  		/* grab an extra skb reference in case of error */
  		skb_get(skb);
  		rc = netlink_unicast(sk, skb, portid, 0);
  		if (rc < 0) {
  			/* fatal failure for our queue flush attempt? */
  			if (++failed >= retry_limit ||
  			    rc == -ECONNREFUSED || rc == -EPERM) {
  				/* yes - error processing for the queue */
  				sk = NULL;
  				if (err_hook)
  					(*err_hook)(skb);
  				if (!skb_hook)
  					goto out;
  				/* keep processing with the skb_hook */
  				continue;
  			} else
  				/* no - requeue to preserve ordering */
  				skb_queue_head(queue, skb);
  		} else {
  			/* it worked - drop the extra reference and continue */
  			consume_skb(skb);
  			failed = 0;
  		}
c6480207f   Paul Moore   audit: rework the...
713
  	}
5b52330bb   Paul Moore   audit: fix auditd...
714
715
  out:
  	return (rc >= 0 ? 0 : rc);
f3d357b09   Eric Paris   Audit: save audit...
716
  }
b551d1d98   Richard Guy Briggs   audit: refactor h...
717
  /*
c6480207f   Paul Moore   audit: rework the...
718
719
   * kauditd_send_multicast_skb - Send a record to any multicast listeners
   * @skb: audit record
451f92163   Richard Guy Briggs   audit: add netlin...
720
   *
c6480207f   Paul Moore   audit: rework the...
721
   * Description:
5b52330bb   Paul Moore   audit: fix auditd...
722
723
724
   * 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...
725
   */
c6480207f   Paul Moore   audit: rework the...
726
  static void kauditd_send_multicast_skb(struct sk_buff *skb)
451f92163   Richard Guy Briggs   audit: add netlin...
727
  {
c6480207f   Paul Moore   audit: rework the...
728
  	struct sk_buff *copy;
5b52330bb   Paul Moore   audit: fix auditd...
729
  	struct sock *sock = audit_get_sk(&init_net);
c6480207f   Paul Moore   audit: rework the...
730
  	struct nlmsghdr *nlh;
451f92163   Richard Guy Briggs   audit: add netlin...
731

5b52330bb   Paul Moore   audit: fix auditd...
732
733
  	/* 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...
734
735
  	if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
  		return;
451f92163   Richard Guy Briggs   audit: add netlin...
736
737
738
739
740
741
742
743
744
745
  	/*
  	 * 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...
746
  	copy = skb_copy(skb, GFP_KERNEL);
451f92163   Richard Guy Briggs   audit: add netlin...
747
748
  	if (!copy)
  		return;
c6480207f   Paul Moore   audit: rework the...
749
750
  	nlh = nlmsg_hdr(copy);
  	nlh->nlmsg_len = skb->len;
451f92163   Richard Guy Briggs   audit: add netlin...
751

c6480207f   Paul Moore   audit: rework the...
752
  	nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
451f92163   Richard Guy Briggs   audit: add netlin...
753
  }
c6480207f   Paul Moore   audit: rework the...
754
  /**
5b52330bb   Paul Moore   audit: fix auditd...
755
756
   * kauditd_thread - Worker thread to send audit records to userspace
   * @dummy: unused
b551d1d98   Richard Guy Briggs   audit: refactor h...
757
   */
97a41e261   Adrian Bunk   [PATCH] kernel/: ...
758
  static int kauditd_thread(void *dummy)
b7d112581   David Woodhouse   AUDIT: Send netli...
759
  {
c6480207f   Paul Moore   audit: rework the...
760
  	int rc;
5b52330bb   Paul Moore   audit: fix auditd...
761
762
763
  	u32 portid = 0;
  	struct net *net = NULL;
  	struct sock *sk = NULL;
48d0e023a   Paul Moore   audit: fix the RC...
764
  	struct auditd_connection *ac;
4aa83872d   Paul Moore   audit: queue netl...
765

c6480207f   Paul Moore   audit: rework the...
766
  #define UNICAST_RETRIES 5
c6480207f   Paul Moore   audit: rework the...
767

831441862   Rafael J. Wysocki   Freezer: make ker...
768
  	set_freezable();
4899b8b16   Andrew Morton   [PATCH] kauditd_t...
769
  	while (!kthread_should_stop()) {
5b52330bb   Paul Moore   audit: fix auditd...
770
771
  		/* NOTE: see the lock comments in auditd_send_unicast_skb() */
  		rcu_read_lock();
48d0e023a   Paul Moore   audit: fix the RC...
772
773
  		ac = rcu_dereference(auditd_conn);
  		if (!ac) {
5b52330bb   Paul Moore   audit: fix auditd...
774
775
776
  			rcu_read_unlock();
  			goto main_queue;
  		}
48d0e023a   Paul Moore   audit: fix the RC...
777
  		net = get_net(ac->net);
5b52330bb   Paul Moore   audit: fix auditd...
778
  		sk = audit_get_sk(net);
48d0e023a   Paul Moore   audit: fix the RC...
779
  		portid = ac->portid;
5b52330bb   Paul Moore   audit: fix auditd...
780
  		rcu_read_unlock();
c6480207f   Paul Moore   audit: rework the...
781
782
  
  		/* attempt to flush the hold queue */
5b52330bb   Paul Moore   audit: fix auditd...
783
784
785
  		rc = kauditd_send_queue(sk, portid,
  					&audit_hold_queue, UNICAST_RETRIES,
  					NULL, kauditd_rehold_skb);
c81be52a3   Paul Moore   audit: fix a race...
786
  		if (ac && rc < 0) {
5b52330bb   Paul Moore   audit: fix auditd...
787
  			sk = NULL;
c81be52a3   Paul Moore   audit: fix a race...
788
  			auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
789
  			goto main_queue;
c6480207f   Paul Moore   audit: rework the...
790
  		}
f3d357b09   Eric Paris   Audit: save audit...
791

c6480207f   Paul Moore   audit: rework the...
792
  		/* attempt to flush the retry queue */
5b52330bb   Paul Moore   audit: fix auditd...
793
794
795
  		rc = kauditd_send_queue(sk, portid,
  					&audit_retry_queue, UNICAST_RETRIES,
  					NULL, kauditd_hold_skb);
c81be52a3   Paul Moore   audit: fix a race...
796
  		if (ac && rc < 0) {
5b52330bb   Paul Moore   audit: fix auditd...
797
  			sk = NULL;
c81be52a3   Paul Moore   audit: fix a race...
798
  			auditd_reset(ac);
5b52330bb   Paul Moore   audit: fix auditd...
799
  			goto main_queue;
c6480207f   Paul Moore   audit: rework the...
800
  		}
db8973194   Dan Duval   audit: efficiency...
801

5b52330bb   Paul Moore   audit: fix auditd...
802
803
804
805
  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...
806
  		 * multicast send and move the record to the hold queue */
264d50963   Paul Moore   audit: make sure ...
807
808
  		rc = kauditd_send_queue(sk, portid, &audit_queue, 1,
  					kauditd_send_multicast_skb,
c81be52a3   Paul Moore   audit: fix a race...
809
810
811
812
  					(sk ?
  					 kauditd_retry_skb : kauditd_hold_skb));
  		if (ac && rc < 0)
  			auditd_reset(ac);
264d50963   Paul Moore   audit: make sure ...
813
  		sk = NULL;
5b52330bb   Paul Moore   audit: fix auditd...
814
815
816
817
818
  
  		/* drop our netns reference, no auditd sends past this line */
  		if (net) {
  			put_net(net);
  			net = NULL;
3320c5133   Richard Guy Briggs   audit: flatten ka...
819
  		}
5b52330bb   Paul Moore   audit: fix auditd...
820
821
822
823
824
825
826
827
828
829
  
  		/* 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...
830
  	}
c6480207f   Paul Moore   audit: rework the...
831

4899b8b16   Andrew Morton   [PATCH] kauditd_t...
832
  	return 0;
b7d112581   David Woodhouse   AUDIT: Send netli...
833
  }
9044e6bca   Al Viro   [PATCH] fix deadl...
834
835
836
  int audit_send_list(void *_dest)
  {
  	struct audit_netlink_list *dest = _dest;
9044e6bca   Al Viro   [PATCH] fix deadl...
837
  	struct sk_buff *skb;
5b52330bb   Paul Moore   audit: fix auditd...
838
  	struct sock *sk = audit_get_sk(dest->net);
9044e6bca   Al Viro   [PATCH] fix deadl...
839
840
  
  	/* wait for parent to finish and send an ACK */
f368c07d7   Amy Griffis   [PATCH] audit: pa...
841
842
  	mutex_lock(&audit_cmd_mutex);
  	mutex_unlock(&audit_cmd_mutex);
9044e6bca   Al Viro   [PATCH] fix deadl...
843
844
  
  	while ((skb = __skb_dequeue(&dest->q)) != NULL)
5b52330bb   Paul Moore   audit: fix auditd...
845
  		netlink_unicast(sk, skb, dest->portid, 0);
9044e6bca   Al Viro   [PATCH] fix deadl...
846

5b52330bb   Paul Moore   audit: fix auditd...
847
  	put_net(dest->net);
9044e6bca   Al Viro   [PATCH] fix deadl...
848
849
850
851
  	kfree(dest);
  
  	return 0;
  }
45a0642b4   Paul Moore   audit: kernel gen...
852
  struct sk_buff *audit_make_reply(int seq, int type, int done,
b8800aa5d   Stephen Hemminger   audit: make funct...
853
  				 int multi, const void *payload, int size)
9044e6bca   Al Viro   [PATCH] fix deadl...
854
855
856
  {
  	struct sk_buff	*skb;
  	struct nlmsghdr	*nlh;
9044e6bca   Al Viro   [PATCH] fix deadl...
857
858
859
  	void		*data;
  	int		flags = multi ? NLM_F_MULTI : 0;
  	int		t     = done  ? NLMSG_DONE  : type;
ee080e6ce   Eric Paris   Audit: cleanup ne...
860
  	skb = nlmsg_new(size, GFP_KERNEL);
9044e6bca   Al Viro   [PATCH] fix deadl...
861
862
  	if (!skb)
  		return NULL;
45a0642b4   Paul Moore   audit: kernel gen...
863
  	nlh	= nlmsg_put(skb, 0, seq, t, size, flags);
c64e66c67   David S. Miller   audit: netlink: M...
864
865
866
  	if (!nlh)
  		goto out_kfree_skb;
  	data = nlmsg_data(nlh);
9044e6bca   Al Viro   [PATCH] fix deadl...
867
868
  	memcpy(data, payload, size);
  	return skb;
c64e66c67   David S. Miller   audit: netlink: M...
869
870
  out_kfree_skb:
  	kfree_skb(skb);
9044e6bca   Al Viro   [PATCH] fix deadl...
871
872
  	return NULL;
  }
f09ac9db2   Eric Paris   Audit: stop deadl...
873
874
875
  static int audit_send_reply_thread(void *arg)
  {
  	struct audit_reply *reply = (struct audit_reply *)arg;
5b52330bb   Paul Moore   audit: fix auditd...
876
  	struct sock *sk = audit_get_sk(reply->net);
f09ac9db2   Eric Paris   Audit: stop deadl...
877
878
879
880
881
882
  
  	mutex_lock(&audit_cmd_mutex);
  	mutex_unlock(&audit_cmd_mutex);
  
  	/* Ignore failure. It'll only happen if the sender goes away,
  	   because our timeout is set to infinite. */
5b52330bb   Paul Moore   audit: fix auditd...
883
884
  	netlink_unicast(sk, reply->skb, reply->portid, 0);
  	put_net(reply->net);
f09ac9db2   Eric Paris   Audit: stop deadl...
885
886
887
  	kfree(reply);
  	return 0;
  }
c6480207f   Paul Moore   audit: rework the...
888

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
889
890
  /**
   * audit_send_reply - send an audit reply message via netlink
d211f177b   Eric W. Biederman   audit: Update kdo...
891
   * @request_skb: skb of request we are replying to (used to target the reply)
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
892
893
894
895
896
897
898
   * @seq: sequence number
   * @type: audit message type
   * @done: done (last) flag
   * @multi: multi-part message flag
   * @payload: payload data
   * @size: payload size
   *
f9441639e   Richard Guy Briggs   audit: fix netlin...
899
   * Allocates an skb, builds the netlink message, and sends it to the port id.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
900
901
   * No failure notifications.
   */
6f285b19d   Eric W. Biederman   audit: Send repli...
902
  static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
f9441639e   Richard Guy Briggs   audit: fix netlin...
903
  			     int multi, const void *payload, int size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
  {
6f285b19d   Eric W. Biederman   audit: Send repli...
905
  	struct net *net = sock_net(NETLINK_CB(request_skb).sk);
f09ac9db2   Eric Paris   Audit: stop deadl...
906
907
908
909
910
911
912
  	struct sk_buff *skb;
  	struct task_struct *tsk;
  	struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
  					    GFP_KERNEL);
  
  	if (!reply)
  		return;
45a0642b4   Paul Moore   audit: kernel gen...
913
  	skb = audit_make_reply(seq, type, done, multi, payload, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
  	if (!skb)
fcaf1eb86   Andrew Morton   [patch 1/1] audit...
915
  		goto out;
f09ac9db2   Eric Paris   Audit: stop deadl...
916

6f285b19d   Eric W. Biederman   audit: Send repli...
917
  	reply->net = get_net(net);
45a0642b4   Paul Moore   audit: kernel gen...
918
  	reply->portid = NETLINK_CB(request_skb).portid;
f09ac9db2   Eric Paris   Audit: stop deadl...
919
920
921
  	reply->skb = skb;
  
  	tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
fcaf1eb86   Andrew Morton   [patch 1/1] audit...
922
923
924
925
926
  	if (!IS_ERR(tsk))
  		return;
  	kfree_skb(skb);
  out:
  	kfree(reply);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
928
929
930
931
932
  }
  
  /*
   * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
   * control messages.
   */
c7bdb545d   Darrel Goeddel   [NETLINK]: Encaps...
933
  static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
  {
  	int err = 0;
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
936
  	/* Only support initial user namespace for now. */
aa4af831b   Eric Paris   AUDIT: Allow logi...
937
938
939
940
941
942
943
944
945
946
  	/*
  	 * 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...
947
  	if (current_user_ns() != &init_user_ns)
aa4af831b   Eric Paris   AUDIT: Allow logi...
948
  		return -ECONNREFUSED;
34e36d8ec   Eric W. Biederman   audit: Limit audi...
949

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
  	switch (msg_type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
  	case AUDIT_LIST:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
953
  	case AUDIT_ADD:
  	case AUDIT_DEL:
189009091   Eric Paris   audit: remove the...
954
955
956
  		return -EOPNOTSUPP;
  	case AUDIT_GET:
  	case AUDIT_SET:
b0fed4021   Eric Paris   audit: implement ...
957
958
  	case AUDIT_GET_FEATURE:
  	case AUDIT_SET_FEATURE:
189009091   Eric Paris   audit: remove the...
959
960
  	case AUDIT_LIST_RULES:
  	case AUDIT_ADD_RULE:
93315ed6d   Amy Griffis   [PATCH] audit str...
961
  	case AUDIT_DEL_RULE:
c2f0c7c35   Steve Grubb   The attached patc...
962
  	case AUDIT_SIGNAL_INFO:
522ed7767   Miloslav Trmac   Audit: add TTY in...
963
964
  	case AUDIT_TTY_GET:
  	case AUDIT_TTY_SET:
74c3cbe33   Al Viro   [PATCH] audit: wa...
965
966
  	case AUDIT_TRIM:
  	case AUDIT_MAKE_EQUIV:
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
967
968
  		/* Only support auditd and auditctl in initial pid namespace
  		 * for now. */
5985de675   Ameen Ali   audit: code clean up
969
  		if (task_active_pid_ns(current) != &init_pid_ns)
5a3cb3b6c   Richard Guy Briggs   audit: allow user...
970
  			return -EPERM;
90f62cf30   Eric W. Biederman   net: Use netlink_...
971
  		if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
973
  			err = -EPERM;
  		break;
05474106a   Steve Grubb   AUDIT: Fix AVC_US...
974
  	case AUDIT_USER:
039b6b3ed   Robert P. J. Day   audit: add spaces...
975
976
  	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_...
977
  		if (!netlink_capable(skb, CAP_AUDIT_WRITE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
980
981
982
983
984
985
  			err = -EPERM;
  		break;
  	default:  /* bad msg */
  		err = -EINVAL;
  	}
  
  	return err;
  }
233a68667   Paul Moore   audit: make audit...
986
  static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
50397bd1e   Eric Paris   [AUDIT] clean up ...
987
  {
dc9eb698f   Eric Paris   audit: stop pushi...
988
  	uid_t uid = from_kuid(&init_user_ns, current_uid());
f1dc4867f   Richard Guy Briggs   audit: anchor all...
989
  	pid_t pid = task_tgid_nr(current);
50397bd1e   Eric Paris   [AUDIT] clean up ...
990

0868a5e15   Tyler Hicks   audit: printk USE...
991
  	if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
50397bd1e   Eric Paris   [AUDIT] clean up ...
992
  		*ab = NULL;
233a68667   Paul Moore   audit: make audit...
993
  		return;
50397bd1e   Eric Paris   [AUDIT] clean up ...
994
995
996
  	}
  
  	*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
0644ec0cc   Kees Cook   audit: catch poss...
997
  	if (unlikely(!*ab))
233a68667   Paul Moore   audit: make audit...
998
  		return;
f1dc4867f   Richard Guy Briggs   audit: anchor all...
999
  	audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
4d3fb709b   Eric Paris   helper for some s...
1000
  	audit_log_session_info(*ab);
b122c3767   Eric Paris   audit: use a cons...
1001
  	audit_log_task_context(*ab);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1002
  }
b0fed4021   Eric Paris   audit: implement ...
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
  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...
1014
  	audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
b0fed4021   Eric Paris   audit: implement ...
1015
1016
1017
1018
1019
1020
1021
1022
  
  	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...
1023
1024
  	if (audit_enabled == AUDIT_OFF)
  		return;
b0fed4021   Eric Paris   audit: implement ...
1025
  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
4a856adf2   Richard Guy Briggs   audit: return on ...
1026
1027
  	if (!ab)
  		return;
ad2ac2632   Richard Guy Briggs   audit: log task i...
1028
  	audit_log_task_info(ab, current);
897f1acbb   Richard Guy Briggs   audit: AUDIT_FEAT...
1029
  	audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d",
b0fed4021   Eric Paris   audit: implement ...
1030
1031
1032
1033
1034
1035
1036
1037
1038
  			 audit_feature_names[which], !!old_feature, !!new_feature,
  			 !!old_lock, !!new_lock, res);
  	audit_log_end(ab);
  }
  
  static int audit_set_feature(struct sk_buff *skb)
  {
  	struct audit_features *uaf;
  	int i;
6eed9b261   Fabian Frederick   kernel/audit.c: u...
1039
  	BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
b0fed4021   Eric Paris   audit: implement ...
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
  	uaf = nlmsg_data(nlmsg_hdr(skb));
  
  	/* 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...
1058
  		if (old_lock && (new_feature != old_feature)) {
b0fed4021   Eric Paris   audit: implement ...
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  			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 ...
1091
  static int audit_replace(struct pid *pid)
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1092
  {
b6c7c115c   Paul Moore   audit: store the ...
1093
  	pid_t pvnr;
5b52330bb   Paul Moore   audit: fix auditd...
1094
  	struct sk_buff *skb;
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1095

b6c7c115c   Paul Moore   audit: store the ...
1096
1097
  	pvnr = pid_vnr(pid);
  	skb = audit_make_reply(0, AUDIT_REPLACE, 0, 0, &pvnr, sizeof(pvnr));
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1098
1099
  	if (!skb)
  		return -ENOMEM;
5b52330bb   Paul Moore   audit: fix auditd...
1100
  	return auditd_send_unicast_skb(skb);
133e1e5ac   Richard Guy Briggs   audit: stop an ol...
1101
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1102
1103
  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  {
dc9eb698f   Eric Paris   audit: stop pushi...
1104
  	u32			seq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  	void			*data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
  	int			err;
c04049939   Steve Grubb   AUDIT: Add messag...
1107
  	struct audit_buffer	*ab;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
  	u16			msg_type = nlh->nlmsg_type;
e1396065e   Al Viro   [PATCH] collect s...
1109
  	struct audit_sig_info   *sig_data;
50397bd1e   Eric Paris   [AUDIT] clean up ...
1110
  	char			*ctx = NULL;
e1396065e   Al Viro   [PATCH] collect s...
1111
  	u32			len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1112

c7bdb545d   Darrel Goeddel   [NETLINK]: Encaps...
1113
  	err = audit_netlink_ok(skb, msg_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
1115
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
  	seq  = nlh->nlmsg_seq;
c64e66c67   David S. Miller   audit: netlink: M...
1117
  	data = nlmsg_data(nlh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118
1119
  
  	switch (msg_type) {
09f883a90   Richard Guy Briggs   audit: clean up A...
1120
1121
1122
1123
1124
  	case AUDIT_GET: {
  		struct audit_status	s;
  		memset(&s, 0, sizeof(s));
  		s.enabled		= audit_enabled;
  		s.failure		= audit_failure;
b6c7c115c   Paul Moore   audit: store the ...
1125
1126
  		/* NOTE: use pid_vnr() so the PID is relative to the current
  		 *       namespace */
48d0e023a   Paul Moore   audit: fix the RC...
1127
  		s.pid			= auditd_pid_vnr();
09f883a90   Richard Guy Briggs   audit: clean up A...
1128
1129
1130
  		s.rate_limit		= audit_rate_limit;
  		s.backlog_limit		= audit_backlog_limit;
  		s.lost			= atomic_read(&audit_lost);
af8b824f2   Paul Moore   audit: rename the...
1131
  		s.backlog		= skb_queue_len(&audit_queue);
0288d7183   Richard Guy Briggs   audit: convert st...
1132
  		s.feature_bitmap	= AUDIT_FEATURE_BITMAP_ALL;
319754248   Paul Moore   audit: rework aud...
1133
  		s.backlog_wait_time	= audit_backlog_wait_time;
6f285b19d   Eric W. Biederman   audit: Send repli...
1134
  		audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  		break;
09f883a90   Richard Guy Briggs   audit: clean up A...
1136
1137
1138
1139
1140
1141
1142
1143
  	}
  	case AUDIT_SET: {
  		struct audit_status	s;
  		memset(&s, 0, sizeof(s));
  		/* guard against past and future API changes */
  		memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
  		if (s.mask & AUDIT_STATUS_ENABLED) {
  			err = audit_set_enabled(s.enabled);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1144
1145
  			if (err < 0)
  				return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1147
1148
  		if (s.mask & AUDIT_STATUS_FAILURE) {
  			err = audit_set_failure(s.failure);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1149
1150
  			if (err < 0)
  				return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1152
  		if (s.mask & AUDIT_STATUS_PID) {
b6c7c115c   Paul Moore   audit: store the ...
1153
1154
1155
1156
1157
1158
1159
  			/* 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...
1160
  			pid_t auditd_pid;
b6c7c115c   Paul Moore   audit: store the ...
1161
  			struct pid *req_pid = task_tgid(current);
4086f7cf0   Steve Grubb   audit: Allow audi...
1162
1163
1164
  			/* 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 ...
1165
  				return -EINVAL;
1a6b9f231   Eric Paris   [AUDIT] make audi...
1166

5b52330bb   Paul Moore   audit: fix auditd...
1167
  			/* test the auditd connection */
b6c7c115c   Paul Moore   audit: store the ...
1168
  			audit_replace(req_pid);
5b52330bb   Paul Moore   audit: fix auditd...
1169

48d0e023a   Paul Moore   audit: fix the RC...
1170
  			auditd_pid = auditd_pid_vnr();
4086f7cf0   Steve Grubb   audit: Allow audi...
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
  			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...
1184
  			}
5b52330bb   Paul Moore   audit: fix auditd...
1185

533c7b69c   Richard Guy Briggs   audit: use proper...
1186
  			if (new_pid) {
5b52330bb   Paul Moore   audit: fix auditd...
1187
  				/* register a new auditd connection */
48d0e023a   Paul Moore   audit: fix the RC...
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
  				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...
1198
1199
  				/* try to process any backlog */
  				wake_up_interruptible(&kauditd_wait);
48d0e023a   Paul Moore   audit: fix the RC...
1200
1201
1202
1203
1204
  			} else {
  				if (audit_enabled != AUDIT_OFF)
  					audit_log_config_change("audit_pid",
  								new_pid,
  								auditd_pid, 1);
5b52330bb   Paul Moore   audit: fix auditd...
1205
  				/* unregister the auditd connection */
c81be52a3   Paul Moore   audit: fix a race...
1206
  				auditd_reset(NULL);
48d0e023a   Paul Moore   audit: fix the RC...
1207
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1208
  		}
09f883a90   Richard Guy Briggs   audit: clean up A...
1209
1210
  		if (s.mask & AUDIT_STATUS_RATE_LIMIT) {
  			err = audit_set_rate_limit(s.rate_limit);
20c6aaa39   zhangxiliang   [PATCH] Fix the b...
1211
1212
1213
  			if (err < 0)
  				return err;
  		}
51cc83f02   Richard Guy Briggs   audit: add audit_...
1214
  		if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) {
09f883a90   Richard Guy Briggs   audit: clean up A...
1215
  			err = audit_set_backlog_limit(s.backlog_limit);
51cc83f02   Richard Guy Briggs   audit: add audit_...
1216
1217
1218
  			if (err < 0)
  				return err;
  		}
3f0c5fad8   Eric Paris   audit: remove nee...
1219
1220
1221
  		if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) {
  			if (sizeof(s) > (size_t)nlh->nlmsg_len)
  				return -EINVAL;
724e7bfcc   Pranith Kumar   audit: Remove con...
1222
  			if (s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME)
3f0c5fad8   Eric Paris   audit: remove nee...
1223
1224
1225
1226
  				return -EINVAL;
  			err = audit_set_backlog_wait_time(s.backlog_wait_time);
  			if (err < 0)
  				return err;
51cc83f02   Richard Guy Briggs   audit: add audit_...
1227
  		}
92c82e8a3   Richard Guy Briggs   audit: add featur...
1228
1229
1230
1231
1232
1233
  		if (s.mask == AUDIT_STATUS_LOST) {
  			u32 lost = atomic_xchg(&audit_lost, 0);
  
  			audit_log_config_change("lost", 0, lost, 1);
  			return lost;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
  		break;
09f883a90   Richard Guy Briggs   audit: clean up A...
1235
  	}
b0fed4021   Eric Paris   audit: implement ...
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  	case AUDIT_GET_FEATURE:
  		err = audit_get_feature(skb);
  		if (err)
  			return err;
  		break;
  	case AUDIT_SET_FEATURE:
  		err = audit_set_feature(skb);
  		if (err)
  			return err;
  		break;
05474106a   Steve Grubb   AUDIT: Fix AVC_US...
1246
  	case AUDIT_USER:
039b6b3ed   Robert P. J. Day   audit: add spaces...
1247
1248
  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
  	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1249
1250
  		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
  			return 0;
86b2efbe3   Richard Guy Briggs   audit: add fields...
1251
  		err = audit_filter(msg_type, AUDIT_FILTER_USER);
724e4fcc8   Richard Guy Briggs   audit: log on err...
1252
  		if (err == 1) { /* match or error */
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1253
  			err = 0;
522ed7767   Miloslav Trmac   Audit: add TTY in...
1254
  			if (msg_type == AUDIT_USER_TTY) {
37282a779   Peter Hurley   tty: audit: Combi...
1255
  				err = tty_audit_push();
522ed7767   Miloslav Trmac   Audit: add TTY in...
1256
1257
1258
  				if (err)
  					break;
  			}
dc9eb698f   Eric Paris   audit: stop pushi...
1259
  			audit_log_common_recv_msg(&ab, msg_type);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1260
  			if (msg_type != AUDIT_USER_TTY)
b50eba7e2   Richard Guy Briggs   audit: format use...
1261
1262
  				audit_log_format(ab, " msg='%.*s'",
  						 AUDIT_MESSAGE_TEXT_MAX,
50397bd1e   Eric Paris   [AUDIT] clean up ...
1263
1264
1265
  						 (char *)data);
  			else {
  				int size;
f7616102d   Eric Paris   audit: use data= ...
1266
  				audit_log_format(ab, " data=");
50397bd1e   Eric Paris   [AUDIT] clean up ...
1267
  				size = nlmsg_len(nlh);
55ad2f8d3   Miloslav Trmac   audit: ignore ter...
1268
1269
1270
  				if (size > 0 &&
  				    ((unsigned char *)data)[size - 1] == '\0')
  					size--;
b556f8ad5   Eric Paris   Audit: standardiz...
1271
  				audit_log_n_untrustedstring(ab, data, size);
4a4cd633b   David Woodhouse   AUDIT: Optimise t...
1272
  			}
50397bd1e   Eric Paris   [AUDIT] clean up ...
1273
  			audit_log_end(ab);
0f45aa18e   David Woodhouse   AUDIT: Allow filt...
1274
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
  		break;
93315ed6d   Amy Griffis   [PATCH] audit str...
1276
1277
1278
1279
  	case AUDIT_ADD_RULE:
  	case AUDIT_DEL_RULE:
  		if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
  			return -EINVAL;
1a6b9f231   Eric Paris   [AUDIT] make audi...
1280
  		if (audit_enabled == AUDIT_LOCKED) {
dc9eb698f   Eric Paris   audit: stop pushi...
1281
1282
  			audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
  			audit_log_format(ab, " audit_enabled=%d res=0", audit_enabled);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1283
  			audit_log_end(ab);
6a01b07fa   Steve Grubb   [PATCH] audit con...
1284
1285
  			return -EPERM;
  		}
45a0642b4   Paul Moore   audit: kernel gen...
1286
  		err = audit_rule_change(msg_type, seq, data, nlmsg_len(nlh));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
  		break;
ce0d9f046   Richard Guy Briggs   audit: refactor a...
1288
  	case AUDIT_LIST_RULES:
6f285b19d   Eric W. Biederman   audit: Send repli...
1289
  		err = audit_list_rules_send(skb, seq);
ce0d9f046   Richard Guy Briggs   audit: refactor a...
1290
  		break;
74c3cbe33   Al Viro   [PATCH] audit: wa...
1291
1292
  	case AUDIT_TRIM:
  		audit_trim_trees();
dc9eb698f   Eric Paris   audit: stop pushi...
1293
  		audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1294
1295
1296
1297
1298
1299
  		audit_log_format(ab, " op=trim res=1");
  		audit_log_end(ab);
  		break;
  	case AUDIT_MAKE_EQUIV: {
  		void *bufp = data;
  		u32 sizes[2];
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1300
  		size_t msglen = nlmsg_len(nlh);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1301
1302
1303
  		char *old, *new;
  
  		err = -EINVAL;
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1304
  		if (msglen < 2 * sizeof(u32))
74c3cbe33   Al Viro   [PATCH] audit: wa...
1305
1306
1307
  			break;
  		memcpy(sizes, bufp, 2 * sizeof(u32));
  		bufp += 2 * sizeof(u32);
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1308
1309
  		msglen -= 2 * sizeof(u32);
  		old = audit_unpack_string(&bufp, &msglen, sizes[0]);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1310
1311
1312
1313
  		if (IS_ERR(old)) {
  			err = PTR_ERR(old);
  			break;
  		}
7719e437f   Harvey Harrison   [PATCH 2/2] audit...
1314
  		new = audit_unpack_string(&bufp, &msglen, sizes[1]);
74c3cbe33   Al Viro   [PATCH] audit: wa...
1315
1316
1317
1318
1319
1320
1321
  		if (IS_ERR(new)) {
  			err = PTR_ERR(new);
  			kfree(old);
  			break;
  		}
  		/* OK, here comes... */
  		err = audit_tag_tree(old, new);
dc9eb698f   Eric Paris   audit: stop pushi...
1322
  		audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
50397bd1e   Eric Paris   [AUDIT] clean up ...
1323

74c3cbe33   Al Viro   [PATCH] audit: wa...
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
  		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...
1334
  	case AUDIT_SIGNAL_INFO:
939cbf260   Eric Paris   Audit: send signa...
1335
1336
1337
1338
1339
1340
  		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...
1341
1342
  		sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
  		if (!sig_data) {
939cbf260   Eric Paris   Audit: send signa...
1343
1344
  			if (audit_sig_sid)
  				security_release_secctx(ctx, len);
e1396065e   Al Viro   [PATCH] collect s...
1345
1346
  			return -ENOMEM;
  		}
cca080d9b   Eric W. Biederman   userns: Convert a...
1347
  		sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
e1396065e   Al Viro   [PATCH] collect s...
1348
  		sig_data->pid = audit_sig_pid;
939cbf260   Eric Paris   Audit: send signa...
1349
1350
1351
1352
  		if (audit_sig_sid) {
  			memcpy(sig_data->ctx, ctx, len);
  			security_release_secctx(ctx, len);
  		}
6f285b19d   Eric W. Biederman   audit: Send repli...
1353
1354
  		audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
  				 sig_data, sizeof(*sig_data) + len);
e1396065e   Al Viro   [PATCH] collect s...
1355
  		kfree(sig_data);
c2f0c7c35   Steve Grubb   The attached patc...
1356
  		break;
522ed7767   Miloslav Trmac   Audit: add TTY in...
1357
1358
  	case AUDIT_TTY_GET: {
  		struct audit_tty_status s;
2e28d38ae   Peter Hurley   tty: audit: Handl...
1359
  		unsigned int t;
8aa14b649   Eric W. Biederman   audit: Simply AUD...
1360

2e28d38ae   Peter Hurley   tty: audit: Handl...
1361
1362
1363
  		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...
1364

6f285b19d   Eric W. Biederman   audit: Send repli...
1365
  		audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
522ed7767   Miloslav Trmac   Audit: add TTY in...
1366
1367
1368
  		break;
  	}
  	case AUDIT_TTY_SET: {
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1369
  		struct audit_tty_status s, old;
a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1370
  		struct audit_buffer	*ab;
2e28d38ae   Peter Hurley   tty: audit: Handl...
1371
  		unsigned int t;
0e23bacca   Eric Paris   audit: rework AUD...
1372
1373
1374
1375
1376
1377
1378
1379
  
  		memset(&s, 0, sizeof(s));
  		/* guard against past and future API changes */
  		memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
  		/* 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_...
1380

2e28d38ae   Peter Hurley   tty: audit: Handl...
1381
1382
1383
1384
1385
  		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...
1386
  		}
2e28d38ae   Peter Hurley   tty: audit: Handl...
1387
1388
  		old.enabled = t & AUDIT_TTY_ENABLE;
  		old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
522ed7767   Miloslav Trmac   Audit: add TTY in...
1389

a06e56b2a   Richard Guy Briggs   audit: log AUDIT_...
1390
  		audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
1ce319f11   Eric Paris   audit: reorder AU...
1391
1392
1393
1394
  		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_...
1395
  		audit_log_end(ab);
522ed7767   Miloslav Trmac   Audit: add TTY in...
1396
1397
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398
1399
1400
1401
1402
1403
1404
  	default:
  		err = -EINVAL;
  		break;
  	}
  
  	return err < 0 ? err : 0;
  }
a9d162087   Paul Moore   audit: combine au...
1405
1406
1407
1408
1409
1410
  /**
   * 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...
1411
   */
a9d162087   Paul Moore   audit: combine au...
1412
  static void audit_receive(struct sk_buff  *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
  {
ea7ae60bf   Eric Paris   Audit: clean up a...
1414
1415
  	struct nlmsghdr *nlh;
  	/*
941912133   Hong zhi guo   audit: replace ob...
1416
  	 * len MUST be signed for nlmsg_next to be able to dec it below 0
ea7ae60bf   Eric Paris   Audit: clean up a...
1417
1418
1419
1420
1421
1422
1423
  	 * if the nlmsg_len was not aligned
  	 */
  	int len;
  	int err;
  
  	nlh = nlmsg_hdr(skb);
  	len = skb->len;
a9d162087   Paul Moore   audit: combine au...
1424
  	mutex_lock(&audit_cmd_mutex);
941912133   Hong zhi guo   audit: replace ob...
1425
  	while (nlmsg_ok(nlh, len)) {
ea7ae60bf   Eric Paris   Audit: clean up a...
1426
1427
1428
  		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...
1429
  			netlink_ack(skb, nlh, err, NULL);
ea7ae60bf   Eric Paris   Audit: clean up a...
1430

2851da570   Alexandru Copot   audit: pass int* ...
1431
  		nlh = nlmsg_next(nlh, &len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
  	}
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1433
  	mutex_unlock(&audit_cmd_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1434
  }
3a101b8de   Richard Guy Briggs   audit: add netlin...
1435
  /* Run custom bind function on netlink socket group connect or bind requests. */
023e2cfa3   Johannes Berg   netlink/genetlink...
1436
  static int audit_bind(struct net *net, int group)
3a101b8de   Richard Guy Briggs   audit: add netlin...
1437
1438
1439
1440
1441
1442
  {
  	if (!capable(CAP_AUDIT_READ))
  		return -EPERM;
  
  	return 0;
  }
33faba7fa   Richard Guy Briggs   audit: listen in ...
1443
  static int __net_init audit_net_init(struct net *net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
  {
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
1445
1446
  	struct netlink_kernel_cfg cfg = {
  		.input	= audit_receive,
3a101b8de   Richard Guy Briggs   audit: add netlin...
1447
  		.bind	= audit_bind,
451f92163   Richard Guy Briggs   audit: add netlin...
1448
1449
  		.flags	= NL_CFG_F_NONROOT_RECV,
  		.groups	= AUDIT_NLGRP_MAX,
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
1450
  	};
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1451

33faba7fa   Richard Guy Briggs   audit: listen in ...
1452
  	struct audit_net *aunet = net_generic(net, audit_net_id);
5b52330bb   Paul Moore   audit: fix auditd...
1453
1454
  	aunet->sk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
  	if (aunet->sk == NULL) {
33faba7fa   Richard Guy Briggs   audit: listen in ...
1455
  		audit_panic("cannot initialize netlink socket in namespace");
11ee39ebf   Gao feng   audit: print erro...
1456
1457
  		return -ENOMEM;
  	}
5b52330bb   Paul Moore   audit: fix auditd...
1458
  	aunet->sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
33faba7fa   Richard Guy Briggs   audit: listen in ...
1459
1460
1461
1462
1463
1464
  	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...
1465

48d0e023a   Paul Moore   audit: fix the RC...
1466
1467
1468
1469
1470
  	/* 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 ...
1471

5b52330bb   Paul Moore   audit: fix auditd...
1472
  	netlink_kernel_release(aunet->sk);
33faba7fa   Richard Guy Briggs   audit: listen in ...
1473
  }
8626877b5   Richard Guy Briggs   audit: fix locati...
1474
  static struct pernet_operations audit_net_ops __net_initdata = {
33faba7fa   Richard Guy Briggs   audit: listen in ...
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
  	.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...
1485
1486
  	if (audit_initialized == AUDIT_DISABLED)
  		return 0;
8cc96382d   Paul Moore   audit: use kmem_c...
1487
1488
1489
  	audit_buffer_cache = kmem_cache_create("audit_buffer",
  					       sizeof(struct audit_buffer),
  					       0, SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490

af8b824f2   Paul Moore   audit: rename the...
1491
  	skb_queue_head_init(&audit_queue);
c6480207f   Paul Moore   audit: rework the...
1492
  	skb_queue_head_init(&audit_retry_queue);
af8b824f2   Paul Moore   audit: rename the...
1493
  	skb_queue_head_init(&audit_hold_queue);
3dc7e3153   Darrel Goeddel   [PATCH] support f...
1494

f368c07d7   Amy Griffis   [PATCH] audit: pa...
1495
1496
  	for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
  		INIT_LIST_HEAD(&audit_inode_hash[i]);
f368c07d7   Amy Griffis   [PATCH] audit: pa...
1497

5b52330bb   Paul Moore   audit: fix auditd...
1498
1499
1500
1501
1502
1503
  	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...
1504

6c9255645   Paul Moore   audit: fixup audi...
1505
1506
1507
1508
1509
1510
  	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...
1511
1512
1513
  	audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL,
  		"state=initialized audit_enabled=%u res=1",
  		 audit_enabled);
6c9255645   Paul Moore   audit: fixup audi...
1514

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1517
1518
1519
1520
1521
1522
  __initcall(audit_init);
  
  /* Process kernel command-line parameter at boot time.  audit=0 or audit=1. */
  static int __init audit_enable(char *str)
  {
  	audit_default = !!simple_strtol(str, NULL, 0);
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1523
1524
  	if (!audit_default)
  		audit_initialized = AUDIT_DISABLED;
0ad0bb601   Paul Moore   audit: ensure tha...
1525
1526
  	audit_enabled = audit_default;
  	audit_ever_enabled = !!audit_enabled;
a3f07114e   Eric Paris   [PATCH] Audit: ma...
1527

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

9b41046cd   OGAWA Hirofumi   [PATCH] Don't pas...
1532
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1533
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1534
  __setup("audit=", audit_enable);
f910fde73   Richard Guy Briggs   audit: add kernel...
1535
1536
1537
1538
  /* 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...
1539
  	u32 audit_backlog_limit_arg;
d957f7b72   Joe Perches   audit: Use more c...
1540

f910fde73   Richard Guy Briggs   audit: add kernel...
1541
  	pr_info("audit_backlog_limit: ");
3e1d0bb62   Joe Perches   audit: Convert in...
1542
1543
1544
  	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...
1545
  			audit_backlog_limit, str);
f910fde73   Richard Guy Briggs   audit: add kernel...
1546
1547
  		return 1;
  	}
3e1d0bb62   Joe Perches   audit: Convert in...
1548
1549
  
  	audit_backlog_limit = audit_backlog_limit_arg;
d957f7b72   Joe Perches   audit: Use more c...
1550
1551
  	pr_cont("%d
  ", audit_backlog_limit);
f910fde73   Richard Guy Briggs   audit: add kernel...
1552
1553
1554
1555
  
  	return 1;
  }
  __setup("audit_backlog_limit=", audit_backlog_limit_set);
16e1904e6   Chris Wright   AUDIT: Add helper...
1556
1557
  static void audit_buffer_free(struct audit_buffer *ab)
  {
8fc6115c2   Chris Wright   AUDIT: expand aud...
1558
1559
  	if (!ab)
  		return;
d865e573b   Markus Elfring   audit: Delete unn...
1560
  	kfree_skb(ab->skb);
8cc96382d   Paul Moore   audit: use kmem_c...
1561
  	kmem_cache_free(audit_buffer_cache, ab);
16e1904e6   Chris Wright   AUDIT: Add helper...
1562
  }
8cc96382d   Paul Moore   audit: use kmem_c...
1563
1564
  static struct audit_buffer *audit_buffer_alloc(struct audit_context *ctx,
  					       gfp_t gfp_mask, int type)
16e1904e6   Chris Wright   AUDIT: Add helper...
1565
  {
8cc96382d   Paul Moore   audit: use kmem_c...
1566
  	struct audit_buffer *ab;
8fc6115c2   Chris Wright   AUDIT: expand aud...
1567

8cc96382d   Paul Moore   audit: use kmem_c...
1568
1569
1570
  	ab = kmem_cache_alloc(audit_buffer_cache, gfp_mask);
  	if (!ab)
  		return NULL;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1571
1572
1573
  
  	ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask);
  	if (!ab->skb)
c64e66c67   David S. Miller   audit: netlink: M...
1574
  		goto err;
8cc96382d   Paul Moore   audit: use kmem_c...
1575
1576
  	if (!nlmsg_put(ab->skb, 0, 0, type, 0, 0))
  		goto err;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1577

8cc96382d   Paul Moore   audit: use kmem_c...
1578
1579
  	ab->ctx = ctx;
  	ab->gfp_mask = gfp_mask;
ee080e6ce   Eric Paris   Audit: cleanup ne...
1580

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

8fc6115c2   Chris Wright   AUDIT: expand aud...
1583
1584
1585
  err:
  	audit_buffer_free(ab);
  	return NULL;
16e1904e6   Chris Wright   AUDIT: Add helper...
1586
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1588
1589
1590
1591
  /**
   * 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...
1592
1593
1594
1595
1596
1597
1598
   * 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...
1599
1600
1601
1602
   * 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...
1603
1604
   * halts).
   */
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1605
1606
  unsigned int audit_serial(void)
  {
01478d7d6   Richard Guy Briggs   audit: use atomic...
1607
  	static atomic_t serial = ATOMIC_INIT(0);
d5b454f2c   David Woodhouse   AUDIT: Fix livelo...
1608

01478d7d6   Richard Guy Briggs   audit: use atomic...
1609
  	return atomic_add_return(1, &serial);
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1610
  }
5600b8927   Daniel Walker   whitespace fixes:...
1611
  static inline void audit_get_stamp(struct audit_context *ctx,
2115bb250   Deepa Dinamani   audit: Use timesp...
1612
  				   struct timespec64 *t, unsigned int *serial)
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1613
  {
48887e63d   Al Viro   [PATCH] fix broke...
1614
  	if (!ctx || !auditsc_get_stamp(ctx, t, serial)) {
e832bf48c   Mel Gorman   audit: Reduce ove...
1615
  		*t = current_kernel_time64();
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1616
1617
1618
  		*serial = audit_serial();
  	}
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
  /**
   * 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...
1634
  struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1635
  				     int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1636
  {
319754248   Paul Moore   audit: rework aud...
1637
  	struct audit_buffer *ab;
2115bb250   Deepa Dinamani   audit: Use timesp...
1638
  	struct timespec64 t;
319754248   Paul Moore   audit: rework aud...
1639
  	unsigned int uninitialized_var(serial);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1640

a3f07114e   Eric Paris   [PATCH] Audit: ma...
1641
  	if (audit_initialized != AUDIT_INITIALIZED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1642
  		return NULL;
86b2efbe3   Richard Guy Briggs   audit: add fields...
1643
  	if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
c8edc80c8   Dustin Kirkland   [PATCH] Exclude m...
1644
  		return NULL;
5b52330bb   Paul Moore   audit: fix auditd...
1645
  	/* NOTE: don't ever fail/sleep on these two conditions:
a09cfa470   Paul Moore   audit: don't ever...
1646
1647
1648
1649
  	 * 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...
1650
1651
1652
1653
1654
  	 * 2. generator holding the audit_cmd_mutex - we don't want to block
  	 *    while holding the mutex */
  	if (!(auditd_test_task(current) ||
  	      (current == __mutex_owner(&audit_cmd_mutex)))) {
  		long stime = audit_backlog_wait_time;
319754248   Paul Moore   audit: rework aud...
1655
1656
1657
1658
1659
  
  		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...
1660

319754248   Paul Moore   audit: rework aud...
1661
1662
  			/* sleep if we are allowed and we haven't exhausted our
  			 * backlog wait limit */
5b52330bb   Paul Moore   audit: fix auditd...
1663
  			if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {
319754248   Paul Moore   audit: rework aud...
1664
1665
1666
1667
1668
  				DECLARE_WAITQUEUE(wait, current);
  
  				add_wait_queue_exclusive(&audit_backlog_wait,
  							 &wait);
  				set_current_state(TASK_UNINTERRUPTIBLE);
5b52330bb   Paul Moore   audit: fix auditd...
1669
  				stime = schedule_timeout(stime);
319754248   Paul Moore   audit: rework aud...
1670
1671
1672
1673
1674
1675
1676
1677
1678
  				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...
1679
  			}
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1680
  		}
fb19b4c6a   David Woodhouse   AUDIT: Honour aud...
1681
  	}
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
1682
  	ab = audit_buffer_alloc(ctx, gfp_mask, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1683
1684
1685
1686
  	if (!ab) {
  		audit_log_lost("out of memory in audit_log_start");
  		return NULL;
  	}
bfb4496e7   David Woodhouse   AUDIT: Assign ser...
1687
  	audit_get_stamp(ab->ctx, &t, &serial);
2115bb250   Deepa Dinamani   audit: Use timesp...
1688
1689
  	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...
1690

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
1692
  	return ab;
  }
8fc6115c2   Chris Wright   AUDIT: expand aud...
1693
  /**
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1694
   * audit_expand - expand skb in the audit buffer
8fc6115c2   Chris Wright   AUDIT: expand aud...
1695
   * @ab: audit_buffer
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1696
   * @extra: space to add at tail of the skb
8fc6115c2   Chris Wright   AUDIT: expand aud...
1697
1698
1699
1700
   *
   * Returns 0 (no space) on failed expansion, or available space if
   * successful.
   */
e3b926b4c   David Woodhouse   AUDIT: pass size ...
1701
  static inline int audit_expand(struct audit_buffer *ab, int extra)
8fc6115c2   Chris Wright   AUDIT: expand aud...
1702
  {
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1703
  	struct sk_buff *skb = ab->skb;
406a1d868   Herbert Xu   [AUDIT]: Increase...
1704
1705
1706
  	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...
1707
1708
  	if (ret < 0) {
  		audit_log_lost("out of memory in audit_expand");
8fc6115c2   Chris Wright   AUDIT: expand aud...
1709
  		return 0;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1710
  	}
406a1d868   Herbert Xu   [AUDIT]: Increase...
1711
1712
1713
  
  	skb->truesize += newtail - oldtail;
  	return newtail;
8fc6115c2   Chris Wright   AUDIT: expand aud...
1714
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715

b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1716
1717
  /*
   * Format an audit message into the audit buffer.  If there isn't enough
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718
1719
   * 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...
1720
1721
   * can't format message larger than 1024 bytes, so we don't either.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
1723
1724
1725
  static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
  			      va_list args)
  {
  	int len, avail;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1726
  	struct sk_buff *skb;
eecb0a733   David Woodhouse   AUDIT: Fix abuse ...
1727
  	va_list args2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1728
1729
1730
  
  	if (!ab)
  		return;
5ac52f33b   Chris Wright   AUDIT: buffer aud...
1731
1732
1733
1734
  	BUG_ON(!ab->skb);
  	skb = ab->skb;
  	avail = skb_tailroom(skb);
  	if (avail == 0) {
e3b926b4c   David Woodhouse   AUDIT: pass size ...
1735
  		avail = audit_expand(ab, AUDIT_BUFSIZ);
8fc6115c2   Chris Wright   AUDIT: expand aud...
1736
1737
  		if (!avail)
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
  	}
eecb0a733   David Woodhouse   AUDIT: Fix abuse ...
1739
  	va_copy(args2, args);
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1740
  	len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1741
1742
1743
1744
  	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...
1745
1746
  		avail = audit_expand(ab,
  			max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
8fc6115c2   Chris Wright   AUDIT: expand aud...
1747
  		if (!avail)
a0e86bd42   Jesper Juhl   audit: always fol...
1748
  			goto out_va_end;
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1749
  		len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1750
  	}
168b71739   Steve Grubb   AUDIT: Clean up l...
1751
1752
  	if (len > 0)
  		skb_put(skb, len);
a0e86bd42   Jesper Juhl   audit: always fol...
1753
1754
  out_va_end:
  	va_end(args2);
8fc6115c2   Chris Wright   AUDIT: expand aud...
1755
1756
  out:
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1757
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1758
1759
1760
1761
1762
1763
1764
1765
  /**
   * 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
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
  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...
1776
  /**
196a50855   Geliang Tang   audit: update the...
1777
   * audit_log_n_hex - convert a buffer to hex and append it to the audit skb
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1778
1779
1780
1781
1782
1783
1784
1785
1786
   * @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...
1787
  void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
168b71739   Steve Grubb   AUDIT: Clean up l...
1788
  		size_t len)
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1789
  {
168b71739   Steve Grubb   AUDIT: Clean up l...
1790
1791
1792
  	int i, avail, new_len;
  	unsigned char *ptr;
  	struct sk_buff *skb;
168b71739   Steve Grubb   AUDIT: Clean up l...
1793

8ef2d3040   Amy Griffis   [PATCH] sanity ch...
1794
1795
  	if (!ab)
  		return;
168b71739   Steve Grubb   AUDIT: Clean up l...
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
  	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 ...
1807

27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1808
  	ptr = skb_tail_pointer(skb);
b8dbc3241   Joe Perches   audit: Use hex_by...
1809
1810
  	for (i = 0; i < len; i++)
  		ptr = hex_byte_pack_upper(ptr, buf[i]);
168b71739   Steve Grubb   AUDIT: Clean up l...
1811
1812
  	*ptr = 0;
  	skb_put(skb, len << 1); /* new string is twice the old string */
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1813
  }
9c937dcc7   Amy Griffis   [PATCH] log more ...
1814
1815
1816
1817
  /*
   * Format a string of no more than slen characters into the audit buffer,
   * enclosed in quote marks.
   */
b556f8ad5   Eric Paris   Audit: standardiz...
1818
1819
  void audit_log_n_string(struct audit_buffer *ab, const char *string,
  			size_t slen)
9c937dcc7   Amy Griffis   [PATCH] log more ...
1820
1821
1822
1823
  {
  	int avail, new_len;
  	unsigned char *ptr;
  	struct sk_buff *skb;
8ef2d3040   Amy Griffis   [PATCH] sanity ch...
1824
1825
  	if (!ab)
  		return;
9c937dcc7   Amy Griffis   [PATCH] log more ...
1826
1827
1828
1829
1830
1831
1832
1833
1834
  	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...
1835
  	ptr = skb_tail_pointer(skb);
9c937dcc7   Amy Griffis   [PATCH] log more ...
1836
1837
1838
1839
1840
1841
1842
  	*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...
1843
  /**
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1844
   * audit_string_contains_control - does a string need to be logged in hex
f706d5d22   Dave Jones   audit: silence tw...
1845
1846
   * @string: string to be checked
   * @len: max length of the string to check
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1847
   */
9fcf836b2   Yaowei Bai   audit: audit_stri...
1848
  bool audit_string_contains_control(const char *string, size_t len)
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1849
1850
  {
  	const unsigned char *p;
b3897f567   Miloslav Trmac   Audit: fix handli...
1851
  	for (p = string; p < (const unsigned char *)string + len; p++) {
1d6c9649e   Vesa-Matti J Kari   kernel/audit.c co...
1852
  		if (*p == '"' || *p < 0x21 || *p > 0x7e)
9fcf836b2   Yaowei Bai   audit: audit_stri...
1853
  			return true;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1854
  	}
9fcf836b2   Yaowei Bai   audit: audit_stri...
1855
  	return false;
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1856
1857
1858
  }
  
  /**
522ed7767   Miloslav Trmac   Audit: add TTY in...
1859
   * audit_log_n_untrustedstring - log a string that may contain random characters
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1860
   * @ab: audit_buffer
f706d5d22   Dave Jones   audit: silence tw...
1861
   * @len: length of string (not including trailing null)
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1862
1863
1864
1865
   * @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...
1866
   * or a space. Unescaped strings will start and end with a double quote mark.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
1867
   * Strings that are escaped are printed in hex (2 digits per char).
9c937dcc7   Amy Griffis   [PATCH] log more ...
1868
1869
1870
   *
   * 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...
1871
   */
b556f8ad5   Eric Paris   Audit: standardiz...
1872
1873
  void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string,
  				 size_t len)
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1874
  {
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1875
  	if (audit_string_contains_control(string, len))
b556f8ad5   Eric Paris   Audit: standardiz...
1876
  		audit_log_n_hex(ab, string, len);
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1877
  	else
b556f8ad5   Eric Paris   Audit: standardiz...
1878
  		audit_log_n_string(ab, string, len);
83c7d0917   David Woodhouse   AUDIT: Avoid log ...
1879
  }
9c937dcc7   Amy Griffis   [PATCH] log more ...
1880
  /**
522ed7767   Miloslav Trmac   Audit: add TTY in...
1881
   * audit_log_untrustedstring - log a string that may contain random characters
9c937dcc7   Amy Griffis   [PATCH] log more ...
1882
1883
1884
   * @ab: audit_buffer
   * @string: string to be logged
   *
522ed7767   Miloslav Trmac   Audit: add TTY in...
1885
   * Same as audit_log_n_untrustedstring(), except that strlen is used to
9c937dcc7   Amy Griffis   [PATCH] log more ...
1886
1887
   * determine string length.
   */
de6bbd1d3   Eric Paris   [AUDIT] break lar...
1888
  void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
9c937dcc7   Amy Griffis   [PATCH] log more ...
1889
  {
b556f8ad5   Eric Paris   Audit: standardiz...
1890
  	audit_log_n_untrustedstring(ab, string, strlen(string));
9c937dcc7   Amy Griffis   [PATCH] log more ...
1891
  }
168b71739   Steve Grubb   AUDIT: Clean up l...
1892
  /* This is a helper-function to print the escaped d_path */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1893
  void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
66b3fad3f   Al Viro   constify path arg...
1894
  		      const struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
  {
44707fdf5   Jan Blunck   d_path: Use struc...
1896
  	char *p, *pathname;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1897

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

168b71739   Steve Grubb   AUDIT: Clean up l...
1901
  	/* We will allow 11 spaces for ' (deleted)' to be appended */
44707fdf5   Jan Blunck   d_path: Use struc...
1902
1903
  	pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
  	if (!pathname) {
def575434   Eric Paris   Audit: remove spa...
1904
  		audit_log_string(ab, "<no_memory>");
168b71739   Steve Grubb   AUDIT: Clean up l...
1905
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1906
  	}
cf28b4863   Jan Blunck   d_path: Make d_pa...
1907
  	p = d_path(path, pathname, PATH_MAX+11);
168b71739   Steve Grubb   AUDIT: Clean up l...
1908
1909
  	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
  		/* FIXME: can we save some information here? */
def575434   Eric Paris   Audit: remove spa...
1910
  		audit_log_string(ab, "<too_long>");
5600b8927   Daniel Walker   whitespace fixes:...
1911
  	} else
168b71739   Steve Grubb   AUDIT: Clean up l...
1912
  		audit_log_untrustedstring(ab, p);
44707fdf5   Jan Blunck   d_path: Use struc...
1913
  	kfree(pathname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1914
  }
4d3fb709b   Eric Paris   helper for some s...
1915
1916
  void audit_log_session_info(struct audit_buffer *ab)
  {
4440e8548   Eric Paris   audit: convert al...
1917
  	unsigned int sessionid = audit_get_sessionid(current);
4d3fb709b   Eric Paris   helper for some s...
1918
  	uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current));
b8f89caaf   Richard Guy Briggs   audit: remove new...
1919
  	audit_log_format(ab, " auid=%u ses=%u", auid, sessionid);
4d3fb709b   Eric Paris   helper for some s...
1920
  }
9d9609851   Eric Paris   Audit: clean up a...
1921
1922
1923
1924
1925
1926
1927
1928
  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 ...
1929
1930
1931
1932
1933
1934
1935
  void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap)
  {
  	int i;
  
  	audit_log_format(ab, " %s=", prefix);
  	CAP_FOR_EACH_U32(i) {
  		audit_log_format(ab, "%08x",
7d8b6c637   Eric Paris   CAPABILITIES: rem...
1936
  				 cap->cap[CAP_LAST_U32 - i]);
b24a30a73   Eric Paris   audit: fix event ...
1937
1938
  	}
  }
691e6d59d   Richard Guy Briggs   audit: reduce sco...
1939
  static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
b24a30a73   Eric Paris   audit: fix event ...
1940
  {
4b3e4ed6b   Richard Guy Briggs   audit: unswing ca...
1941
1942
1943
1944
  	audit_log_cap(ab, "cap_fp", &name->fcap.permitted);
  	audit_log_cap(ab, "cap_fi", &name->fcap.inheritable);
  	audit_log_format(ab, " cap_fe=%d cap_fver=%x",
  			 name->fcap.fE, name->fcap_ver);
b24a30a73   Eric Paris   audit: fix event ...
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
  }
  
  static inline int audit_copy_fcaps(struct audit_names *name,
  				   const struct dentry *dentry)
  {
  	struct cpu_vfs_cap_data caps;
  	int rc;
  
  	if (!dentry)
  		return 0;
  
  	rc = get_vfs_caps_from_disk(dentry, &caps);
  	if (rc)
  		return rc;
  
  	name->fcap.permitted = caps.permitted;
  	name->fcap.inheritable = caps.inheritable;
  	name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
  	name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >>
  				VFS_CAP_REVISION_SHIFT;
  
  	return 0;
  }
  
  /* Copy inode data into an audit_names. */
  void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
d6335d77a   Andreas Gruenbacher   security: Make in...
1971
  		      struct inode *inode)
b24a30a73   Eric Paris   audit: fix event ...
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
  {
  	name->ino   = inode->i_ino;
  	name->dev   = inode->i_sb->s_dev;
  	name->mode  = inode->i_mode;
  	name->uid   = inode->i_uid;
  	name->gid   = inode->i_gid;
  	name->rdev  = inode->i_rdev;
  	security_inode_getsecid(inode, &name->osid);
  	audit_copy_fcaps(name, dentry);
  }
  
  /**
   * audit_log_name - produce AUDIT_PATH record from struct audit_names
   * @context: audit_context for the task
   * @n: audit_names structure with reportable details
   * @path: optional path to report instead of audit_names->name
   * @record_num: record number to report when handling a list of names
   * @call_panic: optional pointer to int that will be updated if secid fails
   */
  void audit_log_name(struct audit_context *context, struct audit_names *n,
8bd107633   Al Viro   audit_log_{name,l...
1992
  		    const struct path *path, int record_num, int *call_panic)
b24a30a73   Eric Paris   audit: fix event ...
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
  {
  	struct audit_buffer *ab;
  	ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
  	if (!ab)
  		return;
  
  	audit_log_format(ab, "item=%d", record_num);
  
  	if (path)
  		audit_log_d_path(ab, " name=", path);
  	else if (n->name) {
  		switch (n->name_len) {
  		case AUDIT_NAME_FULL:
  			/* log the full path */
  			audit_log_format(ab, " name=");
  			audit_log_untrustedstring(ab, n->name->name);
  			break;
  		case 0:
  			/* name was specified as a relative path and the
  			 * directory component is the cwd */
  			audit_log_d_path(ab, " name=", &context->pwd);
  			break;
  		default:
  			/* log the name's directory component */
  			audit_log_format(ab, " name=");
  			audit_log_n_untrustedstring(ab, n->name->name,
  						    n->name_len);
  		}
  	} else
  		audit_log_format(ab, " name=(null)");
425afcff1   Linus Torvalds   Merge branch 'ups...
2023
  	if (n->ino != AUDIT_INO_UNSET)
b24a30a73   Eric Paris   audit: fix event ...
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
  		audit_log_format(ab, " inode=%lu"
  				 " dev=%02x:%02x mode=%#ho"
  				 " ouid=%u ogid=%u rdev=%02x:%02x",
  				 n->ino,
  				 MAJOR(n->dev),
  				 MINOR(n->dev),
  				 n->mode,
  				 from_kuid(&init_user_ns, n->uid),
  				 from_kgid(&init_user_ns, n->gid),
  				 MAJOR(n->rdev),
  				 MINOR(n->rdev));
b24a30a73   Eric Paris   audit: fix event ...
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
  	if (n->osid != 0) {
  		char *ctx = NULL;
  		u32 len;
  		if (security_secid_to_secctx(
  			n->osid, &ctx, &len)) {
  			audit_log_format(ab, " osid=%u", n->osid);
  			if (call_panic)
  				*call_panic = 2;
  		} else {
  			audit_log_format(ab, " obj=%s", ctx);
  			security_release_secctx(ctx, len);
  		}
  	}
d3aea84a4   Jeff Layton   audit: log the au...
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
  	/* log the audit_names record type */
  	audit_log_format(ab, " nametype=");
  	switch(n->type) {
  	case AUDIT_TYPE_NORMAL:
  		audit_log_format(ab, "NORMAL");
  		break;
  	case AUDIT_TYPE_PARENT:
  		audit_log_format(ab, "PARENT");
  		break;
  	case AUDIT_TYPE_CHILD_DELETE:
  		audit_log_format(ab, "DELETE");
  		break;
  	case AUDIT_TYPE_CHILD_CREATE:
  		audit_log_format(ab, "CREATE");
  		break;
  	default:
  		audit_log_format(ab, "UNKNOWN");
  		break;
  	}
b24a30a73   Eric Paris   audit: fix event ...
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
  	audit_log_fcaps(ab, n);
  	audit_log_end(ab);
  }
  
  int audit_log_task_context(struct audit_buffer *ab)
  {
  	char *ctx = NULL;
  	unsigned len;
  	int error;
  	u32 sid;
  
  	security_task_getsecid(current, &sid);
  	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...
2098
2099
2100
  void audit_log_d_path_exe(struct audit_buffer *ab,
  			  struct mm_struct *mm)
  {
5b2825527   Davidlohr Bueso   audit: reduce mma...
2101
2102
2103
2104
  	struct file *exe_file;
  
  	if (!mm)
  		goto out_null;
4766b199e   Davidlohr Bueso   audit: consolidat...
2105

5b2825527   Davidlohr Bueso   audit: reduce mma...
2106
2107
2108
2109
2110
2111
2112
2113
2114
  	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...
2115
  }
3f5be2da8   Richard Guy Briggs   audit: move audit...
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
  struct tty_struct *audit_get_tty(struct task_struct *tsk)
  {
  	struct tty_struct *tty = NULL;
  	unsigned long flags;
  
  	spin_lock_irqsave(&tsk->sighand->siglock, flags);
  	if (tsk->signal)
  		tty = tty_kref_get(tsk->signal->tty);
  	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
  	return tty;
  }
  
  void audit_put_tty(struct tty_struct *tty)
  {
  	tty_kref_put(tty);
  }
b24a30a73   Eric Paris   audit: fix event ...
2132
2133
2134
  void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
  {
  	const struct cred *cred;
9eab339b1   Richard Guy Briggs   audit: get comm u...
2135
  	char comm[sizeof(tsk->comm)];
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
2136
  	struct tty_struct *tty;
b24a30a73   Eric Paris   audit: fix event ...
2137
2138
2139
2140
2141
2142
  
  	if (!ab)
  		return;
  
  	/* tsk == current */
  	cred = current_cred();
db0a6fb5d   Richard Guy Briggs   audit: add tty fi...
2143
  	tty = audit_get_tty(tsk);
b24a30a73   Eric Paris   audit: fix event ...
2144
  	audit_log_format(ab,
c92cdeb45   Richard Guy Briggs   audit: convert PP...
2145
  			 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
b24a30a73   Eric Paris   audit: fix event ...
2146
  			 " euid=%u suid=%u fsuid=%u"
2f2ad1013   Richard Guy Briggs   audit: restore or...
2147
  			 " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
c92cdeb45   Richard Guy Briggs   audit: convert PP...
2148
  			 task_ppid_nr(tsk),
fa2bea2f5   Paul Moore   audit: consistent...
2149
  			 task_tgid_nr(tsk),
b24a30a73   Eric Paris   audit: fix event ...
2150
2151
2152
2153
2154
2155
2156
2157
2158
  			 from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
  			 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...
2159
2160
2161
  			 tty ? tty_name(tty) : "(none)",
  			 audit_get_sessionid(tsk));
  	audit_put_tty(tty);
b24a30a73   Eric Paris   audit: fix event ...
2162
  	audit_log_format(ab, " comm=");
9eab339b1   Richard Guy Briggs   audit: get comm u...
2163
  	audit_log_untrustedstring(ab, get_task_comm(comm, tsk));
4766b199e   Davidlohr Bueso   audit: consolidat...
2164
  	audit_log_d_path_exe(ab, tsk->mm);
b24a30a73   Eric Paris   audit: fix event ...
2165
2166
2167
  	audit_log_task_context(ab);
  }
  EXPORT_SYMBOL(audit_log_task_info);
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2168
  /**
a51d9eaa4   Kees Cook   fs: add link rest...
2169
   * audit_log_link_denied - report a link restriction denial
220119647   Shailendra Verma   audit: fix for ty...
2170
   * @operation: specific link operation
a51d9eaa4   Kees Cook   fs: add link rest...
2171
2172
   * @link: the path that triggered the restriction
   */
8bd107633   Al Viro   audit_log_{name,l...
2173
  void audit_log_link_denied(const char *operation, const struct path *link)
a51d9eaa4   Kees Cook   fs: add link rest...
2174
2175
  {
  	struct audit_buffer *ab;
b24a30a73   Eric Paris   audit: fix event ...
2176
2177
2178
2179
2180
  	struct audit_names *name;
  
  	name = kzalloc(sizeof(*name), GFP_NOFS);
  	if (!name)
  		return;
a51d9eaa4   Kees Cook   fs: add link rest...
2181

b24a30a73   Eric Paris   audit: fix event ...
2182
  	/* Generate AUDIT_ANOM_LINK with subject, operation, outcome. */
a51d9eaa4   Kees Cook   fs: add link rest...
2183
2184
  	ab = audit_log_start(current->audit_context, GFP_KERNEL,
  			     AUDIT_ANOM_LINK);
d1c7d97ad   Sasha Levin   fs: handle failed...
2185
  	if (!ab)
b24a30a73   Eric Paris   audit: fix event ...
2186
2187
2188
2189
  		goto out;
  	audit_log_format(ab, "op=%s", operation);
  	audit_log_task_info(ab, current);
  	audit_log_format(ab, " res=0");
a51d9eaa4   Kees Cook   fs: add link rest...
2190
  	audit_log_end(ab);
b24a30a73   Eric Paris   audit: fix event ...
2191
2192
2193
  
  	/* Generate AUDIT_PATH record with object. */
  	name->type = AUDIT_TYPE_NORMAL;
3b362157b   David Howells   VFS: audit: d_bac...
2194
  	audit_copy_inode(name, link->dentry, d_backing_inode(link->dentry));
b24a30a73   Eric Paris   audit: fix event ...
2195
2196
2197
  	audit_log_name(current->audit_context, name, link, 0, NULL);
  out:
  	kfree(name);
a51d9eaa4   Kees Cook   fs: add link rest...
2198
2199
2200
  }
  
  /**
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2201
2202
2203
   * audit_log_end - end one audit record
   * @ab: the audit_buffer
   *
4aa83872d   Paul Moore   audit: queue netl...
2204
2205
2206
2207
   * 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
   * queue and a tasklet is scheduled to remove them from the queue outside the
   * irq context.  May be called in any context.
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2208
   */
b7d112581   David Woodhouse   AUDIT: Send netli...
2209
  void audit_log_end(struct audit_buffer *ab)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2210
  {
5b52330bb   Paul Moore   audit: fix auditd...
2211
2212
  	struct sk_buff *skb;
  	struct nlmsghdr *nlh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2213
2214
  	if (!ab)
  		return;
5b52330bb   Paul Moore   audit: fix auditd...
2215
2216
2217
  
  	if (audit_rate_check()) {
  		skb = ab->skb;
f3d357b09   Eric Paris   Audit: save audit...
2218
  		ab->skb = NULL;
5b52330bb   Paul Moore   audit: fix auditd...
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
  
  		/* 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...
2230
  	audit_buffer_free(ab);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2231
  }
b0dd25a82   Randy Dunlap   [PATCH] AUDIT: ke...
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
  /**
   * 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:...
2244
  void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
2245
  	       const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2246
2247
2248
  {
  	struct audit_buffer *ab;
  	va_list args;
9ad9ad385   David Woodhouse   AUDIT: Wait for b...
2249
  	ab = audit_log_start(ctx, gfp_mask, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2250
2251
2252
2253
2254
2255
2256
  	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...
2257

131ad62d8   Mr Dash Four   netfilter: add SE...
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
  #ifdef CONFIG_SECURITY
  /**
   * audit_log_secctx - Converts and logs SELinux context
   * @ab: audit_buffer
   * @secid: security number
   *
   * This is a helper function that calls security_secid_to_secctx to convert
   * secid to secctx and then adds the (converted) SELinux context to the audit
   * log by calling audit_log_format, thus also preventing leak of internal secid
   * to userspace. If secid cannot be converted audit_panic is called.
   */
  void audit_log_secctx(struct audit_buffer *ab, u32 secid)
  {
  	u32 len;
  	char *secctx;
  
  	if (security_secid_to_secctx(secid, &secctx, &len)) {
  		audit_panic("Cannot convert secid to context");
  	} else {
  		audit_log_format(ab, " obj=%s", secctx);
  		security_release_secctx(secctx, len);
  	}
  }
  EXPORT_SYMBOL(audit_log_secctx);
  #endif
bf45da97a   lorenzo@gnu.org   [PATCH] EXPORT_SY...
2283
2284
2285
2286
  EXPORT_SYMBOL(audit_log_start);
  EXPORT_SYMBOL(audit_log_end);
  EXPORT_SYMBOL(audit_log_format);
  EXPORT_SYMBOL(audit_log);