diff options
author | kib <kib@FreeBSD.org> | 2016-09-01 07:20:50 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-09-01 07:20:50 +0000 |
commit | b69eb90edd8f905bb048614e52acaabcedd8eba2 (patch) | |
tree | 4dd11e52a71d964e65f8c1cdb19e3ad79834acfb /sys/kern | |
parent | ce87e4672c6494487cc6f6d023d21167ef96f526 (diff) | |
download | FreeBSD-src-b69eb90edd8f905bb048614e52acaabcedd8eba2.zip FreeBSD-src-b69eb90edd8f905bb048614e52acaabcedd8eba2.tar.gz |
MFC r304808:
Prevent leak of URWLOCK_READ_WAITERS flag for urwlocks.
PR: 211947
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_umtx.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index dd205d0..f871d41 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2965,9 +2965,12 @@ sleep: suword32(&rwlock->rw_blocked_readers, blocked_readers-1); if (blocked_readers == 1) { rv = fueword32(&rwlock->rw_state, &state); - if (rv == -1) + if (rv == -1) { + umtxq_unbusy_unlocked(&uq->uq_key); error = EFAULT; - while (error == 0) { + break; + } + for (;;) { rv = casueword32(&rwlock->rw_state, state, &oldstate, state & ~URWLOCK_READ_WAITERS); if (rv == -1) { @@ -2978,6 +2981,8 @@ sleep: break; state = oldstate; error = umtxq_check_susp(td); + if (error != 0) + break; } } |