audit_arg.c revision 180699
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
30178186Srwatson#include <sys/cdefs.h>
31178186Srwatson__FBSDID("$FreeBSD: head/sys/security/audit/audit_arg.c 180699 2008-07-22 15:17:21Z 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
104155192Srwatsonaudit_arg_fd(int fd)
105155192Srwatson{
106155192Srwatson	struct kaudit_record *ar;
107155192Srwatson
108155192Srwatson	ar = currecord();
109155192Srwatson	if (ar == NULL)
110155192Srwatson		return;
111155192Srwatson
112155192Srwatson	ar->k_ar.ar_arg_fd = fd;
113155192Srwatson	ARG_SET_VALID(ar, ARG_FD);
114155192Srwatson}
115155192Srwatson
116155192Srwatsonvoid
117155192Srwatsonaudit_arg_fflags(int fflags)
118155192Srwatson{
119155192Srwatson	struct kaudit_record *ar;
120155192Srwatson
121155192Srwatson	ar = currecord();
122155192Srwatson	if (ar == NULL)
123155192Srwatson		return;
124155192Srwatson
125155192Srwatson	ar->k_ar.ar_arg_fflags = fflags;
126155192Srwatson	ARG_SET_VALID(ar, ARG_FFLAGS);
127155192Srwatson}
128155192Srwatson
129155192Srwatsonvoid
130155192Srwatsonaudit_arg_gid(gid_t gid)
131155192Srwatson{
132155192Srwatson	struct kaudit_record *ar;
133155192Srwatson
134155192Srwatson	ar = currecord();
135155192Srwatson	if (ar == NULL)
136155192Srwatson		return;
137155192Srwatson
138155192Srwatson	ar->k_ar.ar_arg_gid = gid;
139155192Srwatson	ARG_SET_VALID(ar, ARG_GID);
140155192Srwatson}
141155192Srwatson
142155192Srwatsonvoid
143155192Srwatsonaudit_arg_uid(uid_t uid)
144155192Srwatson{
145155192Srwatson	struct kaudit_record *ar;
146155192Srwatson
147155192Srwatson	ar = currecord();
148155192Srwatson	if (ar == NULL)
149155192Srwatson		return;
150155192Srwatson
151155192Srwatson	ar->k_ar.ar_arg_uid = uid;
152155192Srwatson	ARG_SET_VALID(ar, ARG_UID);
153155192Srwatson}
154155192Srwatson
155155192Srwatsonvoid
156155192Srwatsonaudit_arg_egid(gid_t egid)
157155192Srwatson{
158155192Srwatson	struct kaudit_record *ar;
159155192Srwatson
160155192Srwatson	ar = currecord();
161155192Srwatson	if (ar == NULL)
162155192Srwatson		return;
163155192Srwatson
164155192Srwatson	ar->k_ar.ar_arg_egid = egid;
165155192Srwatson	ARG_SET_VALID(ar, ARG_EGID);
166155192Srwatson}
167155192Srwatson
168155192Srwatsonvoid
169155192Srwatsonaudit_arg_euid(uid_t euid)
170155192Srwatson{
171155192Srwatson	struct kaudit_record *ar;
172155192Srwatson
173155192Srwatson	ar = currecord();
174155192Srwatson	if (ar == NULL)
175155192Srwatson		return;
176155192Srwatson
177155192Srwatson	ar->k_ar.ar_arg_euid = euid;
178155192Srwatson	ARG_SET_VALID(ar, ARG_EUID);
179155192Srwatson}
180155192Srwatson
181155192Srwatsonvoid
182155192Srwatsonaudit_arg_rgid(gid_t rgid)
183155192Srwatson{
184155192Srwatson	struct kaudit_record *ar;
185155192Srwatson
186155192Srwatson	ar = currecord();
187155192Srwatson	if (ar == NULL)
188155192Srwatson		return;
189155192Srwatson
190155192Srwatson	ar->k_ar.ar_arg_rgid = rgid;
191155192Srwatson	ARG_SET_VALID(ar, ARG_RGID);
192155192Srwatson}
193155192Srwatson
194155192Srwatsonvoid
195155192Srwatsonaudit_arg_ruid(uid_t ruid)
196155192Srwatson{
197155192Srwatson	struct kaudit_record *ar;
198155192Srwatson
199155192Srwatson	ar = currecord();
200155192Srwatson	if (ar == NULL)
201155192Srwatson		return;
202155192Srwatson
203155192Srwatson	ar->k_ar.ar_arg_ruid = ruid;
204155192Srwatson	ARG_SET_VALID(ar, ARG_RUID);
205155192Srwatson}
206155192Srwatson
207155192Srwatsonvoid
208155192Srwatsonaudit_arg_sgid(gid_t sgid)
209155192Srwatson{
210155192Srwatson	struct kaudit_record *ar;
211155192Srwatson
212155192Srwatson	ar = currecord();
213155192Srwatson	if (ar == NULL)
214155192Srwatson		return;
215155192Srwatson
216155192Srwatson	ar->k_ar.ar_arg_sgid = sgid;
217155192Srwatson	ARG_SET_VALID(ar, ARG_SGID);
218155192Srwatson}
219155192Srwatson
220155192Srwatsonvoid
221155192Srwatsonaudit_arg_suid(uid_t suid)
222155192Srwatson{
223155192Srwatson	struct kaudit_record *ar;
224155192Srwatson
225155192Srwatson	ar = currecord();
226155192Srwatson	if (ar == NULL)
227155192Srwatson		return;
228155192Srwatson
229155192Srwatson	ar->k_ar.ar_arg_suid = suid;
230155192Srwatson	ARG_SET_VALID(ar, ARG_SUID);
231155192Srwatson}
232155192Srwatson
233155192Srwatsonvoid
234155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size)
235155192Srwatson{
236180699Srwatson	u_int i;
237155192Srwatson	struct kaudit_record *ar;
238155192Srwatson
239155192Srwatson	ar = currecord();
240155192Srwatson	if (ar == NULL)
241155192Srwatson		return;
242155192Srwatson
243155192Srwatson	for (i = 0; i < gidset_size; i++)
244155192Srwatson		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
245155192Srwatson	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
246155192Srwatson	ARG_SET_VALID(ar, ARG_GROUPSET);
247155192Srwatson}
248155192Srwatson
249155192Srwatsonvoid
250155192Srwatsonaudit_arg_login(char *login)
251155192Srwatson{
252155192Srwatson	struct kaudit_record *ar;
253155192Srwatson
254155192Srwatson	ar = currecord();
255155192Srwatson	if (ar == NULL)
256155192Srwatson		return;
257155192Srwatson
258155192Srwatson	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
259155192Srwatson	ARG_SET_VALID(ar, ARG_LOGIN);
260155192Srwatson}
261155192Srwatson
262155192Srwatsonvoid
263155192Srwatsonaudit_arg_ctlname(int *name, int namelen)
264155192Srwatson{
265155192Srwatson	struct kaudit_record *ar;
266155192Srwatson
267155192Srwatson	ar = currecord();
268155192Srwatson	if (ar == NULL)
269155192Srwatson		return;
270155192Srwatson
271155192Srwatson	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
272155192Srwatson	ar->k_ar.ar_arg_len = namelen;
273155192Srwatson	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
274155192Srwatson}
275155192Srwatson
276155192Srwatsonvoid
277155192Srwatsonaudit_arg_mask(int mask)
278155192Srwatson{
279155192Srwatson	struct kaudit_record *ar;
280155192Srwatson
281155192Srwatson	ar = currecord();
282155192Srwatson	if (ar == NULL)
283155192Srwatson		return;
284155192Srwatson
285155192Srwatson	ar->k_ar.ar_arg_mask = mask;
286155192Srwatson	ARG_SET_VALID(ar, ARG_MASK);
287155192Srwatson}
288155192Srwatson
289155192Srwatsonvoid
290155192Srwatsonaudit_arg_mode(mode_t mode)
291155192Srwatson{
292155192Srwatson	struct kaudit_record *ar;
293155192Srwatson
294155192Srwatson	ar = currecord();
295155192Srwatson	if (ar == NULL)
296155192Srwatson		return;
297155192Srwatson
298155192Srwatson	ar->k_ar.ar_arg_mode = mode;
299155192Srwatson	ARG_SET_VALID(ar, ARG_MODE);
300155192Srwatson}
301155192Srwatson
302155192Srwatsonvoid
303155192Srwatsonaudit_arg_dev(int dev)
304155192Srwatson{
305155192Srwatson	struct kaudit_record *ar;
306155192Srwatson
307155192Srwatson	ar = currecord();
308155192Srwatson	if (ar == NULL)
309155192Srwatson		return;
310155192Srwatson
311155192Srwatson	ar->k_ar.ar_arg_dev = dev;
312155192Srwatson	ARG_SET_VALID(ar, ARG_DEV);
313155192Srwatson}
314155192Srwatson
315155192Srwatsonvoid
316155192Srwatsonaudit_arg_value(long value)
317155192Srwatson{
318155192Srwatson	struct kaudit_record *ar;
319155192Srwatson
320155192Srwatson	ar = currecord();
321155192Srwatson	if (ar == NULL)
322155192Srwatson		return;
323155192Srwatson
324155192Srwatson	ar->k_ar.ar_arg_value = value;
325155192Srwatson	ARG_SET_VALID(ar, ARG_VALUE);
326155192Srwatson}
327155192Srwatson
328155192Srwatsonvoid
329155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid)
330155192Srwatson{
331155192Srwatson	struct kaudit_record *ar;
332155192Srwatson
333155192Srwatson	ar = currecord();
334155192Srwatson	if (ar == NULL)
335155192Srwatson		return;
336155192Srwatson
337155192Srwatson	ar->k_ar.ar_arg_uid = uid;
338155192Srwatson	ar->k_ar.ar_arg_gid = gid;
339155192Srwatson	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
340155192Srwatson}
341155192Srwatson
342155192Srwatsonvoid
343155192Srwatsonaudit_arg_pid(pid_t pid)
344155192Srwatson{
345155192Srwatson	struct kaudit_record *ar;
346155192Srwatson
347155192Srwatson	ar = currecord();
348155192Srwatson	if (ar == NULL)
349155192Srwatson		return;
350155192Srwatson
351155192Srwatson	ar->k_ar.ar_arg_pid = pid;
352155192Srwatson	ARG_SET_VALID(ar, ARG_PID);
353155192Srwatson}
354155192Srwatson
355155192Srwatsonvoid
356155192Srwatsonaudit_arg_process(struct proc *p)
357155192Srwatson{
358155192Srwatson	struct kaudit_record *ar;
359155192Srwatson
360160086Srwatson	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
361160086Srwatson
362160086Srwatson	PROC_LOCK_ASSERT(p, MA_OWNED);
363160086Srwatson
364155192Srwatson	ar = currecord();
365160086Srwatson	if (ar == NULL)
366155192Srwatson		return;
367155192Srwatson
368170407Srwatson	ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid;
369155192Srwatson	ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
370155192Srwatson	ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
371155192Srwatson	ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
372155192Srwatson	ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
373170407Srwatson	ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid;
374170407Srwatson	ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid;
375159277Srwatson	ar->k_ar.ar_arg_pid = p->p_pid;
376155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
377168688Scsjp	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
378155192Srwatson}
379155192Srwatson
380155192Srwatsonvoid
381155192Srwatsonaudit_arg_signum(u_int signum)
382155192Srwatson{
383155192Srwatson	struct kaudit_record *ar;
384155192Srwatson
385155192Srwatson	ar = currecord();
386155192Srwatson	if (ar == NULL)
387155192Srwatson		return;
388155192Srwatson
389155192Srwatson	ar->k_ar.ar_arg_signum = signum;
390155192Srwatson	ARG_SET_VALID(ar, ARG_SIGNUM);
391155192Srwatson}
392155192Srwatson
393155192Srwatsonvoid
394155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol)
395155192Srwatson{
396155192Srwatson	struct kaudit_record *ar;
397156889Srwatson
398155192Srwatson	ar = currecord();
399155192Srwatson	if (ar == NULL)
400155192Srwatson		return;
401155192Srwatson
402155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
403155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
404155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
405155192Srwatson	ARG_SET_VALID(ar, ARG_SOCKINFO);
406155192Srwatson}
407155192Srwatson
408155192Srwatsonvoid
409160086Srwatsonaudit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
410155192Srwatson{
411155192Srwatson	struct kaudit_record *ar;
412155192Srwatson
413160086Srwatson	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
414160086Srwatson	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
415160086Srwatson
416155192Srwatson	ar = currecord();
417160086Srwatson	if (ar == NULL)
418155192Srwatson		return;
419155192Srwatson
420164011Scsjp	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
421160086Srwatson	switch (sa->sa_family) {
422155192Srwatson	case AF_INET:
423155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET);
424155192Srwatson		break;
425155192Srwatson
426155192Srwatson	case AF_INET6:
427155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET6);
428155192Srwatson		break;
429155192Srwatson
430155192Srwatson	case AF_UNIX:
431160086Srwatson		audit_arg_upath(td, ((struct sockaddr_un *)sa)->sun_path,
432155192Srwatson				ARG_UPATH1);
433155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRUNIX);
434155192Srwatson		break;
435155192Srwatson	/* XXXAUDIT: default:? */
436155192Srwatson	}
437155192Srwatson}
438155192Srwatson
439155192Srwatsonvoid
440155192Srwatsonaudit_arg_auid(uid_t auid)
441155192Srwatson{
442155192Srwatson	struct kaudit_record *ar;
443155192Srwatson
444155192Srwatson	ar = currecord();
445155192Srwatson	if (ar == NULL)
446155192Srwatson		return;
447155192Srwatson
448155192Srwatson	ar->k_ar.ar_arg_auid = auid;
449155192Srwatson	ARG_SET_VALID(ar, ARG_AUID);
450155192Srwatson}
451155192Srwatson
452155192Srwatsonvoid
453155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info)
454155192Srwatson{
455155192Srwatson	struct kaudit_record *ar;
456155192Srwatson
457155192Srwatson	ar = currecord();
458155192Srwatson	if (ar == NULL)
459155192Srwatson		return;
460155192Srwatson
461155192Srwatson	ar->k_ar.ar_arg_auid = au_info->ai_auid;
462155192Srwatson	ar->k_ar.ar_arg_asid = au_info->ai_asid;
463155192Srwatson	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
464155192Srwatson	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
465155192Srwatson	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
466155192Srwatson	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
467155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
468155192Srwatson}
469155192Srwatson
470155192Srwatsonvoid
471171066Scsjpaudit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
472171066Scsjp{
473171066Scsjp	struct kaudit_record *ar;
474171066Scsjp
475171066Scsjp	ar = currecord();
476171066Scsjp	if (ar == NULL)
477171066Scsjp		return;
478171066Scsjp
479171066Scsjp	ar->k_ar.ar_arg_auid = au_info->ai_auid;
480171066Scsjp	ar->k_ar.ar_arg_asid = au_info->ai_asid;
481171066Scsjp	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
482171066Scsjp	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
483171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
484171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
485171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
486171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
487171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
488171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
489171066Scsjp	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
490171066Scsjp}
491171066Scsjp
492171066Scsjpvoid
493155192Srwatsonaudit_arg_text(char *text)
494155192Srwatson{
495155192Srwatson	struct kaudit_record *ar;
496155192Srwatson
497160086Srwatson	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
498160086Srwatson
499155192Srwatson	ar = currecord();
500155192Srwatson	if (ar == NULL)
501155192Srwatson		return;
502155192Srwatson
503155192Srwatson	/* Invalidate the text string */
504155192Srwatson	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
505155192Srwatson
506155192Srwatson	if (ar->k_ar.ar_arg_text == NULL)
507155192Srwatson		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
508155192Srwatson		    M_WAITOK);
509155192Srwatson
510155192Srwatson	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
511155192Srwatson	ARG_SET_VALID(ar, ARG_TEXT);
512155192Srwatson}
513155192Srwatson
514155192Srwatsonvoid
515155192Srwatsonaudit_arg_cmd(int cmd)
516155192Srwatson{
517155192Srwatson	struct kaudit_record *ar;
518155192Srwatson
519155192Srwatson	ar = currecord();
520155192Srwatson	if (ar == NULL)
521155192Srwatson		return;
522155192Srwatson
523155192Srwatson	ar->k_ar.ar_arg_cmd = cmd;
524155192Srwatson	ARG_SET_VALID(ar, ARG_CMD);
525155192Srwatson}
526155192Srwatson
527155192Srwatsonvoid
528155192Srwatsonaudit_arg_svipc_cmd(int cmd)
529155192Srwatson{
530155192Srwatson	struct kaudit_record *ar;
531155192Srwatson
532155192Srwatson	ar = currecord();
533155192Srwatson	if (ar == NULL)
534155192Srwatson		return;
535155192Srwatson
536155192Srwatson	ar->k_ar.ar_arg_svipc_cmd = cmd;
537155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
538155192Srwatson}
539155192Srwatson
540155192Srwatsonvoid
541155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm)
542155192Srwatson{
543155192Srwatson	struct kaudit_record *ar;
544155192Srwatson
545155192Srwatson	ar = currecord();
546155192Srwatson	if (ar == NULL)
547155192Srwatson		return;
548155192Srwatson
549156889Srwatson	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
550156889Srwatson	    sizeof(ar->k_ar.ar_arg_svipc_perm));
551155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
552155192Srwatson}
553155192Srwatson
554155192Srwatsonvoid
555155192Srwatsonaudit_arg_svipc_id(int id)
556155192Srwatson{
557155192Srwatson	struct kaudit_record *ar;
558155192Srwatson
559155192Srwatson	ar = currecord();
560155192Srwatson	if (ar == NULL)
561155192Srwatson		return;
562155192Srwatson
563155192Srwatson	ar->k_ar.ar_arg_svipc_id = id;
564155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ID);
565155192Srwatson}
566155192Srwatson
567155192Srwatsonvoid
568155192Srwatsonaudit_arg_svipc_addr(void * addr)
569155192Srwatson{
570155192Srwatson	struct kaudit_record *ar;
571155192Srwatson
572155192Srwatson	ar = currecord();
573155192Srwatson	if (ar == NULL)
574155192Srwatson		return;
575155192Srwatson
576155192Srwatson	ar->k_ar.ar_arg_svipc_addr = addr;
577155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
578155192Srwatson}
579155192Srwatson
580155192Srwatsonvoid
581155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
582155192Srwatson{
583155192Srwatson	struct kaudit_record *ar;
584155192Srwatson
585155192Srwatson	ar = currecord();
586155192Srwatson	if (ar == NULL)
587155192Srwatson		return;
588155192Srwatson
589155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
590155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
591155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
592155192Srwatson	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
593155192Srwatson}
594155192Srwatson
595155192Srwatsonvoid
596155192Srwatsonaudit_arg_auditon(union auditon_udata *udata)
597155192Srwatson{
598155192Srwatson	struct kaudit_record *ar;
599155192Srwatson
600155192Srwatson	ar = currecord();
601155192Srwatson	if (ar == NULL)
602155192Srwatson		return;
603155192Srwatson
604156889Srwatson	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
605156889Srwatson	    sizeof(ar->k_ar.ar_arg_auditon));
606155192Srwatson	ARG_SET_VALID(ar, ARG_AUDITON);
607155192Srwatson}
608155192Srwatson
609155192Srwatson/*
610155192Srwatson * Audit information about a file, either the file's vnode info, or its
611155192Srwatson * socket address info.
612155192Srwatson */
613155192Srwatsonvoid
614155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp)
615155192Srwatson{
616155192Srwatson	struct kaudit_record *ar;
617155192Srwatson	struct socket *so;
618155192Srwatson	struct inpcb *pcb;
619155192Srwatson	struct vnode *vp;
620155192Srwatson	int vfslocked;
621155192Srwatson
622160086Srwatson	ar = currecord();
623160086Srwatson	if (ar == NULL)
624160086Srwatson		return;
625160086Srwatson
626155192Srwatson	switch (fp->f_type) {
627155192Srwatson	case DTYPE_VNODE:
628155192Srwatson	case DTYPE_FIFO:
629155192Srwatson		/*
630155192Srwatson		 * XXXAUDIT: Only possibly to record as first vnode?
631155192Srwatson		 */
632155192Srwatson		vp = fp->f_vnode;
633155192Srwatson		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
634175202Sattilio		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
635155192Srwatson		audit_arg_vnode(vp, ARG_VNODE1);
636175294Sattilio		VOP_UNLOCK(vp, 0);
637155192Srwatson		VFS_UNLOCK_GIANT(vfslocked);
638155192Srwatson		break;
639155192Srwatson
640155192Srwatson	case DTYPE_SOCKET:
641155192Srwatson		so = (struct socket *)fp->f_data;
642155192Srwatson		if (INP_CHECK_SOCKAF(so, PF_INET)) {
643166845Srwatson			SOCK_LOCK(so);
644155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_type =
645156889Srwatson			    so->so_type;
646155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_domain =
647156889Srwatson			    INP_SOCKAF(so);
648155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_protocol =
649156889Srwatson			    so->so_proto->pr_protocol;
650166845Srwatson			SOCK_UNLOCK(so);
651155192Srwatson			pcb = (struct inpcb *)so->so_pcb;
652178322Srwatson			INP_RLOCK(pcb);
653155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_raddr =
654156889Srwatson			    pcb->inp_faddr.s_addr;
655155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_laddr =
656156889Srwatson			    pcb->inp_laddr.s_addr;
657155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_rport =
658156889Srwatson			    pcb->inp_fport;
659155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_lport =
660156889Srwatson			    pcb->inp_lport;
661178322Srwatson			INP_RUNLOCK(pcb);
662155192Srwatson			ARG_SET_VALID(ar, ARG_SOCKINFO);
663155192Srwatson		}
664155192Srwatson		break;
665155192Srwatson
666155192Srwatson	default:
667155192Srwatson		/* XXXAUDIT: else? */
668155192Srwatson		break;
669155192Srwatson	}
670155192Srwatson}
671155192Srwatson
672156889Srwatson/*
673156889Srwatson * Store a path as given by the user process for auditing into the audit
674156889Srwatson * record stored on the user thread. This function will allocate the memory
675156889Srwatson * to store the path info if not already available. This memory will be freed
676156889Srwatson * when the audit record is freed.
677155192Srwatson *
678155192Srwatson * XXXAUDIT: Possibly assert that the memory isn't already allocated?
679155192Srwatson */
680155192Srwatsonvoid
681155192Srwatsonaudit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
682155192Srwatson{
683155192Srwatson	struct kaudit_record *ar;
684155192Srwatson	char **pathp;
685155192Srwatson
686160086Srwatson	KASSERT(td != NULL, ("audit_arg_upath: td == NULL"));
687160086Srwatson	KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL"));
688155192Srwatson
689160086Srwatson	ar = currecord();
690160086Srwatson	if (ar == NULL)
691160086Srwatson		return;
692160086Srwatson
693155192Srwatson	KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2),
694155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
695155192Srwatson	KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2),
696155270Srwatson	    ("audit_arg_upath: flag %llu", (unsigned long long)flag));
697155192Srwatson
698155192Srwatson	if (flag == ARG_UPATH1)
699155192Srwatson		pathp = &ar->k_ar.ar_arg_upath1;
700155192Srwatson	else
701155192Srwatson		pathp = &ar->k_ar.ar_arg_upath2;
702155192Srwatson
703155192Srwatson	if (*pathp == NULL)
704155192Srwatson		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
705155192Srwatson
706176565Srwatson	audit_canon_path(td, upath, *pathp);
707155192Srwatson
708155192Srwatson	ARG_SET_VALID(ar, flag);
709155192Srwatson}
710155192Srwatson
711155192Srwatson/*
712156889Srwatson * Function to save the path and vnode attr information into the audit
713156889Srwatson * record.
714155192Srwatson *
715155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to
716155192Srwatson * perform a VOP_GETATTR() on the passed vnode.
717155192Srwatson *
718170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
719170196Srwatson * provides access to the generation number as we need that to construct the
720170196Srwatson * BSM file ID.
721170196Srwatson *
722170196Srwatson * XXX: We should accept the process argument from the caller, since it's
723170196Srwatson * very likely they already have a reference.
724170196Srwatson *
725155192Srwatson * XXX: Error handling in this function is poor.
726155192Srwatson *
727155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
728155192Srwatson */
729155192Srwatsonvoid
730155192Srwatsonaudit_arg_vnode(struct vnode *vp, u_int64_t flags)
731155192Srwatson{
732155192Srwatson	struct kaudit_record *ar;
733155192Srwatson	struct vattr vattr;
734155192Srwatson	int error;
735155192Srwatson	struct vnode_au_info *vnp;
736155192Srwatson
737160086Srwatson	KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL"));
738160086Srwatson	KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2),
739160086Srwatson	    ("audit_arg_vnode: flags %jd", (intmax_t)flags));
740155192Srwatson
741155192Srwatson	/*
742155192Srwatson	 * Assume that if the caller is calling audit_arg_vnode() on a
743155192Srwatson	 * non-MPSAFE vnode, then it will have acquired Giant.
744155192Srwatson	 */
745155192Srwatson	VFS_ASSERT_GIANT(vp->v_mount);
746155192Srwatson	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
747155192Srwatson
748155192Srwatson	ar = currecord();
749156889Srwatson	if (ar == NULL)
750155192Srwatson		return;
751155192Srwatson
752155192Srwatson	/*
753155192Srwatson	 * XXXAUDIT: The below clears, and then resets the flags for valid
754155192Srwatson	 * arguments.  Ideally, either the new vnode is used, or the old one
755155192Srwatson	 * would be.
756155192Srwatson	 */
757155192Srwatson	if (flags & ARG_VNODE1) {
758155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
759155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode1;
760155192Srwatson	} else {
761155192Srwatson		ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
762155192Srwatson		vnp = &ar->k_ar.ar_arg_vnode2;
763155192Srwatson	}
764155192Srwatson
765160086Srwatson	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred, curthread);
766155192Srwatson	if (error) {
767155192Srwatson		/* XXX: How to handle this case? */
768155192Srwatson		return;
769155192Srwatson	}
770155192Srwatson
771155192Srwatson	vnp->vn_mode = vattr.va_mode;
772155192Srwatson	vnp->vn_uid = vattr.va_uid;
773155192Srwatson	vnp->vn_gid = vattr.va_gid;
774155192Srwatson	vnp->vn_dev = vattr.va_rdev;
775155192Srwatson	vnp->vn_fsid = vattr.va_fsid;
776155192Srwatson	vnp->vn_fileid = vattr.va_fileid;
777155192Srwatson	vnp->vn_gen = vattr.va_gen;
778155192Srwatson	if (flags & ARG_VNODE1)
779155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE1);
780155192Srwatson	else
781155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE2);
782155192Srwatson}
783155192Srwatson
784155192Srwatson/*
785161813Swsalamon * Audit the argument strings passed to exec.
786161813Swsalamon */
787161813Swsalamonvoid
788161813Swsalamonaudit_arg_argv(char *argv, int argc, int length)
789161813Swsalamon{
790161813Swsalamon	struct kaudit_record *ar;
791161813Swsalamon
792161813Swsalamon	if (audit_argv == 0)
793161813Swsalamon		return;
794161813Swsalamon
795161813Swsalamon	ar = currecord();
796161813Swsalamon	if (ar == NULL)
797161813Swsalamon		return;
798161813Swsalamon
799161813Swsalamon	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
800161813Swsalamon	bcopy(argv, ar->k_ar.ar_arg_argv, length);
801161813Swsalamon	ar->k_ar.ar_arg_argc = argc;
802161813Swsalamon	ARG_SET_VALID(ar, ARG_ARGV);
803161813Swsalamon}
804161813Swsalamon
805161813Swsalamon/*
806161813Swsalamon * Audit the environment strings passed to exec.
807161813Swsalamon */
808161813Swsalamonvoid
809161813Swsalamonaudit_arg_envv(char *envv, int envc, int length)
810161813Swsalamon{
811161813Swsalamon	struct kaudit_record *ar;
812161813Swsalamon
813161813Swsalamon	if (audit_arge == 0)
814161813Swsalamon		return;
815161813Swsalamon
816161813Swsalamon	ar = currecord();
817161813Swsalamon	if (ar == NULL)
818161813Swsalamon		return;
819161813Swsalamon
820161813Swsalamon	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
821161813Swsalamon	bcopy(envv, ar->k_ar.ar_arg_envv, length);
822161813Swsalamon	ar->k_ar.ar_arg_envc = envc;
823161813Swsalamon	ARG_SET_VALID(ar, ARG_ENVV);
824161813Swsalamon}
825161813Swsalamon
826161813Swsalamon/*
827156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode
828156889Srwatson * information because those pieces are not easily obtained within the system
829156889Srwatson * call itself.
830155192Srwatson */
831155192Srwatsonvoid
832155192Srwatsonaudit_sysclose(struct thread *td, int fd)
833155192Srwatson{
834160086Srwatson	struct kaudit_record *ar;
835155192Srwatson	struct vnode *vp;
836155192Srwatson	struct file *fp;
837155192Srwatson	int vfslocked;
838155192Srwatson
839160086Srwatson	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
840160086Srwatson
841160086Srwatson	ar = currecord();
842160086Srwatson	if (ar == NULL)
843160086Srwatson		return;
844160086Srwatson
845155192Srwatson	audit_arg_fd(fd);
846155192Srwatson
847155192Srwatson	if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
848155192Srwatson		return;
849155192Srwatson
850155192Srwatson	vp = fp->f_vnode;
851155192Srwatson	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
852175202Sattilio	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
853155192Srwatson	audit_arg_vnode(vp, ARG_VNODE1);
854175294Sattilio	VOP_UNLOCK(vp, 0);
855155192Srwatson	VFS_UNLOCK_GIANT(vfslocked);
856155192Srwatson	fdrop(fp, td);
857156889Srwatson}
858