1/*-
2 * Copyright (c) 2016, 2018 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * This software was developed by BAE Systems, the University of Cambridge
6 * Computer Laboratory, and Memorial University under DARPA/AFRL contract
7 * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing
8 * (TC) research program.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD$");
34
35#include <sys/param.h>
36#include <sys/conf.h>
37#include <sys/ctype.h>
38#include <sys/kernel.h>
39#include <sys/malloc.h>
40#include <sys/module.h>
41#include <sys/queue.h>
42#include <sys/refcount.h>
43
44#include <sys/dtrace.h>
45#include <sys/dtrace_bsd.h>
46
47#include <bsm/audit.h>
48#include <bsm/audit_internal.h>
49#include <bsm/audit_kevents.h>
50
51#include <security/audit/audit.h>
52#include <security/audit/audit_private.h>
53
54/*-
55 * Audit DTrace provider: allow DTrace to request that audit records be
56 * generated for various audit events, and then expose those records (in
57 * various forms) to probes.  The model is that each event type has two
58 * probes, which use the event's name to create the probe:
59 *
60 * - "commit" passes the kernel-internal (unserialised) kaudit_record
61 *   synchronously (from the originating thread) of the record as we prepare
62 *   to "commit" the record to the audit queue.
63 *
64 * - "bsm" also passes generated BSM, and executes asynchronously in the audit
65 *   worker thread, once it has been extracted from the audit queue.  This is
66 *   the point at which an audit record would be enqueued to the trail on
67 *   disk, or to pipes.
68 *
69 * These probes support very different goals.  The former executes in the
70 * thread originating the record, making it easier to correlate other DTrace
71 * probe activity with the event described in the record.  The latter gives
72 * access to BSM-formatted events (at a cost) allowing DTrace to extract BSM
73 * directly an alternative mechanism to the formal audit trail and audit
74 * pipes.
75 *
76 * To generate names for numeric event IDs, userspace will push the contents
77 * of /etc/security/audit_event into the kernel during audit setup, much as it
78 * does /etc/security/audit_class.  We then create the probes for each of
79 * those mappings.  If one (or both) of the probes are enabled, then we cause
80 * a record to be generated (as both normal audit preselection and audit pipes
81 * do), and catch it on the way out during commit.  There are suitable hook
82 * functions in the audit code that this provider can register to catch
83 * various events in the audit-record life cycle.
84 *
85 * Further ponderings:
86 *
87 * - How do we want to handle events for which there are not names -- perhaps
88 *   a catch-all probe for those events without mappings?
89 *
90 * - Should the evname code really be present even if DTrace isn't loaded...?
91 *   Right now, we arrange that it is so that userspace can usefully maintain
92 *   the list in case DTrace is later loaded (and to prevent userspace
93 *   confusion).
94 *
95 * - Should we add an additional set of audit:class::commit probes that use
96 *   event class names to match broader categories of events as specified in
97 *   /etc/security/event_class?
98 *
99 * - If we pursue that last point, we will want to pass the name of the event
100 *   into the probe explicitly (e.g., as arg0), since it would no longer be
101 *   available as the probe function name.
102 */
103
104static int	dtaudit_unload(void);
105static void	dtaudit_getargdesc(void *, dtrace_id_t, void *,
106		    dtrace_argdesc_t *);
107static void	dtaudit_provide(void *, dtrace_probedesc_t *);
108static void	dtaudit_destroy(void *, dtrace_id_t, void *);
109static void	dtaudit_enable(void *, dtrace_id_t, void *);
110static void	dtaudit_disable(void *, dtrace_id_t, void *);
111static void	dtaudit_load(void *);
112
113static dtrace_pattr_t dtaudit_attr = {
114{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
115{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
116{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
117{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
118{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
119};
120
121/*
122 * Strings for the "module" and "name" portions of the probe.  The name of the
123 * audit event will be the "function" portion of the probe.  All dtaudit
124 * probes therefore take the form audit:event:<event name>:commit.
125 */
126static char	*dtaudit_module_str = "event";
127static char	*dtaudit_name_commit_str = "commit";
128static char	*dtaudit_name_bsm_str = "bsm";
129
130static dtrace_pops_t dtaudit_pops = {
131	.dtps_provide =		dtaudit_provide,
132	.dtps_provide_module =	NULL,
133	.dtps_enable =		dtaudit_enable,
134	.dtps_disable =		dtaudit_disable,
135	.dtps_suspend =		NULL,
136	.dtps_resume =		NULL,
137	.dtps_getargdesc =	dtaudit_getargdesc,
138	.dtps_getargval =	NULL,
139	.dtps_usermode =	NULL,
140	.dtps_destroy =		dtaudit_destroy
141};
142
143static dtrace_provider_id_t	dtaudit_id;
144
145/*
146 * Because looking up entries in the event-to-name mapping is quite expensive,
147 * maintain a global flag tracking whether any dtaudit probes are enabled.  If
148 * not, don't bother doing all that work whenever potential queries about
149 * events turn up during preselection or commit.
150 *
151 * NB: We used to maintain our own variable in dtaudit, but now use the
152 * centralized audit_dtrace_enabled variable imported from the audit code.
153 *
154 * static uint_t		dtaudit_probes_enabled;
155 */
156
157/*
158 * Check dtaudit policy for the event to see whether this is an event we would
159 * like to preselect (i.e., cause an audit record to be generated for).  To
160 * minimise probe effect when not used at all, we not only check for the probe
161 * on the individual event, but also a global flag indicating that at least
162 * one probe is enabled, before acquiring locks, searching lists, etc.
163 *
164 * If the event is selected, return an evname_elem reference to be stored in
165 * the audit record, which we can use later to avoid further lookups.  The
166 * contents of the evname_elem must be sufficiently stable so as to not risk
167 * race conditions here.
168 *
169 * Currently, we take an interest only in the 'event' argument, but in the
170 * future might want to support other types of record selection tied to
171 * additional probe types (e.g., event clases).
172 *
173 * XXXRW: Should we have a catch-all probe here for events without registered
174 * names?
175 */
176static void *
177dtaudit_preselect(au_id_t auid, au_event_t event, au_class_t class)
178{
179	struct evname_elem *ene;
180	int probe_enabled;
181
182	/*
183	 * NB: Lockless reads here may return a slightly stale value; this is
184	 * considered better than acquiring a lock, however.
185	 */
186	if (!audit_dtrace_enabled)
187		return (NULL);
188	ene = au_evnamemap_lookup(event);
189	if (ene == NULL)
190		return (NULL);
191
192	/*
193	 * See if either of the two probes for the audit event are enabled.
194	 *
195	 * NB: Lock also not acquired here -- but perhaps it wouldn't matter
196	 * given that we've already used the list lock above?
197	 *
198	 * XXXRW: Alternatively, au_evnamemap_lookup() could return these
199	 * values while holding the list lock...?
200	 */
201	probe_enabled = ene->ene_commit_probe_enabled ||
202	    ene->ene_bsm_probe_enabled;
203	if (!probe_enabled)
204		return (NULL);
205	return ((void *)ene);
206}
207
208/*
209 * Commit probe pre-BSM.  Fires the probe but also checks to see if we should
210 * ask the audit framework to call us again with BSM arguments in the audit
211 * worker thread.
212 *
213 * XXXRW: Should we have a catch-all probe here for events without registered
214 * names?
215 */
216static int
217dtaudit_commit(struct kaudit_record *kar, au_id_t auid, au_event_t event,
218    au_class_t class, int sorf)
219{
220	char ene_name_lower[EVNAMEMAP_NAME_SIZE];
221	struct evname_elem *ene;
222	int i;
223
224	ene = (struct evname_elem *)kar->k_dtaudit_state;
225	if (ene == NULL)
226		return (0);
227
228	/*
229	 * Process a possibly registered commit probe.
230	 */
231	if (ene->ene_commit_probe_enabled) {
232		/*
233		 * XXXRW: Lock ene to provide stability to the name string.  A
234		 * bit undesirable!  We may want another locking strategy
235		 * here.  At least we don't run the DTrace probe under the
236		 * lock.
237		 *
238		 * XXXRW: We provide the struct audit_record pointer -- but
239		 * perhaps should provide the kaudit_record pointer?
240		 */
241		EVNAME_LOCK(ene);
242		for (i = 0; i < sizeof(ene_name_lower); i++)
243			ene_name_lower[i] = tolower(ene->ene_name[i]);
244		EVNAME_UNLOCK(ene);
245		dtrace_probe(ene->ene_commit_probe_id,
246		    (uintptr_t)ene_name_lower, (uintptr_t)&kar->k_ar, 0, 0, 0);
247	}
248
249	/*
250	 * Return the state of the BSM probe to the caller.
251	 */
252	return (ene->ene_bsm_probe_enabled);
253}
254
255/*
256 * Commit probe post-BSM.
257 *
258 * XXXRW: Should we have a catch-all probe here for events without registered
259 * names?
260 */
261static void
262dtaudit_bsm(struct kaudit_record *kar, au_id_t auid, au_event_t event,
263    au_class_t class, int sorf, void *bsm_data, size_t bsm_len)
264{
265	char ene_name_lower[EVNAMEMAP_NAME_SIZE];
266	struct evname_elem *ene;
267	int i;
268
269	ene = (struct evname_elem *)kar->k_dtaudit_state;
270	if (ene == NULL)
271		return;
272	if (!(ene->ene_bsm_probe_enabled))
273		return;
274
275	/*
276	 * XXXRW: Lock ene to provide stability to the name string.  A bit
277	 * undesirable!  We may want another locking strategy here.  At least
278	 * we don't run the DTrace probe under the lock.
279	 *
280	 * XXXRW: We provide the struct audit_record pointer -- but perhaps
281	 * should provide the kaudit_record pointer?
282	 */
283	EVNAME_LOCK(ene);
284	for (i = 0; i < sizeof(ene_name_lower); i++)
285		ene_name_lower[i] = tolower(ene->ene_name[i]);
286	EVNAME_UNLOCK(ene);
287	dtrace_probe(ene->ene_bsm_probe_id, (uintptr_t)ene_name_lower,
288	    (uintptr_t)&kar->k_ar, (uintptr_t)bsm_data, (uintptr_t)bsm_len,
289	    0);
290}
291
292/*
293 * A very simple provider: argument types are identical across all probes: the
294 * kaudit_record, plus a BSM pointer and length.
295 */
296static void
297dtaudit_getargdesc(void *arg, dtrace_id_t id, void *parg,
298    dtrace_argdesc_t *desc)
299{
300	struct evname_elem *ene;
301	const char *p;
302
303	ene = (struct evname_elem *)parg;
304	p = NULL;
305	switch (desc->dtargd_ndx) {
306	case 0:
307		/* Audit event name. */
308		p = "char *";
309		break;
310
311	case 1:
312		/* In-kernel audit record. */
313		p = "struct audit_record *";
314		break;
315
316	case 2:
317		/* BSM data, if present. */
318		if (id == ene->ene_bsm_probe_id)
319			p = "const void *";
320		else
321			desc->dtargd_ndx = DTRACE_ARGNONE;
322		break;
323
324	case 3:
325		/* BSM length, if present. */
326		if (id == ene->ene_bsm_probe_id)
327			p = "size_t";
328		else
329			desc->dtargd_ndx = DTRACE_ARGNONE;
330		break;
331
332	default:
333		desc->dtargd_ndx = DTRACE_ARGNONE;
334		break;
335	}
336	if (p != NULL)
337		strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
338}
339
340/*
341 * Callback from the event-to-name mapping code when performing
342 * evname_foreach().  Note that we may update the entry, so the foreach code
343 * must have a write lock.  However, as the synchronisation model is private
344 * to the evname code, we cannot easily assert it here.
345 *
346 * XXXRW: How do we want to handle event rename / collision issues here --
347 * e.g., if userspace was using a name to point to one event number, and then
348 * changes it so that the name points at another?  For now, paper over this by
349 * skipping event numbers that are already registered, and likewise skipping
350 * names that are already registered.  However, this could lead to confusing
351 * behaviour so possibly needs to be resolved in the longer term.
352 */
353static void
354dtaudit_au_evnamemap_callback(struct evname_elem *ene)
355{
356	char ene_name_lower[EVNAMEMAP_NAME_SIZE];
357	int i;
358
359	/*
360	 * DTrace, by convention, has lower-case probe names.  However, the
361	 * in-kernel event-to-name mapping table must maintain event-name case
362	 * as submitted by userspace.  Create a temporary lower-case version
363	 * here, away from the fast path, to use when exposing the event name
364	 * to DTrace as part of the name of a probe.
365	 *
366	 * NB: Convert the entire array, including the terminating nul,
367	 * because these strings are short and it's more work not to.  If they
368	 * become long, we might feel more guilty about this sloppiness!
369	 */
370	for (i = 0; i < sizeof(ene_name_lower); i++)
371		ene_name_lower[i] = tolower(ene->ene_name[i]);
372
373	/*
374	 * Don't register a new probe if this event number already has an
375	 * associated commit probe -- or if another event has already
376	 * registered this name.
377	 *
378	 * XXXRW: There is an argument that if multiple numeric events match
379	 * a single name, they should all be exposed to the same named probe.
380	 * In particular, we should perhaps use a probe ID returned by this
381	 * lookup and just stick that in the saved probe ID?
382	 */
383	if ((ene->ene_commit_probe_id == 0) &&
384	    (dtrace_probe_lookup(dtaudit_id, dtaudit_module_str,
385	    ene_name_lower, dtaudit_name_commit_str) == 0)) {
386
387		/*
388		 * Create the commit probe.
389		 *
390		 * NB: We don't declare any extra stack frames because stack()
391		 * will just return the path to the audit commit code, which
392		 * is not really interesting anyway.
393		 *
394		 * We pass in the pointer to the evnam_elem entry so that we
395		 * can easily change its enabled flag in the probe
396		 * enable/disable interface.
397		 */
398		ene->ene_commit_probe_id = dtrace_probe_create(dtaudit_id,
399		    dtaudit_module_str, ene_name_lower,
400		    dtaudit_name_commit_str, 0, ene);
401	}
402
403	/*
404	 * Don't register a new probe if this event number already has an
405	 * associated bsm probe -- or if another event has already
406	 * registered this name.
407	 *
408	 * XXXRW: There is an argument that if multiple numeric events match
409	 * a single name, they should all be exposed to the same named probe.
410	 * In particular, we should perhaps use a probe ID returned by this
411	 * lookup and just stick that in the saved probe ID?
412	 */
413	if ((ene->ene_bsm_probe_id == 0) &&
414	    (dtrace_probe_lookup(dtaudit_id, dtaudit_module_str,
415	    ene_name_lower, dtaudit_name_bsm_str) == 0)) {
416
417		/*
418		 * Create the bsm probe.
419		 *
420		 * NB: We don't declare any extra stack frames because stack()
421		 * will just return the path to the audit commit code, which
422		 * is not really interesting anyway.
423		 *
424		 * We pass in the pointer to the evnam_elem entry so that we
425		 * can easily change its enabled flag in the probe
426		 * enable/disable interface.
427		 */
428		ene->ene_bsm_probe_id = dtrace_probe_create(dtaudit_id,
429		    dtaudit_module_str, ene_name_lower, dtaudit_name_bsm_str,
430		    0, ene);
431	}
432}
433
434static void
435dtaudit_provide(void *arg, dtrace_probedesc_t *desc)
436{
437
438	/*
439	 * Walk all registered number-to-name mapping entries, and ensure each
440	 * is properly registered.
441	 */
442	au_evnamemap_foreach(dtaudit_au_evnamemap_callback);
443}
444
445static void
446dtaudit_destroy(void *arg, dtrace_id_t id, void *parg)
447{
448}
449
450static void
451dtaudit_enable(void *arg, dtrace_id_t id, void *parg)
452{
453	struct evname_elem *ene;
454
455	ene = parg;
456	KASSERT(ene->ene_commit_probe_id == id || ene->ene_bsm_probe_id == id,
457	    ("%s: probe ID mismatch (%u, %u != %u)", __func__,
458	    ene->ene_commit_probe_id, ene->ene_bsm_probe_id, id));
459
460	if (id == ene->ene_commit_probe_id)
461		ene->ene_commit_probe_enabled = 1;
462	else
463		ene->ene_bsm_probe_enabled = 1;
464	refcount_acquire(&audit_dtrace_enabled);
465	audit_syscalls_enabled_update();
466}
467
468static void
469dtaudit_disable(void *arg, dtrace_id_t id, void *parg)
470{
471	struct evname_elem *ene;
472
473	ene = parg;
474	KASSERT(ene->ene_commit_probe_id == id || ene->ene_bsm_probe_id == id,
475	    ("%s: probe ID mismatch (%u, %u != %u)", __func__,
476	    ene->ene_commit_probe_id, ene->ene_bsm_probe_id, id));
477
478	if (id == ene->ene_commit_probe_id)
479		ene->ene_commit_probe_enabled = 0;
480	else
481		ene->ene_bsm_probe_enabled = 0;
482	(void)refcount_release(&audit_dtrace_enabled);
483	audit_syscalls_enabled_update();
484}
485
486static void
487dtaudit_load(void *dummy)
488{
489
490	if (dtrace_register("audit", &dtaudit_attr, DTRACE_PRIV_USER, NULL,
491	    &dtaudit_pops, NULL, &dtaudit_id) != 0)
492		return;
493	dtaudit_hook_preselect = dtaudit_preselect;
494	dtaudit_hook_commit = dtaudit_commit;
495	dtaudit_hook_bsm = dtaudit_bsm;
496}
497
498static int
499dtaudit_unload(void)
500{
501	int error;
502
503	dtaudit_hook_preselect = NULL;
504	dtaudit_hook_commit = NULL;
505	dtaudit_hook_bsm = NULL;
506	if ((error = dtrace_unregister(dtaudit_id)) != 0)
507		return (error);
508	return (0);
509}
510
511static int
512dtaudit_modevent(module_t mod __unused, int type, void *data __unused)
513{
514	int error = 0;
515
516	switch (type) {
517	case MOD_LOAD:
518	case MOD_UNLOAD:
519	case MOD_SHUTDOWN:
520		break;
521
522	default:
523		error = EOPNOTSUPP;
524		break;
525	}
526
527	return (error);
528}
529
530SYSINIT(dtaudit_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, dtaudit_load,
531    NULL);
532SYSUNINIT(dtaudit_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
533    dtaudit_unload, NULL);
534
535DEV_MODULE(dtaudit, dtaudit_modevent, NULL);
536MODULE_VERSION(dtaudit, 1);
537MODULE_DEPEND(dtaudit, dtrace, 1, 1, 1);
538MODULE_DEPEND(dtaudit, opensolaris, 1, 1, 1);
539