audit_arg.c revision 195925
1181053Srwatson/*-
2180701Srwatson * Copyright (c) 1999-2005 Apple Inc.
3155192Srwatson * All rights reserved.
4155192Srwatson *
5155192Srwatson * Redistribution and use in source and binary forms, with or without
6155192Srwatson * modification, are permitted provided that the following conditions
7155192Srwatson * are met:
8155192Srwatson * 1.  Redistributions of source code must retain the above copyright
9155192Srwatson *     notice, this list of conditions and the following disclaimer.
10155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
11155192Srwatson *     notice, this list of conditions and the following disclaimer in the
12155192Srwatson *     documentation and/or other materials provided with the distribution.
13180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14155192Srwatson *     its contributors may be used to endorse or promote products derived
15155192Srwatson *     from this software without specific prior written permission.
16155192Srwatson *
17155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
28155192Srwatson */
29155192Srwatson
30178186Srwatson#include <sys/cdefs.h>
31178186Srwatson__FBSDID("$FreeBSD: head/sys/security/audit/audit_arg.c 195925 2009-07-28 21:39:58Z rwatson $");
32178186Srwatson
33155192Srwatson#include <sys/param.h>
34155192Srwatson#include <sys/filedesc.h>
35155192Srwatson#include <sys/ipc.h>
36155192Srwatson#include <sys/mount.h>
37155192Srwatson#include <sys/proc.h>
38155192Srwatson#include <sys/socket.h>
39155192Srwatson#include <sys/socketvar.h>
40155192Srwatson#include <sys/protosw.h>
41155192Srwatson#include <sys/domain.h>
42159277Srwatson#include <sys/sbuf.h>
43155192Srwatson#include <sys/systm.h>
44155192Srwatson#include <sys/un.h>
45155192Srwatson#include <sys/vnode.h>
46155192Srwatson
47155192Srwatson#include <netinet/in.h>
48155192Srwatson#include <netinet/in_pcb.h>
49155192Srwatson
50155192Srwatson#include <security/audit/audit.h>
51155192Srwatson#include <security/audit/audit_private.h>
52155192Srwatson
53155192Srwatson/*
54155192Srwatson * Calls to manipulate elements of the audit record structure from system
55170196Srwatson * call code.  Macro wrappers will prevent this functions from being entered
56170196Srwatson * if auditing is disabled, avoiding the function call cost.  We check the
57170196Srwatson * thread audit record pointer anyway, as the audit condition could change,
58170196Srwatson * and pre-selection may not have allocated an audit record for this event.
59155192Srwatson *
60155192Srwatson * XXXAUDIT: Should we assert, in each case, that this field of the record
61155192Srwatson * hasn't already been filled in?
62155192Srwatson */
63155192Srwatsonvoid
64170585Srwatsonaudit_arg_addr(void *addr)
65155192Srwatson{
66155192Srwatson	struct kaudit_record *ar;
67155192Srwatson
68155192Srwatson	ar = currecord();
69155192Srwatson	if (ar == NULL)
70155192Srwatson		return;
71155192Srwatson
72155192Srwatson	ar->k_ar.ar_arg_addr = addr;
73155192Srwatson	ARG_SET_VALID(ar, ARG_ADDR);
74155192Srwatson}
75155192Srwatson
76155192Srwatsonvoid
77155192Srwatsonaudit_arg_exit(int status, int retval)
78155192Srwatson{
79155192Srwatson	struct kaudit_record *ar;
80155192Srwatson
81155192Srwatson	ar = currecord();
82155192Srwatson	if (ar == NULL)
83155192Srwatson		return;
84155192Srwatson
85155192Srwatson	ar->k_ar.ar_arg_exitstatus = status;
86155192Srwatson	ar->k_ar.ar_arg_exitretval = retval;
87155192Srwatson	ARG_SET_VALID(ar, ARG_EXIT);
88155192Srwatson}
89155192Srwatson
90155192Srwatsonvoid
91155192Srwatsonaudit_arg_len(int len)
92155192Srwatson{
93155192Srwatson	struct kaudit_record *ar;
94155192Srwatson
95155192Srwatson	ar = currecord();
96155192Srwatson	if (ar == NULL)
97155192Srwatson		return;
98155192Srwatson
99155192Srwatson	ar->k_ar.ar_arg_len = len;
100155192Srwatson	ARG_SET_VALID(ar, ARG_LEN);
101155192Srwatson}
102155192Srwatson
103155192Srwatsonvoid
104195925Srwatsonaudit_arg_atfd1(int atfd)
105195925Srwatson{
106195925Srwatson	struct kaudit_record *ar;
107195925Srwatson
108195925Srwatson	ar = currecord();
109195925Srwatson	if (ar == NULL)
110195925Srwatson		return;
111195925Srwatson
112195925Srwatson	ar->k_ar.ar_arg_atfd1 = atfd;
113195925Srwatson	ARG_SET_VALID(ar, ARG_ATFD1);
114195925Srwatson}
115195925Srwatson
116195925Srwatsonvoid
117195925Srwatsonaudit_arg_atfd2(int atfd)
118195925Srwatson{
119195925Srwatson	struct kaudit_record *ar;
120195925Srwatson
121195925Srwatson	ar = currecord();
122195925Srwatson	if (ar == NULL)
123195925Srwatson		return;
124195925Srwatson
125195925Srwatson	ar->k_ar.ar_arg_atfd2 = atfd;
126195925Srwatson	ARG_SET_VALID(ar, ARG_ATFD2);
127195925Srwatson}
128195925Srwatson
129195925Srwatsonvoid
130155192Srwatsonaudit_arg_fd(int fd)
131155192Srwatson{
132155192Srwatson	struct kaudit_record *ar;
133155192Srwatson
134155192Srwatson	ar = currecord();
135155192Srwatson	if (ar == NULL)
136155192Srwatson		return;
137155192Srwatson
138155192Srwatson	ar->k_ar.ar_arg_fd = fd;
139155192Srwatson	ARG_SET_VALID(ar, ARG_FD);
140155192Srwatson}
141155192Srwatson
142155192Srwatsonvoid
143155192Srwatsonaudit_arg_fflags(int fflags)
144155192Srwatson{
145155192Srwatson	struct kaudit_record *ar;
146155192Srwatson
147155192Srwatson	ar = currecord();
148155192Srwatson	if (ar == NULL)
149155192Srwatson		return;
150155192Srwatson
151155192Srwatson	ar->k_ar.ar_arg_fflags = fflags;
152155192Srwatson	ARG_SET_VALID(ar, ARG_FFLAGS);
153155192Srwatson}
154155192Srwatson
155155192Srwatsonvoid
156155192Srwatsonaudit_arg_gid(gid_t gid)
157155192Srwatson{
158155192Srwatson	struct kaudit_record *ar;
159155192Srwatson
160155192Srwatson	ar = currecord();
161155192Srwatson	if (ar == NULL)
162155192Srwatson		return;
163155192Srwatson
164155192Srwatson	ar->k_ar.ar_arg_gid = gid;
165155192Srwatson	ARG_SET_VALID(ar, ARG_GID);
166155192Srwatson}
167155192Srwatson
168155192Srwatsonvoid
169155192Srwatsonaudit_arg_uid(uid_t uid)
170155192Srwatson{
171155192Srwatson	struct kaudit_record *ar;
172155192Srwatson
173155192Srwatson	ar = currecord();
174155192Srwatson	if (ar == NULL)
175155192Srwatson		return;
176155192Srwatson
177155192Srwatson	ar->k_ar.ar_arg_uid = uid;
178155192Srwatson	ARG_SET_VALID(ar, ARG_UID);
179155192Srwatson}
180155192Srwatson
181155192Srwatsonvoid
182155192Srwatsonaudit_arg_egid(gid_t egid)
183155192Srwatson{
184155192Srwatson	struct kaudit_record *ar;
185155192Srwatson
186155192Srwatson	ar = currecord();
187155192Srwatson	if (ar == NULL)
188155192Srwatson		return;
189155192Srwatson
190155192Srwatson	ar->k_ar.ar_arg_egid = egid;
191155192Srwatson	ARG_SET_VALID(ar, ARG_EGID);
192155192Srwatson}
193155192Srwatson
194155192Srwatsonvoid
195155192Srwatsonaudit_arg_euid(uid_t euid)
196155192Srwatson{
197155192Srwatson	struct kaudit_record *ar;
198155192Srwatson
199155192Srwatson	ar = currecord();
200155192Srwatson	if (ar == NULL)
201155192Srwatson		return;
202155192Srwatson
203155192Srwatson	ar->k_ar.ar_arg_euid = euid;
204155192Srwatson	ARG_SET_VALID(ar, ARG_EUID);
205155192Srwatson}
206155192Srwatson
207155192Srwatsonvoid
208155192Srwatsonaudit_arg_rgid(gid_t rgid)
209155192Srwatson{
210155192Srwatson	struct kaudit_record *ar;
211155192Srwatson
212155192Srwatson	ar = currecord();
213155192Srwatson	if (ar == NULL)
214155192Srwatson		return;
215155192Srwatson
216155192Srwatson	ar->k_ar.ar_arg_rgid = rgid;
217155192Srwatson	ARG_SET_VALID(ar, ARG_RGID);
218155192Srwatson}
219155192Srwatson
220155192Srwatsonvoid
221155192Srwatsonaudit_arg_ruid(uid_t ruid)
222155192Srwatson{
223155192Srwatson	struct kaudit_record *ar;
224155192Srwatson
225155192Srwatson	ar = currecord();
226155192Srwatson	if (ar == NULL)
227155192Srwatson		return;
228155192Srwatson
229155192Srwatson	ar->k_ar.ar_arg_ruid = ruid;
230155192Srwatson	ARG_SET_VALID(ar, ARG_RUID);
231155192Srwatson}
232155192Srwatson
233155192Srwatsonvoid
234155192Srwatsonaudit_arg_sgid(gid_t sgid)
235155192Srwatson{
236155192Srwatson	struct kaudit_record *ar;
237155192Srwatson
238155192Srwatson	ar = currecord();
239155192Srwatson	if (ar == NULL)
240155192Srwatson		return;
241155192Srwatson
242155192Srwatson	ar->k_ar.ar_arg_sgid = sgid;
243155192Srwatson	ARG_SET_VALID(ar, ARG_SGID);
244155192Srwatson}
245155192Srwatson
246155192Srwatsonvoid
247155192Srwatsonaudit_arg_suid(uid_t suid)
248155192Srwatson{
249155192Srwatson	struct kaudit_record *ar;
250155192Srwatson
251155192Srwatson	ar = currecord();
252155192Srwatson	if (ar == NULL)
253155192Srwatson		return;
254155192Srwatson
255155192Srwatson	ar->k_ar.ar_arg_suid = suid;
256155192Srwatson	ARG_SET_VALID(ar, ARG_SUID);
257155192Srwatson}
258155192Srwatson
259155192Srwatsonvoid
260155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size)
261155192Srwatson{
262180699Srwatson	u_int i;
263155192Srwatson	struct kaudit_record *ar;
264155192Srwatson
265195177Ssson	KASSERT(gidset_size <= NGROUPS,
266195177Ssson	    ("audit_arg_groupset: gidset_size > NGROUPS"));
267195177Ssson
268155192Srwatson	ar = currecord();
269155192Srwatson	if (ar == NULL)
270155192Srwatson		return;
271155192Srwatson
272195177Ssson	if (ar->k_ar.ar_arg_groups.gidset == NULL)
273195177Ssson		ar->k_ar.ar_arg_groups.gidset = malloc(
274195177Ssson		    sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK);
275195177Ssson
276155192Srwatson	for (i = 0; i < gidset_size; i++)
277155192Srwatson		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
278155192Srwatson	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
279155192Srwatson	ARG_SET_VALID(ar, ARG_GROUPSET);
280155192Srwatson}
281155192Srwatson
282155192Srwatsonvoid
283155192Srwatsonaudit_arg_login(char *login)
284155192Srwatson{
285155192Srwatson	struct kaudit_record *ar;
286155192Srwatson
287155192Srwatson	ar = currecord();
288155192Srwatson	if (ar == NULL)
289155192Srwatson		return;
290155192Srwatson
291155192Srwatson	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
292155192Srwatson	ARG_SET_VALID(ar, ARG_LOGIN);
293155192Srwatson}
294155192Srwatson
295155192Srwatsonvoid
296155192Srwatsonaudit_arg_ctlname(int *name, int namelen)
297155192Srwatson{
298155192Srwatson	struct kaudit_record *ar;
299155192Srwatson
300155192Srwatson	ar = currecord();
301155192Srwatson	if (ar == NULL)
302155192Srwatson		return;
303155192Srwatson
304155192Srwatson	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
305155192Srwatson	ar->k_ar.ar_arg_len = namelen;
306155192Srwatson	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
307155192Srwatson}
308155192Srwatson
309155192Srwatsonvoid
310155192Srwatsonaudit_arg_mask(int mask)
311155192Srwatson{
312155192Srwatson	struct kaudit_record *ar;
313155192Srwatson
314155192Srwatson	ar = currecord();
315155192Srwatson	if (ar == NULL)
316155192Srwatson		return;
317155192Srwatson
318155192Srwatson	ar->k_ar.ar_arg_mask = mask;
319155192Srwatson	ARG_SET_VALID(ar, ARG_MASK);
320155192Srwatson}
321155192Srwatson
322155192Srwatsonvoid
323155192Srwatsonaudit_arg_mode(mode_t mode)
324155192Srwatson{
325155192Srwatson	struct kaudit_record *ar;
326155192Srwatson
327155192Srwatson	ar = currecord();
328155192Srwatson	if (ar == NULL)
329155192Srwatson		return;
330155192Srwatson
331155192Srwatson	ar->k_ar.ar_arg_mode = mode;
332155192Srwatson	ARG_SET_VALID(ar, ARG_MODE);
333155192Srwatson}
334155192Srwatson
335155192Srwatsonvoid
336155192Srwatsonaudit_arg_dev(int dev)
337155192Srwatson{
338155192Srwatson	struct kaudit_record *ar;
339155192Srwatson
340155192Srwatson	ar = currecord();
341155192Srwatson	if (ar == NULL)
342155192Srwatson		return;
343155192Srwatson
344155192Srwatson	ar->k_ar.ar_arg_dev = dev;
345155192Srwatson	ARG_SET_VALID(ar, ARG_DEV);
346155192Srwatson}
347155192Srwatson
348155192Srwatsonvoid
349155192Srwatsonaudit_arg_value(long value)
350155192Srwatson{
351155192Srwatson	struct kaudit_record *ar;
352155192Srwatson
353155192Srwatson	ar = currecord();
354155192Srwatson	if (ar == NULL)
355155192Srwatson		return;
356155192Srwatson
357155192Srwatson	ar->k_ar.ar_arg_value = value;
358155192Srwatson	ARG_SET_VALID(ar, ARG_VALUE);
359155192Srwatson}
360155192Srwatson
361155192Srwatsonvoid
362155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid)
363155192Srwatson{
364155192Srwatson	struct kaudit_record *ar;
365155192Srwatson
366155192Srwatson	ar = currecord();
367155192Srwatson	if (ar == NULL)
368155192Srwatson		return;
369155192Srwatson
370155192Srwatson	ar->k_ar.ar_arg_uid = uid;
371155192Srwatson	ar->k_ar.ar_arg_gid = gid;
372155192Srwatson	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
373155192Srwatson}
374155192Srwatson
375155192Srwatsonvoid
376155192Srwatsonaudit_arg_pid(pid_t pid)
377155192Srwatson{
378155192Srwatson	struct kaudit_record *ar;
379155192Srwatson
380155192Srwatson	ar = currecord();
381155192Srwatson	if (ar == NULL)
382155192Srwatson		return;
383155192Srwatson
384155192Srwatson	ar->k_ar.ar_arg_pid = pid;
385155192Srwatson	ARG_SET_VALID(ar, ARG_PID);
386155192Srwatson}
387155192Srwatson
388155192Srwatsonvoid
389155192Srwatsonaudit_arg_process(struct proc *p)
390155192Srwatson{
391155192Srwatson	struct kaudit_record *ar;
392184948Srwatson	struct ucred *cred;
393155192Srwatson
394160086Srwatson	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
395160086Srwatson
396160086Srwatson	PROC_LOCK_ASSERT(p, MA_OWNED);
397160086Srwatson
398155192Srwatson	ar = currecord();
399160086Srwatson	if (ar == NULL)
400155192Srwatson		return;
401155192Srwatson
402184948Srwatson	cred = p->p_ucred;
403184948Srwatson	ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid;
404184948Srwatson	ar->k_ar.ar_arg_euid = cred->cr_uid;
405184948Srwatson	ar->k_ar.ar_arg_egid = cred->cr_groups[0];
406184948Srwatson	ar->k_ar.ar_arg_ruid = cred->cr_ruid;
407184948Srwatson	ar->k_ar.ar_arg_rgid = cred->cr_rgid;
408184948Srwatson	ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid;
409184948Srwatson	ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid;
410159277Srwatson	ar->k_ar.ar_arg_pid = p->p_pid;
411155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
412168688Scsjp	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
413155192Srwatson}
414155192Srwatson
415155192Srwatsonvoid
416155192Srwatsonaudit_arg_signum(u_int signum)
417155192Srwatson{
418155192Srwatson	struct kaudit_record *ar;
419155192Srwatson
420155192Srwatson	ar = currecord();
421155192Srwatson	if (ar == NULL)
422155192Srwatson		return;
423155192Srwatson
424155192Srwatson	ar->k_ar.ar_arg_signum = signum;
425155192Srwatson	ARG_SET_VALID(ar, ARG_SIGNUM);
426155192Srwatson}
427155192Srwatson
428155192Srwatsonvoid
429155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol)
430155192Srwatson{
431155192Srwatson	struct kaudit_record *ar;
432156889Srwatson
433155192Srwatson	ar = currecord();
434155192Srwatson	if (ar == NULL)
435155192Srwatson		return;
436155192Srwatson
437155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
438155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
439155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
440155192Srwatson	ARG_SET_VALID(ar, ARG_SOCKINFO);
441155192Srwatson}
442155192Srwatson
443155192Srwatsonvoid
444160086Srwatsonaudit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
445155192Srwatson{
446155192Srwatson	struct kaudit_record *ar;
447155192Srwatson
448160086Srwatson	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
449160086Srwatson	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
450160086Srwatson
451155192Srwatson	ar = currecord();
452160086Srwatson	if (ar == NULL)
453155192Srwatson		return;
454155192Srwatson
455164011Scsjp	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
456160086Srwatson	switch (sa->sa_family) {
457155192Srwatson	case AF_INET:
458155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET);
459155192Srwatson		break;
460155192Srwatson
461155192Srwatson	case AF_INET6:
462155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET6);
463155192Srwatson		break;
464155192Srwatson
465155192Srwatson	case AF_UNIX:
466160086Srwatson		audit_arg_upath(td, ((struct sockaddr_un *)sa)->sun_path,
467180703Srwatson		    ARG_UPATH1);
468155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRUNIX);
469155192Srwatson		break;
470155192Srwatson	/* XXXAUDIT: default:? */
471155192Srwatson	}
472155192Srwatson}
473155192Srwatson
474155192Srwatsonvoid
475155192Srwatsonaudit_arg_auid(uid_t auid)
476155192Srwatson{
477155192Srwatson	struct kaudit_record *ar;
478155192Srwatson
479155192Srwatson	ar = currecord();
480155192Srwatson	if (ar == NULL)
481155192Srwatson		return;
482155192Srwatson
483155192Srwatson	ar->k_ar.ar_arg_auid = auid;
484155192Srwatson	ARG_SET_VALID(ar, ARG_AUID);
485155192Srwatson}
486155192Srwatson
487155192Srwatsonvoid
488155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info)
489155192Srwatson{
490155192Srwatson	struct kaudit_record *ar;
491155192Srwatson
492155192Srwatson	ar = currecord();
493155192Srwatson	if (ar == NULL)
494155192Srwatson		return;
495155192Srwatson
496155192Srwatson	ar->k_ar.ar_arg_auid = au_info->ai_auid;
497155192Srwatson	ar->k_ar.ar_arg_asid = au_info->ai_asid;
498155192Srwatson	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
499155192Srwatson	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
500155192Srwatson	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
501155192Srwatson	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
502155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
503155192Srwatson}
504155192Srwatson
505155192Srwatsonvoid
506171066Scsjpaudit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
507171066Scsjp{
508171066Scsjp	struct kaudit_record *ar;
509171066Scsjp
510171066Scsjp	ar = currecord();
511171066Scsjp	if (ar == NULL)
512171066Scsjp		return;
513171066Scsjp
514171066Scsjp	ar->k_ar.ar_arg_auid = au_info->ai_auid;
515171066Scsjp	ar->k_ar.ar_arg_asid = au_info->ai_asid;
516171066Scsjp	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
517171066Scsjp	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
518171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
519171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
520171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
521171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
522171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
523171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
524171066Scsjp	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
525171066Scsjp}
526171066Scsjp
527171066Scsjpvoid
528155192Srwatsonaudit_arg_text(char *text)
529155192Srwatson{
530155192Srwatson	struct kaudit_record *ar;
531155192Srwatson
532160086Srwatson	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
533160086Srwatson
534155192Srwatson	ar = currecord();
535155192Srwatson	if (ar == NULL)
536155192Srwatson		return;
537155192Srwatson
538155192Srwatson	/* Invalidate the text string */
539155192Srwatson	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
540155192Srwatson
541155192Srwatson	if (ar->k_ar.ar_arg_text == NULL)
542155192Srwatson		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
543155192Srwatson		    M_WAITOK);
544155192Srwatson
545155192Srwatson	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
546155192Srwatson	ARG_SET_VALID(ar, ARG_TEXT);
547155192Srwatson}
548155192Srwatson
549155192Srwatsonvoid
550155192Srwatsonaudit_arg_cmd(int cmd)
551155192Srwatson{
552155192Srwatson	struct kaudit_record *ar;
553155192Srwatson
554155192Srwatson	ar = currecord();
555155192Srwatson	if (ar == NULL)
556155192Srwatson		return;
557155192Srwatson
558155192Srwatson	ar->k_ar.ar_arg_cmd = cmd;
559155192Srwatson	ARG_SET_VALID(ar, ARG_CMD);
560155192Srwatson}
561155192Srwatson
562155192Srwatsonvoid
563155192Srwatsonaudit_arg_svipc_cmd(int cmd)
564155192Srwatson{
565155192Srwatson	struct kaudit_record *ar;
566155192Srwatson
567155192Srwatson	ar = currecord();
568155192Srwatson	if (ar == NULL)
569155192Srwatson		return;
570155192Srwatson
571155192Srwatson	ar->k_ar.ar_arg_svipc_cmd = cmd;
572155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
573155192Srwatson}
574155192Srwatson
575155192Srwatsonvoid
576155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm)
577155192Srwatson{
578155192Srwatson	struct kaudit_record *ar;
579155192Srwatson
580155192Srwatson	ar = currecord();
581155192Srwatson	if (ar == NULL)
582155192Srwatson		return;
583155192Srwatson
584156889Srwatson	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
585156889Srwatson	    sizeof(ar->k_ar.ar_arg_svipc_perm));
586155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
587155192Srwatson}
588155192Srwatson
589155192Srwatsonvoid
590155192Srwatsonaudit_arg_svipc_id(int id)
591155192Srwatson{
592155192Srwatson	struct kaudit_record *ar;
593155192Srwatson
594155192Srwatson	ar = currecord();
595155192Srwatson	if (ar == NULL)
596155192Srwatson		return;
597155192Srwatson
598155192Srwatson	ar->k_ar.ar_arg_svipc_id = id;
599155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ID);
600155192Srwatson}
601155192Srwatson
602155192Srwatsonvoid
603155192Srwatsonaudit_arg_svipc_addr(void * addr)
604155192Srwatson{
605155192Srwatson	struct kaudit_record *ar;
606155192Srwatson
607155192Srwatson	ar = currecord();
608155192Srwatson	if (ar == NULL)
609155192Srwatson		return;
610155192Srwatson
611155192Srwatson	ar->k_ar.ar_arg_svipc_addr = addr;
612155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
613155192Srwatson}
614155192Srwatson
615155192Srwatsonvoid
616155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
617155192Srwatson{
618155192Srwatson	struct kaudit_record *ar;
619155192Srwatson
620155192Srwatson	ar = currecord();
621155192Srwatson	if (ar == NULL)
622155192Srwatson		return;
623155192Srwatson
624155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
625155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
626155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
627155192Srwatson	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
628155192Srwatson}
629155192Srwatson
630155192Srwatsonvoid
631155192Srwatsonaudit_arg_auditon(union auditon_udata *udata)
632155192Srwatson{
633155192Srwatson	struct kaudit_record *ar;
634155192Srwatson
635155192Srwatson	ar = currecord();
636155192Srwatson	if (ar == NULL)
637155192Srwatson		return;
638155192Srwatson
639156889Srwatson	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
640156889Srwatson	    sizeof(ar->k_ar.ar_arg_auditon));
641155192Srwatson	ARG_SET_VALID(ar, ARG_AUDITON);
642155192Srwatson}
643155192Srwatson
644155192Srwatson/*
645155192Srwatson * Audit information about a file, either the file's vnode info, or its
646155192Srwatson * socket address info.
647155192Srwatson */
648155192Srwatsonvoid
649155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp)
650155192Srwatson{
651155192Srwatson	struct kaudit_record *ar;
652155192Srwatson	struct socket *so;
653155192Srwatson	struct inpcb *pcb;
654155192Srwatson	struct vnode *vp;
655155192Srwatson	int vfslocked;
656155192Srwatson
657160086Srwatson	ar = currecord();
658160086Srwatson	if (ar == NULL)
659160086Srwatson		return;
660160086Srwatson
661155192Srwatson	switch (fp->f_type) {
662155192Srwatson	case DTYPE_VNODE:
663155192Srwatson	case DTYPE_FIFO:
664155192Srwatson		/*
665155192Srwatson		 * XXXAUDIT: Only possibly to record as first vnode?
666155192Srwatson		 */
667155192Srwatson		vp = fp->f_vnode;
668155192Srwatson		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
669184661Sjhb		vn_lock(vp, LK_SHARED | LK_RETRY);
670155192Srwatson		audit_arg_vnode(vp, ARG_VNODE1);
671175294Sattilio		VOP_UNLOCK(vp, 0);
672155192Srwatson		VFS_UNLOCK_GIANT(vfslocked);
673155192Srwatson		break;
674155192Srwatson
675155192Srwatson	case DTYPE_SOCKET:
676155192Srwatson		so = (struct socket *)fp->f_data;
677155192Srwatson		if (INP_CHECK_SOCKAF(so, PF_INET)) {
678166845Srwatson			SOCK_LOCK(so);
679155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_type =
680156889Srwatson			    so->so_type;
681155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_domain =
682156889Srwatson			    INP_SOCKAF(so);
683155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_protocol =
684156889Srwatson			    so->so_proto->pr_protocol;
685166845Srwatson			SOCK_UNLOCK(so);
686155192Srwatson			pcb = (struct inpcb *)so->so_pcb;
687178322Srwatson			INP_RLOCK(pcb);
688155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_raddr =
689156889Srwatson			    pcb->inp_faddr.s_addr;
690155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_laddr =
691156889Srwatson			    pcb->inp_laddr.s_addr;
692155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_rport =
693156889Srwatson			    pcb->inp_fport;
694155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_lport =
695156889Srwatson			    pcb->inp_lport;
696178322Srwatson			INP_RUNLOCK(pcb);
697155192Srwatson			ARG_SET_VALID(ar, ARG_SOCKINFO);
698155192Srwatson		}
699155192Srwatson		break;
700155192Srwatson
701155192Srwatson	default:
702155192Srwatson		/* XXXAUDIT: else? */
703155192Srwatson		break;
704155192Srwatson	}
705155192Srwatson}
706155192Srwatson
707156889Srwatson/*
708156889Srwatson * Store a path as given by the user process for auditing into the audit
709180703Srwatson * record stored on the user thread.  This function will allocate the memory
710180703Srwatson * to store the path info if not already available.  This memory will be
711180703Srwatson * freed when the audit record is freed.
712155192Srwatson *
713155192Srwatson * XXXAUDIT: Possibly assert that the memory isn't already allocated?
714155192Srwatson */
715155192Srwatsonvoid
716155192Srwatsonaudit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
717155192Srwatson{
718155192Srwatson	struct kaudit_record *ar;
719155192Srwatson	char **pathp;
720155192Srwatson
721160086Srwatson	KASSERT(td != NULL, ("audit_arg_upath: td == NULL"));
722160086Srwatson	KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL"));
723155192Srwatson
724160086Srwatson	ar = currecord();
725160086Srwatson	if (ar == NULL)
726160086Srwatson		return;
727160086Srwatson
728155192Srwatson	KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2),
729155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
730155192Srwatson	KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2),
731155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
732155192Srwatson
733155192Srwatson	if (flag == ARG_UPATH1)
734155192Srwatson		pathp = &ar->k_ar.ar_arg_upath1;
735155192Srwatson	else
736155192Srwatson		pathp = &ar->k_ar.ar_arg_upath2;
737155192Srwatson
738155192Srwatson	if (*pathp == NULL)
739155192Srwatson		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
740155192Srwatson
741176565Srwatson	audit_canon_path(td, upath, *pathp);
742155192Srwatson
743155192Srwatson	ARG_SET_VALID(ar, flag);
744155192Srwatson}
745155192Srwatson
746155192Srwatson/*
747156889Srwatson * Function to save the path and vnode attr information into the audit
748156889Srwatson * record.
749155192Srwatson *
750155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to
751155192Srwatson * perform a VOP_GETATTR() on the passed vnode.
752155192Srwatson *
753170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
754170196Srwatson * provides access to the generation number as we need that to construct the
755170196Srwatson * BSM file ID.
756170196Srwatson *
757170196Srwatson * XXX: We should accept the process argument from the caller, since it's
758170196Srwatson * very likely they already have a reference.
759170196Srwatson *
760155192Srwatson * XXX: Error handling in this function is poor.
761155192Srwatson *
762155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
763155192Srwatson */
764155192Srwatsonvoid
765155192Srwatsonaudit_arg_vnode(struct vnode *vp, u_int64_t flags)
766155192Srwatson{
767155192Srwatson	struct kaudit_record *ar;
768155192Srwatson	struct vattr vattr;
769155192Srwatson	int error;
770155192Srwatson	struct vnode_au_info *vnp;
771155192Srwatson
772160086Srwatson	KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL"));
773160086Srwatson	KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2),
774160086Srwatson	    ("audit_arg_vnode: flags %jd", (intmax_t)flags));
775155192Srwatson
776155192Srwatson	/*
777155192Srwatson	 * Assume that if the caller is calling audit_arg_vnode() on a
778155192Srwatson	 * non-MPSAFE vnode, then it will have acquired Giant.
779155192Srwatson	 */
780155192Srwatson	VFS_ASSERT_GIANT(vp->v_mount);
781155192Srwatson	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
782155192Srwatson
783155192Srwatson	ar = currecord();
784156889Srwatson	if (ar == NULL)
785155192Srwatson		return;
786155192Srwatson
787155192Srwatson	/*
788155192Srwatson	 * XXXAUDIT: The below clears, and then resets the flags for valid
789155192Srwatson	 * arguments.  Ideally, either the new vnode is used, or the old one
790155192Srwatson	 * would be.
791155192Srwatson	 */
792155192Srwatson	if (flags & ARG_VNODE1) {
793155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
794155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode1;
795155192Srwatson	} else {
796155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
797155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode2;
798155192Srwatson	}
799155192Srwatson
800182371Sattilio	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
801155192Srwatson	if (error) {
802155192Srwatson		/* XXX: How to handle this case? */
803155192Srwatson		return;
804155192Srwatson	}
805155192Srwatson
806155192Srwatson	vnp->vn_mode = vattr.va_mode;
807155192Srwatson	vnp->vn_uid = vattr.va_uid;
808155192Srwatson	vnp->vn_gid = vattr.va_gid;
809155192Srwatson	vnp->vn_dev = vattr.va_rdev;
810155192Srwatson	vnp->vn_fsid = vattr.va_fsid;
811155192Srwatson	vnp->vn_fileid = vattr.va_fileid;
812155192Srwatson	vnp->vn_gen = vattr.va_gen;
813155192Srwatson	if (flags & ARG_VNODE1)
814155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE1);
815155192Srwatson	else
816155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE2);
817155192Srwatson}
818155192Srwatson
819155192Srwatson/*
820161813Swsalamon * Audit the argument strings passed to exec.
821161813Swsalamon */
822161813Swsalamonvoid
823161813Swsalamonaudit_arg_argv(char *argv, int argc, int length)
824161813Swsalamon{
825161813Swsalamon	struct kaudit_record *ar;
826161813Swsalamon
827161813Swsalamon	if (audit_argv == 0)
828161813Swsalamon		return;
829161813Swsalamon
830161813Swsalamon	ar = currecord();
831161813Swsalamon	if (ar == NULL)
832161813Swsalamon		return;
833161813Swsalamon
834161813Swsalamon	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
835161813Swsalamon	bcopy(argv, ar->k_ar.ar_arg_argv, length);
836161813Swsalamon	ar->k_ar.ar_arg_argc = argc;
837161813Swsalamon	ARG_SET_VALID(ar, ARG_ARGV);
838161813Swsalamon}
839161813Swsalamon
840161813Swsalamon/*
841161813Swsalamon * Audit the environment strings passed to exec.
842161813Swsalamon */
843161813Swsalamonvoid
844161813Swsalamonaudit_arg_envv(char *envv, int envc, int length)
845161813Swsalamon{
846161813Swsalamon	struct kaudit_record *ar;
847161813Swsalamon
848161813Swsalamon	if (audit_arge == 0)
849161813Swsalamon		return;
850161813Swsalamon
851161813Swsalamon	ar = currecord();
852161813Swsalamon	if (ar == NULL)
853161813Swsalamon		return;
854161813Swsalamon
855161813Swsalamon	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
856161813Swsalamon	bcopy(envv, ar->k_ar.ar_arg_envv, length);
857161813Swsalamon	ar->k_ar.ar_arg_envc = envc;
858161813Swsalamon	ARG_SET_VALID(ar, ARG_ENVV);
859161813Swsalamon}
860161813Swsalamon
861161813Swsalamon/*
862156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode
863156889Srwatson * information because those pieces are not easily obtained within the system
864156889Srwatson * call itself.
865155192Srwatson */
866155192Srwatsonvoid
867155192Srwatsonaudit_sysclose(struct thread *td, int fd)
868155192Srwatson{
869160086Srwatson	struct kaudit_record *ar;
870155192Srwatson	struct vnode *vp;
871155192Srwatson	struct file *fp;
872155192Srwatson	int vfslocked;
873155192Srwatson
874160086Srwatson	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
875160086Srwatson
876160086Srwatson	ar = currecord();
877160086Srwatson	if (ar == NULL)
878160086Srwatson		return;
879160086Srwatson
880155192Srwatson	audit_arg_fd(fd);
881155192Srwatson
882155192Srwatson	if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
883155192Srwatson		return;
884155192Srwatson
885155192Srwatson	vp = fp->f_vnode;
886155192Srwatson	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
887184661Sjhb	vn_lock(vp, LK_SHARED | LK_RETRY);
888155192Srwatson	audit_arg_vnode(vp, ARG_VNODE1);
889175294Sattilio	VOP_UNLOCK(vp, 0);
890155192Srwatson	VFS_UNLOCK_GIANT(vfslocked);
891155192Srwatson	fdrop(fp, td);
892156889Srwatson}
893