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