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