audit_arg.c revision 170585
1155192Srwatson/*
2155192Srwatson * Copyright (c) 1999-2005 Apple Computer, 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.
13155192Srwatson * 3.  Neither the name of Apple Computer, 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 * $FreeBSD: head/sys/security/audit/audit_arg.c 170585 2007-06-11 22:10:54Z rwatson $
30155192Srwatson */
31155192Srwatson
32155192Srwatson#include <sys/param.h>
33155192Srwatson#include <sys/filedesc.h>
34155192Srwatson#include <sys/ipc.h>
35155192Srwatson#include <sys/mount.h>
36155192Srwatson#include <sys/proc.h>
37155192Srwatson#include <sys/socket.h>
38155192Srwatson#include <sys/socketvar.h>
39155192Srwatson#include <sys/protosw.h>
40155192Srwatson#include <sys/domain.h>
41159277Srwatson#include <sys/sbuf.h>
42155192Srwatson#include <sys/systm.h>
43155192Srwatson#include <sys/un.h>
44155192Srwatson#include <sys/vnode.h>
45155192Srwatson
46155192Srwatson#include <netinet/in.h>
47155192Srwatson#include <netinet/in_pcb.h>
48155192Srwatson
49155192Srwatson#include <security/audit/audit.h>
50155192Srwatson#include <security/audit/audit_private.h>
51155192Srwatson
52155192Srwatson/*
53155192Srwatson * Calls to manipulate elements of the audit record structure from system
54170196Srwatson * call code.  Macro wrappers will prevent this functions from being entered
55170196Srwatson * if auditing is disabled, avoiding the function call cost.  We check the
56170196Srwatson * thread audit record pointer anyway, as the audit condition could change,
57170196Srwatson * and pre-selection may not have allocated an audit record for this event.
58155192Srwatson *
59155192Srwatson * XXXAUDIT: Should we assert, in each case, that this field of the record
60155192Srwatson * hasn't already been filled in?
61155192Srwatson */
62155192Srwatsonvoid
63170585Srwatsonaudit_arg_addr(void *addr)
64155192Srwatson{
65155192Srwatson	struct kaudit_record *ar;
66155192Srwatson
67155192Srwatson	ar = currecord();
68155192Srwatson	if (ar == NULL)
69155192Srwatson		return;
70155192Srwatson
71155192Srwatson	ar->k_ar.ar_arg_addr = addr;
72155192Srwatson	ARG_SET_VALID(ar, ARG_ADDR);
73155192Srwatson}
74155192Srwatson
75155192Srwatsonvoid
76155192Srwatsonaudit_arg_exit(int status, int retval)
77155192Srwatson{
78155192Srwatson	struct kaudit_record *ar;
79155192Srwatson
80155192Srwatson	ar = currecord();
81155192Srwatson	if (ar == NULL)
82155192Srwatson		return;
83155192Srwatson
84155192Srwatson	ar->k_ar.ar_arg_exitstatus = status;
85155192Srwatson	ar->k_ar.ar_arg_exitretval = retval;
86155192Srwatson	ARG_SET_VALID(ar, ARG_EXIT);
87155192Srwatson}
88155192Srwatson
89155192Srwatsonvoid
90155192Srwatsonaudit_arg_len(int len)
91155192Srwatson{
92155192Srwatson	struct kaudit_record *ar;
93155192Srwatson
94155192Srwatson	ar = currecord();
95155192Srwatson	if (ar == NULL)
96155192Srwatson		return;
97155192Srwatson
98155192Srwatson	ar->k_ar.ar_arg_len = len;
99155192Srwatson	ARG_SET_VALID(ar, ARG_LEN);
100155192Srwatson}
101155192Srwatson
102155192Srwatsonvoid
103155192Srwatsonaudit_arg_fd(int fd)
104155192Srwatson{
105155192Srwatson	struct kaudit_record *ar;
106155192Srwatson
107155192Srwatson	ar = currecord();
108155192Srwatson	if (ar == NULL)
109155192Srwatson		return;
110155192Srwatson
111155192Srwatson	ar->k_ar.ar_arg_fd = fd;
112155192Srwatson	ARG_SET_VALID(ar, ARG_FD);
113155192Srwatson}
114155192Srwatson
115155192Srwatsonvoid
116155192Srwatsonaudit_arg_fflags(int fflags)
117155192Srwatson{
118155192Srwatson	struct kaudit_record *ar;
119155192Srwatson
120155192Srwatson	ar = currecord();
121155192Srwatson	if (ar == NULL)
122155192Srwatson		return;
123155192Srwatson
124155192Srwatson	ar->k_ar.ar_arg_fflags = fflags;
125155192Srwatson	ARG_SET_VALID(ar, ARG_FFLAGS);
126155192Srwatson}
127155192Srwatson
128155192Srwatsonvoid
129155192Srwatsonaudit_arg_gid(gid_t gid)
130155192Srwatson{
131155192Srwatson	struct kaudit_record *ar;
132155192Srwatson
133155192Srwatson	ar = currecord();
134155192Srwatson	if (ar == NULL)
135155192Srwatson		return;
136155192Srwatson
137155192Srwatson	ar->k_ar.ar_arg_gid = gid;
138155192Srwatson	ARG_SET_VALID(ar, ARG_GID);
139155192Srwatson}
140155192Srwatson
141155192Srwatsonvoid
142155192Srwatsonaudit_arg_uid(uid_t uid)
143155192Srwatson{
144155192Srwatson	struct kaudit_record *ar;
145155192Srwatson
146155192Srwatson	ar = currecord();
147155192Srwatson	if (ar == NULL)
148155192Srwatson		return;
149155192Srwatson
150155192Srwatson	ar->k_ar.ar_arg_uid = uid;
151155192Srwatson	ARG_SET_VALID(ar, ARG_UID);
152155192Srwatson}
153155192Srwatson
154155192Srwatsonvoid
155155192Srwatsonaudit_arg_egid(gid_t egid)
156155192Srwatson{
157155192Srwatson	struct kaudit_record *ar;
158155192Srwatson
159155192Srwatson	ar = currecord();
160155192Srwatson	if (ar == NULL)
161155192Srwatson		return;
162155192Srwatson
163155192Srwatson	ar->k_ar.ar_arg_egid = egid;
164155192Srwatson	ARG_SET_VALID(ar, ARG_EGID);
165155192Srwatson}
166155192Srwatson
167155192Srwatsonvoid
168155192Srwatsonaudit_arg_euid(uid_t euid)
169155192Srwatson{
170155192Srwatson	struct kaudit_record *ar;
171155192Srwatson
172155192Srwatson	ar = currecord();
173155192Srwatson	if (ar == NULL)
174155192Srwatson		return;
175155192Srwatson
176155192Srwatson	ar->k_ar.ar_arg_euid = euid;
177155192Srwatson	ARG_SET_VALID(ar, ARG_EUID);
178155192Srwatson}
179155192Srwatson
180155192Srwatsonvoid
181155192Srwatsonaudit_arg_rgid(gid_t rgid)
182155192Srwatson{
183155192Srwatson	struct kaudit_record *ar;
184155192Srwatson
185155192Srwatson	ar = currecord();
186155192Srwatson	if (ar == NULL)
187155192Srwatson		return;
188155192Srwatson
189155192Srwatson	ar->k_ar.ar_arg_rgid = rgid;
190155192Srwatson	ARG_SET_VALID(ar, ARG_RGID);
191155192Srwatson}
192155192Srwatson
193155192Srwatsonvoid
194155192Srwatsonaudit_arg_ruid(uid_t ruid)
195155192Srwatson{
196155192Srwatson	struct kaudit_record *ar;
197155192Srwatson
198155192Srwatson	ar = currecord();
199155192Srwatson	if (ar == NULL)
200155192Srwatson		return;
201155192Srwatson
202155192Srwatson	ar->k_ar.ar_arg_ruid = ruid;
203155192Srwatson	ARG_SET_VALID(ar, ARG_RUID);
204155192Srwatson}
205155192Srwatson
206155192Srwatsonvoid
207155192Srwatsonaudit_arg_sgid(gid_t sgid)
208155192Srwatson{
209155192Srwatson	struct kaudit_record *ar;
210155192Srwatson
211155192Srwatson	ar = currecord();
212155192Srwatson	if (ar == NULL)
213155192Srwatson		return;
214155192Srwatson
215155192Srwatson	ar->k_ar.ar_arg_sgid = sgid;
216155192Srwatson	ARG_SET_VALID(ar, ARG_SGID);
217155192Srwatson}
218155192Srwatson
219155192Srwatsonvoid
220155192Srwatsonaudit_arg_suid(uid_t suid)
221155192Srwatson{
222155192Srwatson	struct kaudit_record *ar;
223155192Srwatson
224155192Srwatson	ar = currecord();
225155192Srwatson	if (ar == NULL)
226155192Srwatson		return;
227155192Srwatson
228155192Srwatson	ar->k_ar.ar_arg_suid = suid;
229155192Srwatson	ARG_SET_VALID(ar, ARG_SUID);
230155192Srwatson}
231155192Srwatson
232155192Srwatsonvoid
233155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size)
234155192Srwatson{
235155192Srwatson	int i;
236155192Srwatson	struct kaudit_record *ar;
237155192Srwatson
238155192Srwatson	ar = currecord();
239155192Srwatson	if (ar == NULL)
240155192Srwatson		return;
241155192Srwatson
242155192Srwatson	for (i = 0; i < gidset_size; i++)
243155192Srwatson		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
244155192Srwatson	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
245155192Srwatson	ARG_SET_VALID(ar, ARG_GROUPSET);
246155192Srwatson}
247155192Srwatson
248155192Srwatsonvoid
249155192Srwatsonaudit_arg_login(char *login)
250155192Srwatson{
251155192Srwatson	struct kaudit_record *ar;
252155192Srwatson
253155192Srwatson	ar = currecord();
254155192Srwatson	if (ar == NULL)
255155192Srwatson		return;
256155192Srwatson
257155192Srwatson	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
258155192Srwatson	ARG_SET_VALID(ar, ARG_LOGIN);
259155192Srwatson}
260155192Srwatson
261155192Srwatsonvoid
262155192Srwatsonaudit_arg_ctlname(int *name, int namelen)
263155192Srwatson{
264155192Srwatson	struct kaudit_record *ar;
265155192Srwatson
266155192Srwatson	ar = currecord();
267155192Srwatson	if (ar == NULL)
268155192Srwatson		return;
269155192Srwatson
270155192Srwatson	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
271155192Srwatson	ar->k_ar.ar_arg_len = namelen;
272155192Srwatson	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
273155192Srwatson}
274155192Srwatson
275155192Srwatsonvoid
276155192Srwatsonaudit_arg_mask(int mask)
277155192Srwatson{
278155192Srwatson	struct kaudit_record *ar;
279155192Srwatson
280155192Srwatson	ar = currecord();
281155192Srwatson	if (ar == NULL)
282155192Srwatson		return;
283155192Srwatson
284155192Srwatson	ar->k_ar.ar_arg_mask = mask;
285155192Srwatson	ARG_SET_VALID(ar, ARG_MASK);
286155192Srwatson}
287155192Srwatson
288155192Srwatsonvoid
289155192Srwatsonaudit_arg_mode(mode_t mode)
290155192Srwatson{
291155192Srwatson	struct kaudit_record *ar;
292155192Srwatson
293155192Srwatson	ar = currecord();
294155192Srwatson	if (ar == NULL)
295155192Srwatson		return;
296155192Srwatson
297155192Srwatson	ar->k_ar.ar_arg_mode = mode;
298155192Srwatson	ARG_SET_VALID(ar, ARG_MODE);
299155192Srwatson}
300155192Srwatson
301155192Srwatsonvoid
302155192Srwatsonaudit_arg_dev(int dev)
303155192Srwatson{
304155192Srwatson	struct kaudit_record *ar;
305155192Srwatson
306155192Srwatson	ar = currecord();
307155192Srwatson	if (ar == NULL)
308155192Srwatson		return;
309155192Srwatson
310155192Srwatson	ar->k_ar.ar_arg_dev = dev;
311155192Srwatson	ARG_SET_VALID(ar, ARG_DEV);
312155192Srwatson}
313155192Srwatson
314155192Srwatsonvoid
315155192Srwatsonaudit_arg_value(long value)
316155192Srwatson{
317155192Srwatson	struct kaudit_record *ar;
318155192Srwatson
319155192Srwatson	ar = currecord();
320155192Srwatson	if (ar == NULL)
321155192Srwatson		return;
322155192Srwatson
323155192Srwatson	ar->k_ar.ar_arg_value = value;
324155192Srwatson	ARG_SET_VALID(ar, ARG_VALUE);
325155192Srwatson}
326155192Srwatson
327155192Srwatsonvoid
328155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid)
329155192Srwatson{
330155192Srwatson	struct kaudit_record *ar;
331155192Srwatson
332155192Srwatson	ar = currecord();
333155192Srwatson	if (ar == NULL)
334155192Srwatson		return;
335155192Srwatson
336155192Srwatson	ar->k_ar.ar_arg_uid = uid;
337155192Srwatson	ar->k_ar.ar_arg_gid = gid;
338155192Srwatson	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
339155192Srwatson}
340155192Srwatson
341155192Srwatsonvoid
342155192Srwatsonaudit_arg_pid(pid_t pid)
343155192Srwatson{
344155192Srwatson	struct kaudit_record *ar;
345155192Srwatson
346155192Srwatson	ar = currecord();
347155192Srwatson	if (ar == NULL)
348155192Srwatson		return;
349155192Srwatson
350155192Srwatson	ar->k_ar.ar_arg_pid = pid;
351155192Srwatson	ARG_SET_VALID(ar, ARG_PID);
352155192Srwatson}
353155192Srwatson
354155192Srwatsonvoid
355155192Srwatsonaudit_arg_process(struct proc *p)
356155192Srwatson{
357155192Srwatson	struct kaudit_record *ar;
358155192Srwatson
359160086Srwatson	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
360160086Srwatson
361160086Srwatson	PROC_LOCK_ASSERT(p, MA_OWNED);
362160086Srwatson
363155192Srwatson	ar = currecord();
364160086Srwatson	if (ar == NULL)
365155192Srwatson		return;
366155192Srwatson
367170407Srwatson	ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid;
368155192Srwatson	ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
369155192Srwatson	ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
370155192Srwatson	ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
371155192Srwatson	ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
372170407Srwatson	ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid;
373170407Srwatson	ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid;
374159277Srwatson	ar->k_ar.ar_arg_pid = p->p_pid;
375155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
376168688Scsjp	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
377155192Srwatson}
378155192Srwatson
379155192Srwatsonvoid
380155192Srwatsonaudit_arg_signum(u_int signum)
381155192Srwatson{
382155192Srwatson	struct kaudit_record *ar;
383155192Srwatson
384155192Srwatson	ar = currecord();
385155192Srwatson	if (ar == NULL)
386155192Srwatson		return;
387155192Srwatson
388155192Srwatson	ar->k_ar.ar_arg_signum = signum;
389155192Srwatson	ARG_SET_VALID(ar, ARG_SIGNUM);
390155192Srwatson}
391155192Srwatson
392155192Srwatsonvoid
393155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol)
394155192Srwatson{
395155192Srwatson	struct kaudit_record *ar;
396156889Srwatson
397155192Srwatson	ar = currecord();
398155192Srwatson	if (ar == NULL)
399155192Srwatson		return;
400155192Srwatson
401155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
402155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
403155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
404155192Srwatson	ARG_SET_VALID(ar, ARG_SOCKINFO);
405155192Srwatson}
406155192Srwatson
407155192Srwatsonvoid
408160086Srwatsonaudit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
409155192Srwatson{
410155192Srwatson	struct kaudit_record *ar;
411155192Srwatson
412160086Srwatson	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
413160086Srwatson	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
414160086Srwatson
415155192Srwatson	ar = currecord();
416160086Srwatson	if (ar == NULL)
417155192Srwatson		return;
418155192Srwatson
419164011Scsjp	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
420160086Srwatson	switch (sa->sa_family) {
421155192Srwatson	case AF_INET:
422155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET);
423155192Srwatson		break;
424155192Srwatson
425155192Srwatson	case AF_INET6:
426155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET6);
427155192Srwatson		break;
428155192Srwatson
429155192Srwatson	case AF_UNIX:
430160086Srwatson		audit_arg_upath(td, ((struct sockaddr_un *)sa)->sun_path,
431155192Srwatson				ARG_UPATH1);
432155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRUNIX);
433155192Srwatson		break;
434155192Srwatson	/* XXXAUDIT: default:? */
435155192Srwatson	}
436155192Srwatson}
437155192Srwatson
438155192Srwatsonvoid
439155192Srwatsonaudit_arg_auid(uid_t auid)
440155192Srwatson{
441155192Srwatson	struct kaudit_record *ar;
442155192Srwatson
443155192Srwatson	ar = currecord();
444155192Srwatson	if (ar == NULL)
445155192Srwatson		return;
446155192Srwatson
447155192Srwatson	ar->k_ar.ar_arg_auid = auid;
448155192Srwatson	ARG_SET_VALID(ar, ARG_AUID);
449155192Srwatson}
450155192Srwatson
451155192Srwatsonvoid
452155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info)
453155192Srwatson{
454155192Srwatson	struct kaudit_record *ar;
455155192Srwatson
456155192Srwatson	ar = currecord();
457155192Srwatson	if (ar == NULL)
458155192Srwatson		return;
459155192Srwatson
460155192Srwatson	ar->k_ar.ar_arg_auid = au_info->ai_auid;
461155192Srwatson	ar->k_ar.ar_arg_asid = au_info->ai_asid;
462155192Srwatson	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
463155192Srwatson	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
464155192Srwatson	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
465155192Srwatson	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
466155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
467155192Srwatson}
468155192Srwatson
469155192Srwatsonvoid
470155192Srwatsonaudit_arg_text(char *text)
471155192Srwatson{
472155192Srwatson	struct kaudit_record *ar;
473155192Srwatson
474160086Srwatson	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
475160086Srwatson
476155192Srwatson	ar = currecord();
477155192Srwatson	if (ar == NULL)
478155192Srwatson		return;
479155192Srwatson
480155192Srwatson	/* Invalidate the text string */
481155192Srwatson	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
482155192Srwatson
483155192Srwatson	if (ar->k_ar.ar_arg_text == NULL)
484155192Srwatson		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
485155192Srwatson		    M_WAITOK);
486155192Srwatson
487155192Srwatson	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
488155192Srwatson	ARG_SET_VALID(ar, ARG_TEXT);
489155192Srwatson}
490155192Srwatson
491155192Srwatsonvoid
492155192Srwatsonaudit_arg_cmd(int cmd)
493155192Srwatson{
494155192Srwatson	struct kaudit_record *ar;
495155192Srwatson
496155192Srwatson	ar = currecord();
497155192Srwatson	if (ar == NULL)
498155192Srwatson		return;
499155192Srwatson
500155192Srwatson	ar->k_ar.ar_arg_cmd = cmd;
501155192Srwatson	ARG_SET_VALID(ar, ARG_CMD);
502155192Srwatson}
503155192Srwatson
504155192Srwatsonvoid
505155192Srwatsonaudit_arg_svipc_cmd(int cmd)
506155192Srwatson{
507155192Srwatson	struct kaudit_record *ar;
508155192Srwatson
509155192Srwatson	ar = currecord();
510155192Srwatson	if (ar == NULL)
511155192Srwatson		return;
512155192Srwatson
513155192Srwatson	ar->k_ar.ar_arg_svipc_cmd = cmd;
514155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
515155192Srwatson}
516155192Srwatson
517155192Srwatsonvoid
518155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm)
519155192Srwatson{
520155192Srwatson	struct kaudit_record *ar;
521155192Srwatson
522155192Srwatson	ar = currecord();
523155192Srwatson	if (ar == NULL)
524155192Srwatson		return;
525155192Srwatson
526156889Srwatson	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
527156889Srwatson	    sizeof(ar->k_ar.ar_arg_svipc_perm));
528155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
529155192Srwatson}
530155192Srwatson
531155192Srwatsonvoid
532155192Srwatsonaudit_arg_svipc_id(int id)
533155192Srwatson{
534155192Srwatson	struct kaudit_record *ar;
535155192Srwatson
536155192Srwatson	ar = currecord();
537155192Srwatson	if (ar == NULL)
538155192Srwatson		return;
539155192Srwatson
540155192Srwatson	ar->k_ar.ar_arg_svipc_id = id;
541155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ID);
542155192Srwatson}
543155192Srwatson
544155192Srwatsonvoid
545155192Srwatsonaudit_arg_svipc_addr(void * addr)
546155192Srwatson{
547155192Srwatson	struct kaudit_record *ar;
548155192Srwatson
549155192Srwatson	ar = currecord();
550155192Srwatson	if (ar == NULL)
551155192Srwatson		return;
552155192Srwatson
553155192Srwatson	ar->k_ar.ar_arg_svipc_addr = addr;
554155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
555155192Srwatson}
556155192Srwatson
557155192Srwatsonvoid
558155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
559155192Srwatson{
560155192Srwatson	struct kaudit_record *ar;
561155192Srwatson
562155192Srwatson	ar = currecord();
563155192Srwatson	if (ar == NULL)
564155192Srwatson		return;
565155192Srwatson
566155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
567155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
568155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
569155192Srwatson	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
570155192Srwatson}
571155192Srwatson
572155192Srwatsonvoid
573155192Srwatsonaudit_arg_auditon(union auditon_udata *udata)
574155192Srwatson{
575155192Srwatson	struct kaudit_record *ar;
576155192Srwatson
577155192Srwatson	ar = currecord();
578155192Srwatson	if (ar == NULL)
579155192Srwatson		return;
580155192Srwatson
581156889Srwatson	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
582156889Srwatson	    sizeof(ar->k_ar.ar_arg_auditon));
583155192Srwatson	ARG_SET_VALID(ar, ARG_AUDITON);
584155192Srwatson}
585155192Srwatson
586155192Srwatson/*
587155192Srwatson * Audit information about a file, either the file's vnode info, or its
588155192Srwatson * socket address info.
589155192Srwatson */
590155192Srwatsonvoid
591155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp)
592155192Srwatson{
593155192Srwatson	struct kaudit_record *ar;
594155192Srwatson	struct socket *so;
595155192Srwatson	struct inpcb *pcb;
596155192Srwatson	struct vnode *vp;
597155192Srwatson	int vfslocked;
598155192Srwatson
599160086Srwatson	ar = currecord();
600160086Srwatson	if (ar == NULL)
601160086Srwatson		return;
602160086Srwatson
603155192Srwatson	switch (fp->f_type) {
604155192Srwatson	case DTYPE_VNODE:
605155192Srwatson	case DTYPE_FIFO:
606155192Srwatson		/*
607155192Srwatson		 * XXXAUDIT: Only possibly to record as first vnode?
608155192Srwatson		 */
609155192Srwatson		vp = fp->f_vnode;
610155192Srwatson		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
611155192Srwatson		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
612155192Srwatson		audit_arg_vnode(vp, ARG_VNODE1);
613155192Srwatson		VOP_UNLOCK(vp, 0, curthread);
614155192Srwatson		VFS_UNLOCK_GIANT(vfslocked);
615155192Srwatson		break;
616155192Srwatson
617155192Srwatson	case DTYPE_SOCKET:
618155192Srwatson		so = (struct socket *)fp->f_data;
619155192Srwatson		if (INP_CHECK_SOCKAF(so, PF_INET)) {
620166845Srwatson			SOCK_LOCK(so);
621155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_type =
622156889Srwatson			    so->so_type;
623155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_domain =
624156889Srwatson			    INP_SOCKAF(so);
625155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_protocol =
626156889Srwatson			    so->so_proto->pr_protocol;
627166845Srwatson			SOCK_UNLOCK(so);
628155192Srwatson			pcb = (struct inpcb *)so->so_pcb;
629166845Srwatson			INP_LOCK(pcb);
630155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_raddr =
631156889Srwatson			    pcb->inp_faddr.s_addr;
632155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_laddr =
633156889Srwatson			    pcb->inp_laddr.s_addr;
634155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_rport =
635156889Srwatson			    pcb->inp_fport;
636155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_lport =
637156889Srwatson			    pcb->inp_lport;
638166845Srwatson			INP_UNLOCK(pcb);
639155192Srwatson			ARG_SET_VALID(ar, ARG_SOCKINFO);
640155192Srwatson		}
641155192Srwatson		break;
642155192Srwatson
643155192Srwatson	default:
644155192Srwatson		/* XXXAUDIT: else? */
645155192Srwatson		break;
646155192Srwatson	}
647155192Srwatson}
648155192Srwatson
649156889Srwatson/*
650156889Srwatson * Store a path as given by the user process for auditing into the audit
651156889Srwatson * record stored on the user thread. This function will allocate the memory
652156889Srwatson * to store the path info if not already available. This memory will be freed
653156889Srwatson * when the audit record is freed.
654155192Srwatson *
655155192Srwatson * XXXAUDIT: Possibly assert that the memory isn't already allocated?
656155192Srwatson */
657155192Srwatsonvoid
658155192Srwatsonaudit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
659155192Srwatson{
660155192Srwatson	struct kaudit_record *ar;
661155192Srwatson	char **pathp;
662155192Srwatson
663160086Srwatson	KASSERT(td != NULL, ("audit_arg_upath: td == NULL"));
664160086Srwatson	KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL"));
665155192Srwatson
666160086Srwatson	ar = currecord();
667160086Srwatson	if (ar == NULL)
668160086Srwatson		return;
669160086Srwatson
670155192Srwatson	KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2),
671155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
672155192Srwatson	KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2),
673155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
674155192Srwatson
675155192Srwatson	if (flag == ARG_UPATH1)
676155192Srwatson		pathp = &ar->k_ar.ar_arg_upath1;
677155192Srwatson	else
678155192Srwatson		pathp = &ar->k_ar.ar_arg_upath2;
679155192Srwatson
680155192Srwatson	if (*pathp == NULL)
681155192Srwatson		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
682155192Srwatson
683155192Srwatson	canon_path(td, upath, *pathp);
684155192Srwatson
685155192Srwatson	ARG_SET_VALID(ar, flag);
686155192Srwatson}
687155192Srwatson
688155192Srwatson/*
689156889Srwatson * Function to save the path and vnode attr information into the audit
690156889Srwatson * record.
691155192Srwatson *
692155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to
693155192Srwatson * perform a VOP_GETATTR() on the passed vnode.
694155192Srwatson *
695170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
696170196Srwatson * provides access to the generation number as we need that to construct the
697170196Srwatson * BSM file ID.
698170196Srwatson *
699170196Srwatson * XXX: We should accept the process argument from the caller, since it's
700170196Srwatson * very likely they already have a reference.
701170196Srwatson *
702155192Srwatson * XXX: Error handling in this function is poor.
703155192Srwatson *
704155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
705155192Srwatson */
706155192Srwatsonvoid
707155192Srwatsonaudit_arg_vnode(struct vnode *vp, u_int64_t flags)
708155192Srwatson{
709155192Srwatson	struct kaudit_record *ar;
710155192Srwatson	struct vattr vattr;
711155192Srwatson	int error;
712155192Srwatson	struct vnode_au_info *vnp;
713155192Srwatson
714160086Srwatson	KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL"));
715160086Srwatson	KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2),
716160086Srwatson	    ("audit_arg_vnode: flags %jd", (intmax_t)flags));
717155192Srwatson
718155192Srwatson	/*
719155192Srwatson	 * Assume that if the caller is calling audit_arg_vnode() on a
720155192Srwatson	 * non-MPSAFE vnode, then it will have acquired Giant.
721155192Srwatson	 */
722155192Srwatson	VFS_ASSERT_GIANT(vp->v_mount);
723155192Srwatson	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
724155192Srwatson
725155192Srwatson	ar = currecord();
726156889Srwatson	if (ar == NULL)
727155192Srwatson		return;
728155192Srwatson
729155192Srwatson	/*
730155192Srwatson	 * XXXAUDIT: The below clears, and then resets the flags for valid
731155192Srwatson	 * arguments.  Ideally, either the new vnode is used, or the old one
732155192Srwatson	 * would be.
733155192Srwatson	 */
734155192Srwatson	if (flags & ARG_VNODE1) {
735155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
736155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode1;
737155192Srwatson	} else {
738155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
739155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode2;
740155192Srwatson	}
741155192Srwatson
742160086Srwatson	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred, curthread);
743155192Srwatson	if (error) {
744155192Srwatson		/* XXX: How to handle this case? */
745155192Srwatson		return;
746155192Srwatson	}
747155192Srwatson
748155192Srwatson	vnp->vn_mode = vattr.va_mode;
749155192Srwatson	vnp->vn_uid = vattr.va_uid;
750155192Srwatson	vnp->vn_gid = vattr.va_gid;
751155192Srwatson	vnp->vn_dev = vattr.va_rdev;
752155192Srwatson	vnp->vn_fsid = vattr.va_fsid;
753155192Srwatson	vnp->vn_fileid = vattr.va_fileid;
754155192Srwatson	vnp->vn_gen = vattr.va_gen;
755155192Srwatson	if (flags & ARG_VNODE1)
756155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE1);
757155192Srwatson	else
758155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE2);
759155192Srwatson}
760155192Srwatson
761155192Srwatson/*
762161813Swsalamon * Audit the argument strings passed to exec.
763161813Swsalamon */
764161813Swsalamonvoid
765161813Swsalamonaudit_arg_argv(char *argv, int argc, int length)
766161813Swsalamon{
767161813Swsalamon	struct kaudit_record *ar;
768161813Swsalamon
769161813Swsalamon	if (audit_argv == 0)
770161813Swsalamon		return;
771161813Swsalamon
772161813Swsalamon	ar = currecord();
773161813Swsalamon	if (ar == NULL)
774161813Swsalamon		return;
775161813Swsalamon
776161813Swsalamon	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
777161813Swsalamon	bcopy(argv, ar->k_ar.ar_arg_argv, length);
778161813Swsalamon	ar->k_ar.ar_arg_argc = argc;
779161813Swsalamon	ARG_SET_VALID(ar, ARG_ARGV);
780161813Swsalamon}
781161813Swsalamon
782161813Swsalamon/*
783161813Swsalamon * Audit the environment strings passed to exec.
784161813Swsalamon */
785161813Swsalamonvoid
786161813Swsalamonaudit_arg_envv(char *envv, int envc, int length)
787161813Swsalamon{
788161813Swsalamon	struct kaudit_record *ar;
789161813Swsalamon
790161813Swsalamon	if (audit_arge == 0)
791161813Swsalamon		return;
792161813Swsalamon
793161813Swsalamon	ar = currecord();
794161813Swsalamon	if (ar == NULL)
795161813Swsalamon		return;
796161813Swsalamon
797161813Swsalamon	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
798161813Swsalamon	bcopy(envv, ar->k_ar.ar_arg_envv, length);
799161813Swsalamon	ar->k_ar.ar_arg_envc = envc;
800161813Swsalamon	ARG_SET_VALID(ar, ARG_ENVV);
801161813Swsalamon}
802161813Swsalamon
803161813Swsalamon/*
804156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode
805156889Srwatson * information because those pieces are not easily obtained within the system
806156889Srwatson * call itself.
807155192Srwatson */
808155192Srwatsonvoid
809155192Srwatsonaudit_sysclose(struct thread *td, int fd)
810155192Srwatson{
811160086Srwatson	struct kaudit_record *ar;
812155192Srwatson	struct vnode *vp;
813155192Srwatson	struct file *fp;
814155192Srwatson	int vfslocked;
815155192Srwatson
816160086Srwatson	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
817160086Srwatson
818160086Srwatson	ar = currecord();
819160086Srwatson	if (ar == NULL)
820160086Srwatson		return;
821160086Srwatson
822155192Srwatson	audit_arg_fd(fd);
823155192Srwatson
824155192Srwatson	if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
825155192Srwatson		return;
826155192Srwatson
827155192Srwatson	vp = fp->f_vnode;
828155192Srwatson	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
829155192Srwatson	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
830155192Srwatson	audit_arg_vnode(vp, ARG_VNODE1);
831155192Srwatson	VOP_UNLOCK(vp, 0, td);
832155192Srwatson	VFS_UNLOCK_GIANT(vfslocked);
833155192Srwatson	fdrop(fp, td);
834156889Srwatson}
835