diff options
author | Bryan Cantrill <bryan@joyent.com> | 2015-11-24 00:52:03 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2016-08-09 08:41:45 -0700 |
commit | 158dfbe4529de26c7bd687efe70e837858cbf8cf (patch) | |
tree | 13f2ae26c31724ec61c15b7e990fecfcadecd7e1 /usr/src | |
parent | 447b1e1fca22e4de5e04623965fbb1460857930c (diff) | |
download | illumos-gate-158dfbe4529de26c7bd687efe70e837858cbf8cf.tar.gz |
7206 dpwrite() acquires p_lock unnecessarily
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/devpoll.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/usr/src/uts/common/io/devpoll.c b/usr/src/uts/common/io/devpoll.c index e00ac1d1e9..8c63043d00 100644 --- a/usr/src/uts/common/io/devpoll.c +++ b/usr/src/uts/common/io/devpoll.c @@ -670,15 +670,26 @@ dpwrite(dev_t dev, struct uio *uiop, cred_t *credp) uiosize = uiop->uio_resid; pollfdnum = uiosize / size; - mutex_enter(&curproc->p_lock); - if (pollfdnum > (uint_t)rctl_enforced_value( - rctlproc_legacy[RLIMIT_NOFILE], curproc->p_rctls, curproc)) { - (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE], - curproc->p_rctls, curproc, RCA_SAFE); + + /* + * We want to make sure that pollfdnum isn't large enough to DoS us, + * but we also don't want to grab p_lock unnecessarily -- so we + * perform the full check against our resource limits if and only if + * pollfdnum is larger than the known-to-be-sane value of UINT8_MAX. + */ + if (pollfdnum > UINT8_MAX) { + mutex_enter(&curproc->p_lock); + if (pollfdnum > + (uint_t)rctl_enforced_value(rctlproc_legacy[RLIMIT_NOFILE], + curproc->p_rctls, curproc)) { + (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE], + curproc->p_rctls, curproc, RCA_SAFE); + mutex_exit(&curproc->p_lock); + return (EINVAL); + } mutex_exit(&curproc->p_lock); - return (EINVAL); } - mutex_exit(&curproc->p_lock); + /* * Copy in the pollfd array. Walk through the array and add * each polled fd to the cached set. |