Deleted Added
full compact
audit_arg.c (159277) audit_arg.c (160086)
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

--- 12 unchanged lines hidden (view full) ---

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

--- 12 unchanged lines hidden (view full) ---

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 159277 2006-06-05 16:12:00Z rwatson $
29 * $FreeBSD: head/sys/security/audit/audit_arg.c 160086 2006-07-03 14:55:55Z rwatson $
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>

--- 314 unchanged lines hidden (view full) ---

352 ARG_SET_VALID(ar, ARG_PID);
353}
354
355void
356audit_arg_process(struct proc *p)
357{
358 struct kaudit_record *ar;
359
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>

--- 314 unchanged lines hidden (view full) ---

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
360 ar = currecord();
364 ar = currecord();
361 if ((ar == NULL) || (p == NULL))
365 if (ar == NULL)
362 return;
363
366 return;
367
364 /*
365 * XXXAUDIT: PROC_LOCK_ASSERT(p);
366 */
367 ar->k_ar.ar_arg_auid = p->p_au->ai_auid;
368 ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
369 ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
370 ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
371 ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
372 ar->k_ar.ar_arg_asid = p->p_au->ai_asid;
373 ar->k_ar.ar_arg_termid = p->p_au->ai_termid;
374 ar->k_ar.ar_arg_pid = p->p_pid;

--- 24 unchanged lines hidden (view full) ---

399 return;
400
401 ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
402 ar->k_ar.ar_arg_sockinfo.so_type = sotype;
403 ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
404 ARG_SET_VALID(ar, ARG_SOCKINFO);
405}
406
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;

--- 24 unchanged lines hidden (view full) ---

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
407/*
408 * XXXAUDIT: Argument here should be 'sa' not 'so'. Caller is responsible
409 * for synchronizing access to the source of the address.
410 */
411void
408void
412audit_arg_sockaddr(struct thread *td, struct sockaddr *so)
409audit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
413{
414 struct kaudit_record *ar;
415
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();
416 ar = currecord();
417 if (ar == NULL || td == NULL || so == NULL)
417 if (ar == NULL)
418 return;
419
418 return;
419
420 bcopy(so, &ar->k_ar.ar_arg_sockaddr, sizeof(ar->k_ar.ar_arg_sockaddr));
421 switch (so->sa_family) {
420 bcopy(sa, &ar->k_ar.ar_arg_sockaddr,
421 sizeof(ar->k_ar.ar_arg_sockaddr));
422 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:
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:
431 audit_arg_upath(td, ((struct sockaddr_un *)so)->sun_path,
432 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

--- 27 unchanged lines hidden (view full) ---

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
433 ARG_UPATH1);
434 ARG_SET_VALID(ar, ARG_SADDRUNIX);
435 break;
436 /* XXXAUDIT: default:? */
437 }
438}
439
440void

--- 27 unchanged lines hidden (view full) ---

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
475 ar = currecord();
476 if (ar == NULL)
477 return;
478
478 ar = currecord();
479 if (ar == NULL)
480 return;
481
479 /*
480 * XXXAUDIT: Why do we accept a possibly NULL string here?
481 */
482 /* Invalidate the text string */
483 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
482 /* Invalidate the text string */
483 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
484 if (text == NULL)
485 return;
486
487 if (ar->k_ar.ar_arg_text == NULL)
488 ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
489 M_WAITOK);
490
491 strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
492 ARG_SET_VALID(ar, ARG_TEXT);
493}

--- 101 unchanged lines hidden (view full) ---

595audit_arg_file(struct proc *p, struct file *fp)
596{
597 struct kaudit_record *ar;
598 struct socket *so;
599 struct inpcb *pcb;
600 struct vnode *vp;
601 int vfslocked;
602
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}

--- 101 unchanged lines hidden (view full) ---

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
603 /*
604 * XXXAUDIT: Why is the (ar == NULL) test only in the socket case?
605 */
601 ar = currecord();
602 if (ar == NULL)
603 return;
604
606 switch (fp->f_type) {
607 case DTYPE_VNODE:
608 case DTYPE_FIFO:
609 /*
610 * XXXAUDIT: Only possibly to record as first vnode?
611 */
612 vp = fp->f_vnode;
613 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
614 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
615 audit_arg_vnode(vp, ARG_VNODE1);
616 VOP_UNLOCK(vp, 0, curthread);
617 VFS_UNLOCK_GIANT(vfslocked);
618 break;
619
620 case DTYPE_SOCKET:
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:
621 ar = currecord();
622 if (ar == NULL)
623 return;
624
625 /*
626 * XXXAUDIT: Socket locking? Inpcb locking?
627 */
628 so = (struct socket *)fp->f_data;
620 so = (struct socket *)fp->f_data;
621 SOCK_LOCK(so);
629 if (INP_CHECK_SOCKAF(so, PF_INET)) {
630 if (so->so_pcb == NULL)
631 return;
632 ar->k_ar.ar_arg_sockinfo.so_type =
633 so->so_type;
634 ar->k_ar.ar_arg_sockinfo.so_domain =
635 INP_SOCKAF(so);
636 ar->k_ar.ar_arg_sockinfo.so_protocol =

--- 4 unchanged lines hidden (view full) ---

641 ar->k_ar.ar_arg_sockinfo.so_laddr =
642 pcb->inp_laddr.s_addr;
643 ar->k_ar.ar_arg_sockinfo.so_rport =
644 pcb->inp_fport;
645 ar->k_ar.ar_arg_sockinfo.so_lport =
646 pcb->inp_lport;
647 ARG_SET_VALID(ar, ARG_SOCKINFO);
648 }
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 =

--- 4 unchanged lines hidden (view full) ---

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);
649 break;
650
651 default:
652 /* XXXAUDIT: else? */
653 break;
654 }
655
656}

--- 7 unchanged lines hidden (view full) ---

664 * XXXAUDIT: Possibly assert that the memory isn't already allocated?
665 */
666void
667audit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
668{
669 struct kaudit_record *ar;
670 char **pathp;
671
643 break;
644
645 default:
646 /* XXXAUDIT: else? */
647 break;
648 }
649
650}

--- 7 unchanged lines hidden (view full) ---

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
672 if (td == NULL || upath == NULL)
673 return; /* nothing to do! */
666 KASSERT(td != NULL, ("audit_arg_upath: td == NULL"));
667 KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL"));
674
668
669 ar = currecord();
670 if (ar == NULL)
671 return;
672
675 /*
676 * XXXAUDIT: Witness warning for possible sleep here?
677 */
678 KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2),
679 ("audit_arg_upath: flag %llu", (unsigned long long)flag));
680 KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2),
681 ("audit_arg_upath: flag %llu", (unsigned long long)flag));
682
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
683 ar = currecord();
684 if (ar == NULL)
685 return;
686
687 if (flag == ARG_UPATH1)
688 pathp = &ar->k_ar.ar_arg_upath1;
689 else
690 pathp = &ar->k_ar.ar_arg_upath2;
691
692 if (*pathp == NULL)
693 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
694

--- 20 unchanged lines hidden (view full) ---

715 */
716void
717audit_arg_vnode(struct vnode *vp, u_int64_t flags)
718{
719 struct kaudit_record *ar;
720 struct vattr vattr;
721 int error;
722 struct vnode_au_info *vnp;
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

--- 20 unchanged lines hidden (view full) ---

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;
723 struct thread *td;
724
717
725 /*
726 * XXXAUDIT: Why is vp possibly NULL here?
727 */
728 if (vp == NULL)
729 return;
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));
730
731 /*
732 * Assume that if the caller is calling audit_arg_vnode() on a
733 * non-MPSAFE vnode, then it will have acquired Giant.
734 */
735 VFS_ASSERT_GIANT(vp->v_mount);
736 ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
737
738 ar = currecord();
739 if (ar == NULL)
740 return;
741
742 /*
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 /*
743 * XXXAUDIT: KASSERT argument validity instead?
744 *
745 * XXXAUDIT: The below clears, and then resets the flags for valid
746 * arguments. Ideally, either the new vnode is used, or the old one
747 * would be.
748 */
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 */
749 if ((flags & (ARG_VNODE1 | ARG_VNODE2)) == 0)
750 return;
751
752 td = curthread;
753
754 if (flags & ARG_VNODE1) {
755 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
756 vnp = &ar->k_ar.ar_arg_vnode1;
757 } else {
758 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
759 vnp = &ar->k_ar.ar_arg_vnode2;
760 }
761
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
762 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
746 error = VOP_GETATTR(vp, &vattr, curthread->td_ucred, curthread);
763 if (error) {
764 /* XXX: How to handle this case? */
765 return;
766 }
767
768 vnp->vn_mode = vattr.va_mode;
769 vnp->vn_uid = vattr.va_uid;
770 vnp->vn_gid = vattr.va_gid;

--- 10 unchanged lines hidden (view full) ---

781/*
782 * The close() system call uses it's own audit call to capture the path/vnode
783 * information because those pieces are not easily obtained within the system
784 * call itself.
785 */
786void
787audit_sysclose(struct thread *td, int fd)
788{
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;

--- 10 unchanged lines hidden (view full) ---

765/*
766 * The close() system call uses it's own audit call to capture the path/vnode
767 * information because those pieces are not easily obtained within the system
768 * call itself.
769 */
770void
771audit_sysclose(struct thread *td, int fd)
772{
773 struct kaudit_record *ar;
789 struct vnode *vp;
790 struct file *fp;
791 int vfslocked;
792
774 struct vnode *vp;
775 struct file *fp;
776 int vfslocked;
777
778 KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
779
780 ar = currecord();
781 if (ar == NULL)
782 return;
783
793 audit_arg_fd(fd);
794
795 if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
796 return;
797
798 vp = fp->f_vnode;
799 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
800 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
801 audit_arg_vnode(vp, ARG_VNODE1);
802 VOP_UNLOCK(vp, 0, td);
803 VFS_UNLOCK_GIANT(vfslocked);
804 fdrop(fp, td);
805}
784 audit_arg_fd(fd);
785
786 if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
787 return;
788
789 vp = fp->f_vnode;
790 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
791 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
792 audit_arg_vnode(vp, ARG_VNODE1);
793 VOP_UNLOCK(vp, 0, td);
794 VFS_UNLOCK_GIANT(vfslocked);
795 fdrop(fp, td);
796}