svn commit: r344278 - head/sys/kern
Mark Johnston
markj at FreeBSD.org
Tue Feb 19 15:46:44 UTC 2019
Author: markj
Date: Tue Feb 19 15:46:43 2019
New Revision: 344278
URL: https://svnweb.freebsd.org/changeset/base/344278
Log:
Move a racy assertion in filt_pipewrite().
EVFILT_WRITE knotes for pipes live on the knlist for the other end of the
pipe. Since they do not hold a reference on the corresponding file
structure, they may be removed from the knlist by pipeclose() while still
remaining active. In this case, there is no knlist lock acquired before
filt_pipewrite() is called, so the assertion fails.
Fix the problem by first checking whether that end of the pipe has been
closed. These checks are memory safe since the knote holds a reference
on one end of the pipe, and the pipe structure is not freed until both
ends are closed. The checks are not racy since PIPE_EOF is never cleared
after being set, and pipe_present is never set back to PIPE_ACTIVE after
pipeclose() has been called.
PR: 235640
Reported and tested by: pho
Reviewed by: kib
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D19224
Modified:
head/sys/kern/sys_pipe.c
Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c Tue Feb 19 12:45:37 2019 (r344277)
+++ head/sys/kern/sys_pipe.c Tue Feb 19 15:46:43 2019 (r344278)
@@ -1741,15 +1741,19 @@ static int
filt_pipewrite(struct knote *kn, long hint)
{
struct pipe *wpipe;
-
+
+ /*
+ * If this end of the pipe is closed, the knote was removed from the
+ * knlist and the list lock (i.e., the pipe lock) is therefore not held.
+ */
wpipe = kn->kn_hook;
- PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
if (wpipe->pipe_present != PIPE_ACTIVE ||
(wpipe->pipe_state & PIPE_EOF)) {
kn->kn_data = 0;
kn->kn_flags |= EV_EOF;
return (1);
}
+ PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
kn->kn_data = (wpipe->pipe_buffer.size > 0) ?
(wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) : PIPE_BUF;
if (wpipe->pipe_state & PIPE_DIRECTW)
More information about the svn-src-head
mailing list