| 720 | } |
| 721 | |
| 722 | int |
| 723 | kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) |
| 724 | { |
| 725 | struct file *fp; |
| 726 | struct filedesc *fdp; |
| 727 | int error, tmp, locked; |
| 728 | |
| 729 | AUDIT_ARG_FD(fd); |
| 730 | AUDIT_ARG_CMD(com); |
| 731 | |
| 732 | fdp = td->td_proc->p_fd; |
| 733 | |
| 734 | switch (com) { |
| 735 | case FIONCLEX: |
| 736 | case FIOCLEX: |
| 737 | FILEDESC_XLOCK(fdp); |
| 738 | locked = LA_XLOCKED; |
| 739 | break; |
| 740 | default: |
| 741 | #ifdef CAPABILITIES |
| 742 | FILEDESC_SLOCK(fdp); |
| 743 | locked = LA_SLOCKED; |
| 744 | #else |
| 745 | locked = LA_UNLOCKED; |
| 746 | #endif |
| 747 | break; |
| 748 | } |
| 749 | |
| 750 | #ifdef CAPABILITIES |
| 751 | if ((fp = fget_locked(fdp, fd)) == NULL) { |
| 752 | error = EBADF; |
| 753 | goto out; |
| 754 | } |
| 755 | if ((error = cap_ioctl_check(fdp, fd, com)) != 0) { |
| 756 | fp = NULL; /* fhold() was not called yet */ |
| 757 | goto out; |
| 758 | } |
| 759 | if (!fhold(fp)) { |
| 760 | error = EBADF; |
| 761 | fp = NULL; |
| 762 | goto out; |
| 763 | } |
| 764 | if (locked == LA_SLOCKED) { |
| 765 | FILEDESC_SUNLOCK(fdp); |
| 766 | locked = LA_UNLOCKED; |
| 767 | } |
| 768 | #else |
| 769 | error = fget(td, fd, &cap_ioctl_rights, &fp); |
| 770 | if (error != 0) { |
| 771 | fp = NULL; |
| 772 | goto out; |
| 773 | } |
| 774 | #endif |
| 775 | if ((fp->f_flag & (FREAD | FWRITE)) == 0) { |
| 776 | error = EBADF; |
| 777 | goto out; |
| 778 | } |
| 779 |
no test coverage detected