]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/security/audit/audit_dtrace.c
MFV r348578: 9962 zil_commit should omit cache thrash
[FreeBSD/FreeBSD.git] / sys / security / audit / audit_dtrace.c
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
104 static int      dtaudit_unload(void);
105 static void     dtaudit_getargdesc(void *, dtrace_id_t, void *,
106                     dtrace_argdesc_t *);
107 static void     dtaudit_provide(void *, dtrace_probedesc_t *);
108 static void     dtaudit_destroy(void *, dtrace_id_t, void *);
109 static void     dtaudit_enable(void *, dtrace_id_t, void *);
110 static void     dtaudit_disable(void *, dtrace_id_t, void *);
111 static void     dtaudit_load(void *);
112
113 static 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  */
126 static char     *dtaudit_module_str = "event";
127 static char     *dtaudit_name_commit_str = "commit";
128 static char     *dtaudit_name_bsm_str = "bsm";
129
130 static 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
143 static 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  */
176 static void *
177 dtaudit_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  */
216 static int
217 dtaudit_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  */
261 static void
262 dtaudit_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  */
296 static void
297 dtaudit_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  */
353 static void
354 dtaudit_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
434 static void
435 dtaudit_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
445 static void
446 dtaudit_destroy(void *arg, dtrace_id_t id, void *parg)
447 {
448 }
449
450 static void
451 dtaudit_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
468 static void
469 dtaudit_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
486 static void
487 dtaudit_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
498 static int
499 dtaudit_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
511 static int
512 dtaudit_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
530 SYSINIT(dtaudit_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, dtaudit_load,
531     NULL);
532 SYSUNINIT(dtaudit_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
533     dtaudit_unload, NULL);
534
535 DEV_MODULE(dtaudit, dtaudit_modevent, NULL);
536 MODULE_VERSION(dtaudit, 1);
537 MODULE_DEPEND(dtaudit, dtrace, 1, 1, 1);
538 MODULE_DEPEND(dtaudit, opensolaris, 1, 1, 1);