audit_arg.c revision 202143
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 202143 2010-01-12 07:49:34Z brooks $");
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
265202143Sbrooks	KASSERT(gidset_size <= ngroups_max + 1,
266202143Sbrooks	    ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)"));
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:
466195939Srwatson		audit_arg_upath1(td, ((struct sockaddr_un *)sa)->sun_path);
467155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRUNIX);
468155192Srwatson		break;
469155192Srwatson	/* XXXAUDIT: default:? */
470155192Srwatson	}
471155192Srwatson}
472155192Srwatson
473155192Srwatsonvoid
474155192Srwatsonaudit_arg_auid(uid_t auid)
475155192Srwatson{
476155192Srwatson	struct kaudit_record *ar;
477155192Srwatson
478155192Srwatson	ar = currecord();
479155192Srwatson	if (ar == NULL)
480155192Srwatson		return;
481155192Srwatson
482155192Srwatson	ar->k_ar.ar_arg_auid = auid;
483155192Srwatson	ARG_SET_VALID(ar, ARG_AUID);
484155192Srwatson}
485155192Srwatson
486155192Srwatsonvoid
487155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info)
488155192Srwatson{
489155192Srwatson	struct kaudit_record *ar;
490155192Srwatson
491155192Srwatson	ar = currecord();
492155192Srwatson	if (ar == NULL)
493155192Srwatson		return;
494155192Srwatson
495155192Srwatson	ar->k_ar.ar_arg_auid = au_info->ai_auid;
496155192Srwatson	ar->k_ar.ar_arg_asid = au_info->ai_asid;
497155192Srwatson	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
498155192Srwatson	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
499155192Srwatson	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
500155192Srwatson	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
501155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
502155192Srwatson}
503155192Srwatson
504155192Srwatsonvoid
505171066Scsjpaudit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
506171066Scsjp{
507171066Scsjp	struct kaudit_record *ar;
508171066Scsjp
509171066Scsjp	ar = currecord();
510171066Scsjp	if (ar == NULL)
511171066Scsjp		return;
512171066Scsjp
513171066Scsjp	ar->k_ar.ar_arg_auid = au_info->ai_auid;
514171066Scsjp	ar->k_ar.ar_arg_asid = au_info->ai_asid;
515171066Scsjp	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
516171066Scsjp	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
517171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
518171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
519171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
520171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
521171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
522171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
523171066Scsjp	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
524171066Scsjp}
525171066Scsjp
526171066Scsjpvoid
527155192Srwatsonaudit_arg_text(char *text)
528155192Srwatson{
529155192Srwatson	struct kaudit_record *ar;
530155192Srwatson
531160086Srwatson	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
532160086Srwatson
533155192Srwatson	ar = currecord();
534155192Srwatson	if (ar == NULL)
535155192Srwatson		return;
536155192Srwatson
537155192Srwatson	/* Invalidate the text string */
538155192Srwatson	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
539155192Srwatson
540155192Srwatson	if (ar->k_ar.ar_arg_text == NULL)
541155192Srwatson		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
542155192Srwatson		    M_WAITOK);
543155192Srwatson
544155192Srwatson	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
545155192Srwatson	ARG_SET_VALID(ar, ARG_TEXT);
546155192Srwatson}
547155192Srwatson
548155192Srwatsonvoid
549155192Srwatsonaudit_arg_cmd(int cmd)
550155192Srwatson{
551155192Srwatson	struct kaudit_record *ar;
552155192Srwatson
553155192Srwatson	ar = currecord();
554155192Srwatson	if (ar == NULL)
555155192Srwatson		return;
556155192Srwatson
557155192Srwatson	ar->k_ar.ar_arg_cmd = cmd;
558155192Srwatson	ARG_SET_VALID(ar, ARG_CMD);
559155192Srwatson}
560155192Srwatson
561155192Srwatsonvoid
562155192Srwatsonaudit_arg_svipc_cmd(int cmd)
563155192Srwatson{
564155192Srwatson	struct kaudit_record *ar;
565155192Srwatson
566155192Srwatson	ar = currecord();
567155192Srwatson	if (ar == NULL)
568155192Srwatson		return;
569155192Srwatson
570155192Srwatson	ar->k_ar.ar_arg_svipc_cmd = cmd;
571155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
572155192Srwatson}
573155192Srwatson
574155192Srwatsonvoid
575155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm)
576155192Srwatson{
577155192Srwatson	struct kaudit_record *ar;
578155192Srwatson
579155192Srwatson	ar = currecord();
580155192Srwatson	if (ar == NULL)
581155192Srwatson		return;
582155192Srwatson
583156889Srwatson	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
584156889Srwatson	    sizeof(ar->k_ar.ar_arg_svipc_perm));
585155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
586155192Srwatson}
587155192Srwatson
588155192Srwatsonvoid
589155192Srwatsonaudit_arg_svipc_id(int id)
590155192Srwatson{
591155192Srwatson	struct kaudit_record *ar;
592155192Srwatson
593155192Srwatson	ar = currecord();
594155192Srwatson	if (ar == NULL)
595155192Srwatson		return;
596155192Srwatson
597155192Srwatson	ar->k_ar.ar_arg_svipc_id = id;
598155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ID);
599155192Srwatson}
600155192Srwatson
601155192Srwatsonvoid
602155192Srwatsonaudit_arg_svipc_addr(void * addr)
603155192Srwatson{
604155192Srwatson	struct kaudit_record *ar;
605155192Srwatson
606155192Srwatson	ar = currecord();
607155192Srwatson	if (ar == NULL)
608155192Srwatson		return;
609155192Srwatson
610155192Srwatson	ar->k_ar.ar_arg_svipc_addr = addr;
611155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
612155192Srwatson}
613155192Srwatson
614155192Srwatsonvoid
615155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
616155192Srwatson{
617155192Srwatson	struct kaudit_record *ar;
618155192Srwatson
619155192Srwatson	ar = currecord();
620155192Srwatson	if (ar == NULL)
621155192Srwatson		return;
622155192Srwatson
623155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
624155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
625155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
626155192Srwatson	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
627155192Srwatson}
628155192Srwatson
629155192Srwatsonvoid
630155192Srwatsonaudit_arg_auditon(union auditon_udata *udata)
631155192Srwatson{
632155192Srwatson	struct kaudit_record *ar;
633155192Srwatson
634155192Srwatson	ar = currecord();
635155192Srwatson	if (ar == NULL)
636155192Srwatson		return;
637155192Srwatson
638156889Srwatson	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
639156889Srwatson	    sizeof(ar->k_ar.ar_arg_auditon));
640155192Srwatson	ARG_SET_VALID(ar, ARG_AUDITON);
641155192Srwatson}
642155192Srwatson
643155192Srwatson/*
644155192Srwatson * Audit information about a file, either the file's vnode info, or its
645155192Srwatson * socket address info.
646155192Srwatson */
647155192Srwatsonvoid
648155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp)
649155192Srwatson{
650155192Srwatson	struct kaudit_record *ar;
651155192Srwatson	struct socket *so;
652155192Srwatson	struct inpcb *pcb;
653155192Srwatson	struct vnode *vp;
654155192Srwatson	int vfslocked;
655155192Srwatson
656160086Srwatson	ar = currecord();
657160086Srwatson	if (ar == NULL)
658160086Srwatson		return;
659160086Srwatson
660155192Srwatson	switch (fp->f_type) {
661155192Srwatson	case DTYPE_VNODE:
662155192Srwatson	case DTYPE_FIFO:
663155192Srwatson		/*
664155192Srwatson		 * XXXAUDIT: Only possibly to record as first vnode?
665155192Srwatson		 */
666155192Srwatson		vp = fp->f_vnode;
667155192Srwatson		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
668184661Sjhb		vn_lock(vp, LK_SHARED | LK_RETRY);
669195926Srwatson		audit_arg_vnode1(vp);
670175294Sattilio		VOP_UNLOCK(vp, 0);
671155192Srwatson		VFS_UNLOCK_GIANT(vfslocked);
672155192Srwatson		break;
673155192Srwatson
674155192Srwatson	case DTYPE_SOCKET:
675155192Srwatson		so = (struct socket *)fp->f_data;
676155192Srwatson		if (INP_CHECK_SOCKAF(so, PF_INET)) {
677166845Srwatson			SOCK_LOCK(so);
678155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_type =
679156889Srwatson			    so->so_type;
680155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_domain =
681156889Srwatson			    INP_SOCKAF(so);
682155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_protocol =
683156889Srwatson			    so->so_proto->pr_protocol;
684166845Srwatson			SOCK_UNLOCK(so);
685155192Srwatson			pcb = (struct inpcb *)so->so_pcb;
686178322Srwatson			INP_RLOCK(pcb);
687155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_raddr =
688156889Srwatson			    pcb->inp_faddr.s_addr;
689155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_laddr =
690156889Srwatson			    pcb->inp_laddr.s_addr;
691155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_rport =
692156889Srwatson			    pcb->inp_fport;
693155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_lport =
694156889Srwatson			    pcb->inp_lport;
695178322Srwatson			INP_RUNLOCK(pcb);
696155192Srwatson			ARG_SET_VALID(ar, ARG_SOCKINFO);
697155192Srwatson		}
698155192Srwatson		break;
699155192Srwatson
700155192Srwatson	default:
701155192Srwatson		/* XXXAUDIT: else? */
702155192Srwatson		break;
703155192Srwatson	}
704155192Srwatson}
705155192Srwatson
706156889Srwatson/*
707156889Srwatson * Store a path as given by the user process for auditing into the audit
708180703Srwatson * record stored on the user thread.  This function will allocate the memory
709180703Srwatson * to store the path info if not already available.  This memory will be
710180703Srwatson * freed when the audit record is freed.
711155192Srwatson */
712195939Srwatsonstatic void
713195939Srwatsonaudit_arg_upath(struct thread *td, char *upath, char **pathp)
714195939Srwatson{
715195939Srwatson
716195939Srwatson	if (*pathp == NULL)
717195939Srwatson		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
718195939Srwatson	audit_canon_path(td, upath, *pathp);
719195939Srwatson}
720195939Srwatson
721155192Srwatsonvoid
722195939Srwatsonaudit_arg_upath1(struct thread *td, char *upath)
723155192Srwatson{
724155192Srwatson	struct kaudit_record *ar;
725155192Srwatson
726160086Srwatson	ar = currecord();
727160086Srwatson	if (ar == NULL)
728160086Srwatson		return;
729160086Srwatson
730195939Srwatson	audit_arg_upath(td, upath, &ar->k_ar.ar_arg_upath1);
731195939Srwatson	ARG_SET_VALID(ar, ARG_UPATH1);
732195939Srwatson}
733155192Srwatson
734195939Srwatsonvoid
735195939Srwatsonaudit_arg_upath2(struct thread *td, char *upath)
736195939Srwatson{
737195939Srwatson	struct kaudit_record *ar;
738155192Srwatson
739195939Srwatson	ar = currecord();
740195939Srwatson	if (ar == NULL)
741195939Srwatson		return;
742155192Srwatson
743195939Srwatson	audit_arg_upath(td, upath, &ar->k_ar.ar_arg_upath2);
744195939Srwatson	ARG_SET_VALID(ar, ARG_UPATH2);
745155192Srwatson}
746155192Srwatson
747155192Srwatson/*
748156889Srwatson * Function to save the path and vnode attr information into the audit
749156889Srwatson * record.
750155192Srwatson *
751155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to
752155192Srwatson * perform a VOP_GETATTR() on the passed vnode.
753155192Srwatson *
754170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
755170196Srwatson * provides access to the generation number as we need that to construct the
756170196Srwatson * BSM file ID.
757170196Srwatson *
758170196Srwatson * XXX: We should accept the process argument from the caller, since it's
759170196Srwatson * very likely they already have a reference.
760170196Srwatson *
761155192Srwatson * XXX: Error handling in this function is poor.
762155192Srwatson *
763155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
764155192Srwatson */
765195926Srwatsonstatic int
766195926Srwatsonaudit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp)
767155192Srwatson{
768155192Srwatson	struct vattr vattr;
769155192Srwatson	int error;
770155192Srwatson
771155192Srwatson	/*
772155192Srwatson	 * Assume that if the caller is calling audit_arg_vnode() on a
773155192Srwatson	 * non-MPSAFE vnode, then it will have acquired Giant.
774155192Srwatson	 */
775155192Srwatson	VFS_ASSERT_GIANT(vp->v_mount);
776155192Srwatson	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
777155192Srwatson
778182371Sattilio	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
779155192Srwatson	if (error) {
780155192Srwatson		/* XXX: How to handle this case? */
781195926Srwatson		return (error);
782155192Srwatson	}
783155192Srwatson
784155192Srwatson	vnp->vn_mode = vattr.va_mode;
785155192Srwatson	vnp->vn_uid = vattr.va_uid;
786155192Srwatson	vnp->vn_gid = vattr.va_gid;
787155192Srwatson	vnp->vn_dev = vattr.va_rdev;
788155192Srwatson	vnp->vn_fsid = vattr.va_fsid;
789155192Srwatson	vnp->vn_fileid = vattr.va_fileid;
790155192Srwatson	vnp->vn_gen = vattr.va_gen;
791195926Srwatson	return (0);
792195926Srwatson}
793195926Srwatson
794195926Srwatsonvoid
795195926Srwatsonaudit_arg_vnode1(struct vnode *vp)
796195926Srwatson{
797195926Srwatson	struct kaudit_record *ar;
798195926Srwatson	int error;
799195926Srwatson
800195926Srwatson	ar = currecord();
801195926Srwatson	if (ar == NULL)
802195926Srwatson		return;
803195926Srwatson
804195926Srwatson	ARG_CLEAR_VALID(ar, ARG_VNODE1);
805195926Srwatson	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1);
806195926Srwatson	if (error == 0)
807155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE1);
808195926Srwatson}
809195926Srwatson
810195926Srwatsonvoid
811195926Srwatsonaudit_arg_vnode2(struct vnode *vp)
812195926Srwatson{
813195926Srwatson	struct kaudit_record *ar;
814195926Srwatson	int error;
815195926Srwatson
816195926Srwatson	ar = currecord();
817195926Srwatson	if (ar == NULL)
818195926Srwatson		return;
819195926Srwatson
820195926Srwatson	ARG_CLEAR_VALID(ar, ARG_VNODE2);
821195926Srwatson	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2);
822195926Srwatson	if (error == 0)
823155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE2);
824155192Srwatson}
825155192Srwatson
826155192Srwatson/*
827161813Swsalamon * Audit the argument strings passed to exec.
828161813Swsalamon */
829161813Swsalamonvoid
830161813Swsalamonaudit_arg_argv(char *argv, int argc, int length)
831161813Swsalamon{
832161813Swsalamon	struct kaudit_record *ar;
833161813Swsalamon
834161813Swsalamon	if (audit_argv == 0)
835161813Swsalamon		return;
836161813Swsalamon
837161813Swsalamon	ar = currecord();
838161813Swsalamon	if (ar == NULL)
839161813Swsalamon		return;
840161813Swsalamon
841161813Swsalamon	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
842161813Swsalamon	bcopy(argv, ar->k_ar.ar_arg_argv, length);
843161813Swsalamon	ar->k_ar.ar_arg_argc = argc;
844161813Swsalamon	ARG_SET_VALID(ar, ARG_ARGV);
845161813Swsalamon}
846161813Swsalamon
847161813Swsalamon/*
848161813Swsalamon * Audit the environment strings passed to exec.
849161813Swsalamon */
850161813Swsalamonvoid
851161813Swsalamonaudit_arg_envv(char *envv, int envc, int length)
852161813Swsalamon{
853161813Swsalamon	struct kaudit_record *ar;
854161813Swsalamon
855161813Swsalamon	if (audit_arge == 0)
856161813Swsalamon		return;
857161813Swsalamon
858161813Swsalamon	ar = currecord();
859161813Swsalamon	if (ar == NULL)
860161813Swsalamon		return;
861161813Swsalamon
862161813Swsalamon	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
863161813Swsalamon	bcopy(envv, ar->k_ar.ar_arg_envv, length);
864161813Swsalamon	ar->k_ar.ar_arg_envc = envc;
865161813Swsalamon	ARG_SET_VALID(ar, ARG_ENVV);
866161813Swsalamon}
867161813Swsalamon
868161813Swsalamon/*
869156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode
870156889Srwatson * information because those pieces are not easily obtained within the system
871156889Srwatson * call itself.
872155192Srwatson */
873155192Srwatsonvoid
874155192Srwatsonaudit_sysclose(struct thread *td, int fd)
875155192Srwatson{
876160086Srwatson	struct kaudit_record *ar;
877155192Srwatson	struct vnode *vp;
878155192Srwatson	struct file *fp;
879155192Srwatson	int vfslocked;
880155192Srwatson
881160086Srwatson	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
882160086Srwatson
883160086Srwatson	ar = currecord();
884160086Srwatson	if (ar == NULL)
885160086Srwatson		return;
886160086Srwatson
887155192Srwatson	audit_arg_fd(fd);
888155192Srwatson
889155192Srwatson	if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
890155192Srwatson		return;
891155192Srwatson
892155192Srwatson	vp = fp->f_vnode;
893155192Srwatson	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
894184661Sjhb	vn_lock(vp, LK_SHARED | LK_RETRY);
895195926Srwatson	audit_arg_vnode1(vp);
896175294Sattilio	VOP_UNLOCK(vp, 0);
897155192Srwatson	VFS_UNLOCK_GIANT(vfslocked);
898155192Srwatson	fdrop(fp, td);
899156889Srwatson}
900