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