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} |