Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Kernel panic related to pipe
> Date: Mon, 05 Oct 2026 17:57:25 +0700
> From: Robert Elz <kre%munnari.OZ.AU@localhost>
> References: <asN1qORaELZUHaDN%big-apple.aprisoft.de@localhost> <877bjwlcbw.fsf%castella.elements.tetera.org@localhost> <asNzOSWNKvzPAmxu%big-apple.aprisoft.de@localhost>
>
> Date: Mon, 5 Oct 2026 12:02:16 +0200
> From: Martin Husemann <martin%duskware.de@localhost>
> Message-ID: <asN1qORaELZUHaDN%big-apple.aprisoft.de@localhost>
>
> | Taylor: it crashes in the
> |
> | KASSERT(mutex_owned(pipe->pipe_lock));
> |
> | with a NULL deref as apparently "pipe" is NULL.
>
> Try with src/sys/kern/sys_pipe.c 1.178 (from about 20 mins ago).
Thanks, but while this stop-gap measure will help to unblock others,
it cannot be correct on its own. Here's the context of the change:
@@ -507,62 +507,64 @@ again:
/*
* Detect EOF condition.
* Read returns 0 on EOF, no need to set error.
*
* XXX Why rpipe->pipe_state and not wpipe->pipe_state?
* XXX Distinguish reader-closed from writer-closed?
*/
if (rpipe->pipe_state & PIPE_EOF)
break;
...
/*
* If the "write-side" is blocked, wake it up now.
*/
wpipe = rpipe->pipe_peer;
- pipeselwakeup(wpipe, POLL_OUT);
- cv_broadcast(&wpipe->pipe_wcv);
+ if (wpipe != NULL) {
+ pipeselwakeup(wpipe, POLL_OUT);
+ cv_broadcast(&wpipe->pipe_wcv);
+ }
In the ellipsis, the pipe->pipe_lock (it's the same for the reader and
the writer) is not released. (You'll also find a call to a function
`pipeunlock', but that just changes a flag bit under that lock and
signals a condvar; it doesn't mutex_exit.) And the transition from
pipe->pipe_peer != NULL to pipe->pipe_peer == NULL only happens
(a) under the lock, and
(b) after PIPE_EOF has been set on both sides of the pipe:
1049 pipe->pipe_state |= PIPE_EOF;
1050 if ((ppipe = pipe->pipe_peer) != NULL) {
...
1064 ppipe->pipe_state |= PIPE_EOF;
1065 if (ppipe->pipe_busy) {
1066 cv_broadcast(&ppipe->pipe_rcv);
1067 cv_broadcast(&ppipe->pipe_wcv);
1068 while (ppipe->pipe_busy)
1069 cv_wait(&ppipe->pipe_draincv, lock);
1070 }
1071 ppipe->pipe_peer = NULL;
1072 }
https://nxr.netbsd.org/xref/src/sys/kern/sys_pipe.c?r=1.177#1049
Hence, if, in the context of your change, PIPE_EOF has been set in
rpipe->pipe_state, then rpipe->pipe_peer is supposed to be nonnull.
So:
1. there is something else going wrong here, and
2. we don't have an adequate automatic test for it.
Home |
Main Index |
Thread Index |
Old Index