658 mutex_exit(&devpoll_lock);
659
660 mutex_enter(&dpep->dpe_lock);
661 pcp = dpep->dpe_pcache;
662 is_epoll = (dpep->dpe_flag & DP_ISEPOLLCOMPAT) != 0;
663 size = (is_epoll) ? sizeof (dvpoll_epollfd_t) : sizeof (pollfd_t);
664 mutex_exit(&dpep->dpe_lock);
665
666 if (!is_epoll && curproc->p_pid != pcp->pc_pid) {
667 if (pcp->pc_pid != -1) {
668 return (EACCES);
669 }
670
671 pcp->pc_pid = curproc->p_pid;
672 }
673
674 uiosize = uiop->uio_resid;
675 pollfdnum = uiosize / size;
676
677 /*
678 * For epoll-enabled handles, restrict the allowed write size to 2.
679 * This corresponds to an epoll_ctl(3C) performing an EPOLL_CTL_MOD
680 * operation which is expanded into two operations (DEL and ADD).
681 *
682 * All other operations performed through epoll_ctl(3C) will consist of
683 * a single entry.
684 */
685 if (is_epoll && pollfdnum > 2) {
686 return (EINVAL);
687 }
688
689 /*
690 * We want to make sure that pollfdnum isn't large enough to DoS us,
691 * but we also don't want to grab p_lock unnecessarily -- so we
692 * perform the full check against our resource limits if and only if
693 * pollfdnum is larger than the known-to-be-sane value of UINT8_MAX.
694 */
695 if (pollfdnum > UINT8_MAX) {
696 mutex_enter(&curproc->p_lock);
697 if (pollfdnum >
698 (uint_t)rctl_enforced_value(rctlproc_legacy[RLIMIT_NOFILE],
699 curproc->p_rctls, curproc)) {
700 (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE],
701 curproc->p_rctls, curproc, RCA_SAFE);
702 mutex_exit(&curproc->p_lock);
703 return (EINVAL);
704 }
705 mutex_exit(&curproc->p_lock);
706 }
707
708 /*
709 * Copy in the pollfd array. Walk through the array and add
728 */
729 if ((error = uiocopy((caddr_t)pollfdp, uiosize, UIO_WRITE, uiop,
730 ©size)) != 0) {
731 kmem_free(pollfdp, uiosize);
732 return (error);
733 }
734
735 /*
736 * We are about to enter the core portion of dpwrite(). Make sure this
737 * write has exclusive access in this portion of the code, i.e., no
738 * other writers in this code.
739 *
740 * Waiting for all readers to drop their references to the dpe is
741 * unecessary since the pollcache itself is protected by pc_lock.
742 */
743 mutex_enter(&dpep->dpe_lock);
744 dpep->dpe_writerwait++;
745 while ((dpep->dpe_flag & DP_WRITER_PRESENT) != 0) {
746 ASSERT(dpep->dpe_refcnt != 0);
747
748 /*
749 * The epoll API does not allow EINTR as a result when making
750 * modifications to the set of polled fds. Given that write
751 * activity is relatively quick and the size of accepted writes
752 * is limited above to two entries, a signal-ignorant wait is
753 * used here to avoid the EINTR.
754 */
755 if (is_epoll) {
756 cv_wait(&dpep->dpe_cv, &dpep->dpe_lock);
757 continue;
758 }
759
760 /*
761 * Non-epoll writers to /dev/poll handles can tolerate EINTR.
762 */
763 if (!cv_wait_sig_swap(&dpep->dpe_cv, &dpep->dpe_lock)) {
764 dpep->dpe_writerwait--;
765 mutex_exit(&dpep->dpe_lock);
766 kmem_free(pollfdp, uiosize);
767 return (EINTR);
768 }
769 }
770 dpep->dpe_writerwait--;
771 dpep->dpe_flag |= DP_WRITER_PRESENT;
772 dpep->dpe_refcnt++;
773
774 if (!is_epoll && (dpep->dpe_flag & DP_ISEPOLLCOMPAT) != 0) {
775 /*
776 * The epoll compat mode was enabled while we were waiting to
777 * establish write access. It is not safe to continue since
778 * state was prepared for non-epoll operation.
779 */
780 error = EBUSY;
781 goto bypass;
782 }
|
658 mutex_exit(&devpoll_lock);
659
660 mutex_enter(&dpep->dpe_lock);
661 pcp = dpep->dpe_pcache;
662 is_epoll = (dpep->dpe_flag & DP_ISEPOLLCOMPAT) != 0;
663 size = (is_epoll) ? sizeof (dvpoll_epollfd_t) : sizeof (pollfd_t);
664 mutex_exit(&dpep->dpe_lock);
665
666 if (!is_epoll && curproc->p_pid != pcp->pc_pid) {
667 if (pcp->pc_pid != -1) {
668 return (EACCES);
669 }
670
671 pcp->pc_pid = curproc->p_pid;
672 }
673
674 uiosize = uiop->uio_resid;
675 pollfdnum = uiosize / size;
676
677 /*
678 * We want to make sure that pollfdnum isn't large enough to DoS us,
679 * but we also don't want to grab p_lock unnecessarily -- so we
680 * perform the full check against our resource limits if and only if
681 * pollfdnum is larger than the known-to-be-sane value of UINT8_MAX.
682 */
683 if (pollfdnum > UINT8_MAX) {
684 mutex_enter(&curproc->p_lock);
685 if (pollfdnum >
686 (uint_t)rctl_enforced_value(rctlproc_legacy[RLIMIT_NOFILE],
687 curproc->p_rctls, curproc)) {
688 (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE],
689 curproc->p_rctls, curproc, RCA_SAFE);
690 mutex_exit(&curproc->p_lock);
691 return (EINVAL);
692 }
693 mutex_exit(&curproc->p_lock);
694 }
695
696 /*
697 * Copy in the pollfd array. Walk through the array and add
716 */
717 if ((error = uiocopy((caddr_t)pollfdp, uiosize, UIO_WRITE, uiop,
718 ©size)) != 0) {
719 kmem_free(pollfdp, uiosize);
720 return (error);
721 }
722
723 /*
724 * We are about to enter the core portion of dpwrite(). Make sure this
725 * write has exclusive access in this portion of the code, i.e., no
726 * other writers in this code.
727 *
728 * Waiting for all readers to drop their references to the dpe is
729 * unecessary since the pollcache itself is protected by pc_lock.
730 */
731 mutex_enter(&dpep->dpe_lock);
732 dpep->dpe_writerwait++;
733 while ((dpep->dpe_flag & DP_WRITER_PRESENT) != 0) {
734 ASSERT(dpep->dpe_refcnt != 0);
735
736 if (!cv_wait_sig_swap(&dpep->dpe_cv, &dpep->dpe_lock)) {
737 dpep->dpe_writerwait--;
738 mutex_exit(&dpep->dpe_lock);
739 kmem_free(pollfdp, uiosize);
740 return (EINTR);
741 }
742 }
743 dpep->dpe_writerwait--;
744 dpep->dpe_flag |= DP_WRITER_PRESENT;
745 dpep->dpe_refcnt++;
746
747 if (!is_epoll && (dpep->dpe_flag & DP_ISEPOLLCOMPAT) != 0) {
748 /*
749 * The epoll compat mode was enabled while we were waiting to
750 * establish write access. It is not safe to continue since
751 * state was prepared for non-epoll operation.
752 */
753 error = EBUSY;
754 goto bypass;
755 }
|