1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1999-2005 Apple Inc.
5 * Copyright (c) 2016-2017 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * Portions of this software were developed by BAE Systems, the University of
9 * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
10 * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
11 * Computing (TC) research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1.  Redistributions of source code must retain the above copyright
17 *     notice, this list of conditions and the following disclaimer.
18 * 2.  Redistributions in binary form must reproduce the above copyright
19 *     notice, this list of conditions and the following disclaimer in the
20 *     documentation and/or other materials provided with the distribution.
21 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
22 *     its contributors may be used to endorse or promote products derived
23 *     from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41#include <sys/param.h>
42#include <sys/filedesc.h>
43#include <sys/capsicum.h>
44#include <sys/ipc.h>
45#include <sys/mount.h>
46#include <sys/proc.h>
47#include <sys/socket.h>
48#include <sys/socketvar.h>
49#include <sys/protosw.h>
50#include <sys/domain.h>
51#include <sys/sbuf.h>
52#include <sys/systm.h>
53#include <sys/un.h>
54#include <sys/vnode.h>
55
56#include <netinet/in.h>
57#include <netinet/in_pcb.h>
58
59#include <security/audit/audit.h>
60#include <security/audit/audit_private.h>
61
62/*
63 * Calls to manipulate elements of the audit record structure from system
64 * call code.  Macro wrappers will prevent this functions from being entered
65 * if auditing is disabled, avoiding the function call cost.  We check the
66 * thread audit record pointer anyway, as the audit condition could change,
67 * and pre-selection may not have allocated an audit record for this event.
68 *
69 * XXXAUDIT: Should we assert, in each case, that this field of the record
70 * hasn't already been filled in?
71 */
72void
73audit_arg_addr(void *addr)
74{
75	struct kaudit_record *ar;
76
77	ar = currecord();
78	if (ar == NULL)
79		return;
80
81	ar->k_ar.ar_arg_addr = addr;
82	ARG_SET_VALID(ar, ARG_ADDR);
83}
84
85void
86audit_arg_exit(int status, int retval)
87{
88	struct kaudit_record *ar;
89
90	ar = currecord();
91	if (ar == NULL)
92		return;
93
94	ar->k_ar.ar_arg_exitstatus = status;
95	ar->k_ar.ar_arg_exitretval = retval;
96	ARG_SET_VALID(ar, ARG_EXIT);
97}
98
99void
100audit_arg_len(int len)
101{
102	struct kaudit_record *ar;
103
104	ar = currecord();
105	if (ar == NULL)
106		return;
107
108	ar->k_ar.ar_arg_len = len;
109	ARG_SET_VALID(ar, ARG_LEN);
110}
111
112void
113audit_arg_atfd1(int atfd)
114{
115	struct kaudit_record *ar;
116
117	ar = currecord();
118	if (ar == NULL)
119		return;
120
121	ar->k_ar.ar_arg_atfd1 = atfd;
122	ARG_SET_VALID(ar, ARG_ATFD1);
123}
124
125void
126audit_arg_atfd2(int atfd)
127{
128	struct kaudit_record *ar;
129
130	ar = currecord();
131	if (ar == NULL)
132		return;
133
134	ar->k_ar.ar_arg_atfd2 = atfd;
135	ARG_SET_VALID(ar, ARG_ATFD2);
136}
137
138void
139audit_arg_fd(int fd)
140{
141	struct kaudit_record *ar;
142
143	ar = currecord();
144	if (ar == NULL)
145		return;
146
147	ar->k_ar.ar_arg_fd = fd;
148	ARG_SET_VALID(ar, ARG_FD);
149}
150
151void
152audit_arg_fflags(int fflags)
153{
154	struct kaudit_record *ar;
155
156	ar = currecord();
157	if (ar == NULL)
158		return;
159
160	ar->k_ar.ar_arg_fflags = fflags;
161	ARG_SET_VALID(ar, ARG_FFLAGS);
162}
163
164void
165audit_arg_gid(gid_t gid)
166{
167	struct kaudit_record *ar;
168
169	ar = currecord();
170	if (ar == NULL)
171		return;
172
173	ar->k_ar.ar_arg_gid = gid;
174	ARG_SET_VALID(ar, ARG_GID);
175}
176
177void
178audit_arg_uid(uid_t uid)
179{
180	struct kaudit_record *ar;
181
182	ar = currecord();
183	if (ar == NULL)
184		return;
185
186	ar->k_ar.ar_arg_uid = uid;
187	ARG_SET_VALID(ar, ARG_UID);
188}
189
190void
191audit_arg_egid(gid_t egid)
192{
193	struct kaudit_record *ar;
194
195	ar = currecord();
196	if (ar == NULL)
197		return;
198
199	ar->k_ar.ar_arg_egid = egid;
200	ARG_SET_VALID(ar, ARG_EGID);
201}
202
203void
204audit_arg_euid(uid_t euid)
205{
206	struct kaudit_record *ar;
207
208	ar = currecord();
209	if (ar == NULL)
210		return;
211
212	ar->k_ar.ar_arg_euid = euid;
213	ARG_SET_VALID(ar, ARG_EUID);
214}
215
216void
217audit_arg_rgid(gid_t rgid)
218{
219	struct kaudit_record *ar;
220
221	ar = currecord();
222	if (ar == NULL)
223		return;
224
225	ar->k_ar.ar_arg_rgid = rgid;
226	ARG_SET_VALID(ar, ARG_RGID);
227}
228
229void
230audit_arg_ruid(uid_t ruid)
231{
232	struct kaudit_record *ar;
233
234	ar = currecord();
235	if (ar == NULL)
236		return;
237
238	ar->k_ar.ar_arg_ruid = ruid;
239	ARG_SET_VALID(ar, ARG_RUID);
240}
241
242void
243audit_arg_sgid(gid_t sgid)
244{
245	struct kaudit_record *ar;
246
247	ar = currecord();
248	if (ar == NULL)
249		return;
250
251	ar->k_ar.ar_arg_sgid = sgid;
252	ARG_SET_VALID(ar, ARG_SGID);
253}
254
255void
256audit_arg_suid(uid_t suid)
257{
258	struct kaudit_record *ar;
259
260	ar = currecord();
261	if (ar == NULL)
262		return;
263
264	ar->k_ar.ar_arg_suid = suid;
265	ARG_SET_VALID(ar, ARG_SUID);
266}
267
268void
269audit_arg_groupset(gid_t *gidset, u_int gidset_size)
270{
271	u_int i;
272	struct kaudit_record *ar;
273
274	KASSERT(gidset_size <= ngroups_max + 1,
275	    ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)"));
276
277	ar = currecord();
278	if (ar == NULL)
279		return;
280
281	if (ar->k_ar.ar_arg_groups.gidset == NULL)
282		ar->k_ar.ar_arg_groups.gidset = malloc(
283		    sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK);
284
285	for (i = 0; i < gidset_size; i++)
286		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
287	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
288	ARG_SET_VALID(ar, ARG_GROUPSET);
289}
290
291void
292audit_arg_login(char *login)
293{
294	struct kaudit_record *ar;
295
296	ar = currecord();
297	if (ar == NULL)
298		return;
299
300	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
301	ARG_SET_VALID(ar, ARG_LOGIN);
302}
303
304void
305audit_arg_ctlname(int *name, int namelen)
306{
307	struct kaudit_record *ar;
308
309	ar = currecord();
310	if (ar == NULL)
311		return;
312
313	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
314	ar->k_ar.ar_arg_len = namelen;
315	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
316}
317
318void
319audit_arg_mask(int mask)
320{
321	struct kaudit_record *ar;
322
323	ar = currecord();
324	if (ar == NULL)
325		return;
326
327	ar->k_ar.ar_arg_mask = mask;
328	ARG_SET_VALID(ar, ARG_MASK);
329}
330
331void
332audit_arg_mode(mode_t mode)
333{
334	struct kaudit_record *ar;
335
336	ar = currecord();
337	if (ar == NULL)
338		return;
339
340	ar->k_ar.ar_arg_mode = mode;
341	ARG_SET_VALID(ar, ARG_MODE);
342}
343
344void
345audit_arg_dev(int dev)
346{
347	struct kaudit_record *ar;
348
349	ar = currecord();
350	if (ar == NULL)
351		return;
352
353	ar->k_ar.ar_arg_dev = dev;
354	ARG_SET_VALID(ar, ARG_DEV);
355}
356
357void
358audit_arg_value(long value)
359{
360	struct kaudit_record *ar;
361
362	ar = currecord();
363	if (ar == NULL)
364		return;
365
366	ar->k_ar.ar_arg_value = value;
367	ARG_SET_VALID(ar, ARG_VALUE);
368}
369
370void
371audit_arg_owner(uid_t uid, gid_t gid)
372{
373	struct kaudit_record *ar;
374
375	ar = currecord();
376	if (ar == NULL)
377		return;
378
379	ar->k_ar.ar_arg_uid = uid;
380	ar->k_ar.ar_arg_gid = gid;
381	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
382}
383
384void
385audit_arg_pid(pid_t pid)
386{
387	struct kaudit_record *ar;
388
389	ar = currecord();
390	if (ar == NULL)
391		return;
392
393	ar->k_ar.ar_arg_pid = pid;
394	ARG_SET_VALID(ar, ARG_PID);
395}
396
397void
398audit_arg_process(struct proc *p)
399{
400	struct kaudit_record *ar;
401	struct ucred *cred;
402
403	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
404
405	PROC_LOCK_ASSERT(p, MA_OWNED);
406
407	ar = currecord();
408	if (ar == NULL)
409		return;
410
411	cred = p->p_ucred;
412	ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid;
413	ar->k_ar.ar_arg_euid = cred->cr_uid;
414	ar->k_ar.ar_arg_egid = cred->cr_groups[0];
415	ar->k_ar.ar_arg_ruid = cred->cr_ruid;
416	ar->k_ar.ar_arg_rgid = cred->cr_rgid;
417	ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid;
418	ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid;
419	ar->k_ar.ar_arg_pid = p->p_pid;
420	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
421	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
422}
423
424void
425audit_arg_signum(u_int signum)
426{
427	struct kaudit_record *ar;
428
429	ar = currecord();
430	if (ar == NULL)
431		return;
432
433	ar->k_ar.ar_arg_signum = signum;
434	ARG_SET_VALID(ar, ARG_SIGNUM);
435}
436
437void
438audit_arg_socket(int sodomain, int sotype, int soprotocol)
439{
440	struct kaudit_record *ar;
441
442	ar = currecord();
443	if (ar == NULL)
444		return;
445
446	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
447	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
448	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
449	ARG_SET_VALID(ar, ARG_SOCKINFO);
450}
451
452void
453audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa)
454{
455	struct kaudit_record *ar;
456
457	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
458	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
459
460	ar = currecord();
461	if (ar == NULL)
462		return;
463
464	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
465	switch (sa->sa_family) {
466	case AF_INET:
467		ARG_SET_VALID(ar, ARG_SADDRINET);
468		break;
469
470	case AF_INET6:
471		ARG_SET_VALID(ar, ARG_SADDRINET6);
472		break;
473
474	case AF_UNIX:
475		if (dirfd != AT_FDCWD)
476			audit_arg_atfd1(dirfd);
477		audit_arg_upath1(td, dirfd,
478		    ((struct sockaddr_un *)sa)->sun_path);
479		ARG_SET_VALID(ar, ARG_SADDRUNIX);
480		break;
481	/* XXXAUDIT: default:? */
482	}
483}
484
485void
486audit_arg_auid(uid_t auid)
487{
488	struct kaudit_record *ar;
489
490	ar = currecord();
491	if (ar == NULL)
492		return;
493
494	ar->k_ar.ar_arg_auid = auid;
495	ARG_SET_VALID(ar, ARG_AUID);
496}
497
498void
499audit_arg_auditinfo(struct auditinfo *au_info)
500{
501	struct kaudit_record *ar;
502
503	ar = currecord();
504	if (ar == NULL)
505		return;
506
507	ar->k_ar.ar_arg_auid = au_info->ai_auid;
508	ar->k_ar.ar_arg_asid = au_info->ai_asid;
509	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
510	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
511	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
512	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
513	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
514}
515
516void
517audit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
518{
519	struct kaudit_record *ar;
520
521	ar = currecord();
522	if (ar == NULL)
523		return;
524
525	ar->k_ar.ar_arg_auid = au_info->ai_auid;
526	ar->k_ar.ar_arg_asid = au_info->ai_asid;
527	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
528	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
529	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
530	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
531	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
532	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
533	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
534	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
535	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
536}
537
538void
539audit_arg_text(const char *text)
540{
541	struct kaudit_record *ar;
542
543	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
544
545	ar = currecord();
546	if (ar == NULL)
547		return;
548
549	/* Invalidate the text string */
550	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
551
552	if (ar->k_ar.ar_arg_text == NULL)
553		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
554		    M_WAITOK);
555
556	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
557	ARG_SET_VALID(ar, ARG_TEXT);
558}
559
560void
561audit_arg_cmd(int cmd)
562{
563	struct kaudit_record *ar;
564
565	ar = currecord();
566	if (ar == NULL)
567		return;
568
569	ar->k_ar.ar_arg_cmd = cmd;
570	ARG_SET_VALID(ar, ARG_CMD);
571}
572
573void
574audit_arg_svipc_cmd(int cmd)
575{
576	struct kaudit_record *ar;
577
578	ar = currecord();
579	if (ar == NULL)
580		return;
581
582	ar->k_ar.ar_arg_svipc_cmd = cmd;
583	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
584}
585
586void
587audit_arg_svipc_perm(struct ipc_perm *perm)
588{
589	struct kaudit_record *ar;
590
591	ar = currecord();
592	if (ar == NULL)
593		return;
594
595	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
596	    sizeof(ar->k_ar.ar_arg_svipc_perm));
597	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
598}
599
600void
601audit_arg_svipc_id(int id)
602{
603	struct kaudit_record *ar;
604
605	ar = currecord();
606	if (ar == NULL)
607		return;
608
609	ar->k_ar.ar_arg_svipc_id = id;
610	ARG_SET_VALID(ar, ARG_SVIPC_ID);
611}
612
613void
614audit_arg_svipc_addr(void * addr)
615{
616	struct kaudit_record *ar;
617
618	ar = currecord();
619	if (ar == NULL)
620		return;
621
622	ar->k_ar.ar_arg_svipc_addr = addr;
623	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
624}
625
626void
627audit_arg_svipc_which(int which)
628{
629	struct kaudit_record *ar;
630
631	ar = currecord();
632	if (ar == NULL)
633		return;
634
635	ar->k_ar.ar_arg_svipc_which = which;
636	ARG_SET_VALID(ar, ARG_SVIPC_WHICH);
637}
638
639void
640audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
641{
642	struct kaudit_record *ar;
643
644	ar = currecord();
645	if (ar == NULL)
646		return;
647
648	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
649	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
650	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
651	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
652}
653
654void
655audit_arg_auditon(union auditon_udata *udata)
656{
657	struct kaudit_record *ar;
658
659	ar = currecord();
660	if (ar == NULL)
661		return;
662
663	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
664	    sizeof(ar->k_ar.ar_arg_auditon));
665	ARG_SET_VALID(ar, ARG_AUDITON);
666}
667
668/*
669 * Audit information about a file, either the file's vnode info, or its
670 * socket address info.
671 */
672void
673audit_arg_file(struct proc *p, struct file *fp)
674{
675	struct kaudit_record *ar;
676	struct socket *so;
677	struct inpcb *pcb;
678	struct vnode *vp;
679
680	ar = currecord();
681	if (ar == NULL)
682		return;
683
684	switch (fp->f_type) {
685	case DTYPE_VNODE:
686	case DTYPE_FIFO:
687		/*
688		 * XXXAUDIT: Only possibly to record as first vnode?
689		 */
690		vp = fp->f_vnode;
691		vn_lock(vp, LK_SHARED | LK_RETRY);
692		audit_arg_vnode1(vp);
693		VOP_UNLOCK(vp);
694		break;
695
696	case DTYPE_SOCKET:
697		so = (struct socket *)fp->f_data;
698		if (INP_CHECK_SOCKAF(so, PF_INET)) {
699			SOCK_LOCK(so);
700			ar->k_ar.ar_arg_sockinfo.so_type =
701			    so->so_type;
702			ar->k_ar.ar_arg_sockinfo.so_domain =
703			    INP_SOCKAF(so);
704			ar->k_ar.ar_arg_sockinfo.so_protocol =
705			    so->so_proto->pr_protocol;
706			SOCK_UNLOCK(so);
707			pcb = (struct inpcb *)so->so_pcb;
708			INP_RLOCK(pcb);
709			ar->k_ar.ar_arg_sockinfo.so_raddr =
710			    pcb->inp_faddr.s_addr;
711			ar->k_ar.ar_arg_sockinfo.so_laddr =
712			    pcb->inp_laddr.s_addr;
713			ar->k_ar.ar_arg_sockinfo.so_rport =
714			    pcb->inp_fport;
715			ar->k_ar.ar_arg_sockinfo.so_lport =
716			    pcb->inp_lport;
717			INP_RUNLOCK(pcb);
718			ARG_SET_VALID(ar, ARG_SOCKINFO);
719		}
720		break;
721
722	default:
723		/* XXXAUDIT: else? */
724		break;
725	}
726}
727
728/*
729 * Store a path as given by the user process for auditing into the audit
730 * record stored on the user thread.  This function will allocate the memory
731 * to store the path info if not already available.  This memory will be
732 * freed when the audit record is freed.  The path is canonlicalised with
733 * respect to the thread and directory descriptor passed.
734 */
735static void
736audit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp)
737{
738
739	if (*pathp == NULL)
740		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
741	audit_canon_path(td, dirfd, upath, *pathp);
742}
743
744void
745audit_arg_upath1(struct thread *td, int dirfd, char *upath)
746{
747	struct kaudit_record *ar;
748
749	ar = currecord();
750	if (ar == NULL)
751		return;
752
753	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1);
754	ARG_SET_VALID(ar, ARG_UPATH1);
755}
756
757void
758audit_arg_upath2(struct thread *td, int dirfd, char *upath)
759{
760	struct kaudit_record *ar;
761
762	ar = currecord();
763	if (ar == NULL)
764		return;
765
766	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2);
767	ARG_SET_VALID(ar, ARG_UPATH2);
768}
769
770static void
771audit_arg_upath_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
772    char *upath, char **pathp)
773{
774
775	if (*pathp == NULL)
776		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
777	audit_canon_path_vp(td, rdir, cdir, upath, *pathp);
778}
779
780void
781audit_arg_upath1_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
782    char *upath)
783{
784	struct kaudit_record *ar;
785
786	ar = currecord();
787	if (ar == NULL)
788		return;
789
790	audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath1);
791	ARG_SET_VALID(ar, ARG_UPATH1);
792}
793
794void
795audit_arg_upath2_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
796    char *upath)
797{
798	struct kaudit_record *ar;
799
800	ar = currecord();
801	if (ar == NULL)
802		return;
803
804	audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath2);
805	ARG_SET_VALID(ar, ARG_UPATH2);
806}
807
808/*
809 * Variants on path auditing that do not canonicalise the path passed in;
810 * these are for use with filesystem-like subsystems that employ string names,
811 * but do not support a hierarchical namespace -- for example, POSIX IPC
812 * objects.  The subsystem should have performed any necessary
813 * canonicalisation required to make the paths useful to audit analysis.
814 */
815static void
816audit_arg_upath_canon(char *upath, char **pathp)
817{
818
819	if (*pathp == NULL)
820		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
821	(void)snprintf(*pathp, MAXPATHLEN, "%s", upath);
822}
823
824void
825audit_arg_upath1_canon(char *upath)
826{
827	struct kaudit_record *ar;
828
829	ar = currecord();
830	if (ar == NULL)
831		return;
832
833	audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath1);
834	ARG_SET_VALID(ar, ARG_UPATH1);
835}
836
837void
838audit_arg_upath2_canon(char *upath)
839{
840	struct kaudit_record *ar;
841
842	ar = currecord();
843	if (ar == NULL)
844		return;
845
846	audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath2);
847	ARG_SET_VALID(ar, ARG_UPATH2);
848}
849
850/*
851 * Function to save the path and vnode attr information into the audit
852 * record.
853 *
854 * It is assumed that the caller will hold any vnode locks necessary to
855 * perform a VOP_GETATTR() on the passed vnode.
856 *
857 * XXX: The attr code is very similar to vfs_default.c:vop_stdstat(), but always
858 * provides access to the generation number as we need that to construct the
859 * BSM file ID.
860 *
861 * XXX: We should accept the process argument from the caller, since it's
862 * very likely they already have a reference.
863 *
864 * XXX: Error handling in this function is poor.
865 *
866 * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
867 */
868static int
869audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp)
870{
871	struct vattr vattr;
872	int error;
873
874	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
875
876	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
877	if (error) {
878		/* XXX: How to handle this case? */
879		return (error);
880	}
881
882	vnp->vn_mode = vattr.va_mode;
883	vnp->vn_uid = vattr.va_uid;
884	vnp->vn_gid = vattr.va_gid;
885	vnp->vn_dev = vattr.va_rdev;
886	vnp->vn_fsid = vattr.va_fsid;
887	vnp->vn_fileid = vattr.va_fileid;
888	vnp->vn_gen = vattr.va_gen;
889	return (0);
890}
891
892void
893audit_arg_vnode1(struct vnode *vp)
894{
895	struct kaudit_record *ar;
896	int error;
897
898	ar = currecord();
899	if (ar == NULL)
900		return;
901
902	ARG_CLEAR_VALID(ar, ARG_VNODE1);
903	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1);
904	if (error == 0)
905		ARG_SET_VALID(ar, ARG_VNODE1);
906}
907
908void
909audit_arg_vnode2(struct vnode *vp)
910{
911	struct kaudit_record *ar;
912	int error;
913
914	ar = currecord();
915	if (ar == NULL)
916		return;
917
918	ARG_CLEAR_VALID(ar, ARG_VNODE2);
919	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2);
920	if (error == 0)
921		ARG_SET_VALID(ar, ARG_VNODE2);
922}
923
924/*
925 * Audit the argument strings passed to exec.
926 */
927void
928audit_arg_argv(char *argv, int argc, int length)
929{
930	struct kaudit_record *ar;
931
932	if (audit_argv == 0)
933		return;
934
935	ar = currecord();
936	if (ar == NULL)
937		return;
938
939	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
940	bcopy(argv, ar->k_ar.ar_arg_argv, length);
941	ar->k_ar.ar_arg_argc = argc;
942	ARG_SET_VALID(ar, ARG_ARGV);
943}
944
945/*
946 * Audit the environment strings passed to exec.
947 */
948void
949audit_arg_envv(char *envv, int envc, int length)
950{
951	struct kaudit_record *ar;
952
953	if (audit_arge == 0)
954		return;
955
956	ar = currecord();
957	if (ar == NULL)
958		return;
959
960	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
961	bcopy(envv, ar->k_ar.ar_arg_envv, length);
962	ar->k_ar.ar_arg_envc = envc;
963	ARG_SET_VALID(ar, ARG_ENVV);
964}
965
966void
967audit_arg_rights(cap_rights_t *rightsp)
968{
969	struct kaudit_record *ar;
970
971	ar = currecord();
972	if (ar == NULL)
973		return;
974
975	ar->k_ar.ar_arg_rights = *rightsp;
976	ARG_SET_VALID(ar, ARG_RIGHTS);
977}
978
979void
980audit_arg_fcntl_rights(uint32_t fcntlrights)
981{
982	struct kaudit_record *ar;
983
984	ar = currecord();
985	if (ar == NULL)
986		return;
987
988	ar->k_ar.ar_arg_fcntl_rights = fcntlrights;
989	ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS);
990}
991
992/*
993 * The close() system call uses it's own audit call to capture the path/vnode
994 * information because those pieces are not easily obtained within the system
995 * call itself.
996 */
997void
998audit_sysclose(struct thread *td, int fd, struct file *fp)
999{
1000	struct kaudit_record *ar;
1001	struct vnode *vp;
1002
1003	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
1004
1005	ar = currecord();
1006	if (ar == NULL)
1007		return;
1008
1009	audit_arg_fd(fd);
1010
1011	vp = fp->f_vnode;
1012	if (vp == NULL)
1013		return;
1014	vn_lock(vp, LK_SHARED | LK_RETRY);
1015	audit_arg_vnode1(vp);
1016	VOP_UNLOCK(vp);
1017}
1018