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