NetBSD Problem Report #60851
From www@netbsd.org Mon Oct 5 19:09:46 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id C95981A923B
for <gnats-bugs@gnats.NetBSD.org>; Mon, 5 Oct 2026 19:09:46 +0000 (UTC)
Message-Id: <20261005190945.7BC7A1A923C@mollari.NetBSD.org>
Date: Mon, 5 Oct 2026 19:09:45 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: change in pipe kevent EVFILT_READ/WRITE on wrong end
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>
>Number: 60851
>Notify-List: mk@kilbi.de
>Category: kern
>Synopsis: change in pipe kevent EVFILT_READ/WRITE on wrong end
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: riastradh
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Oct 05 19:10:01 +0000 2026
>Closed-Date: Thu Oct 08 15:39:59 +0000 2026
>Last-Modified: Thu Oct 08 15:39:59 +0000 2026
>Originator: Taylor R Campbell
>Release: current
>Organization:
Acme Pipefitters, Inc.
>Environment:
>Description:
Before my recent flurry of changes to the pipe(2)
implementation, kevent EVFILT_READ on the write end of a pipe,
and kevent EVFILT_WRITE on the read end of a pipe, would
quietly be accepted.
After the changes, specifically after
https://mail-index.netbsd.org/source-changes/2026/10/03/msg164422.html,
kevent would reject these with EINVAL.
1208 switch (kn->kn_filter) {
1209 case EVFILT_READ:
1210 if ((fp->f_flag & FREAD) == 0) {
1211 mutex_exit(lock);
1212 return (EINVAL);
1213 }
1214 kn->kn_fop = &pipe_rfiltops;
1215 break;
1216 case EVFILT_WRITE:
1217 if ((fp->f_flag & FWRITE) == 0) {
1218 mutex_exit(lock);
1219 return (EINVAL);
1220 }
1221 kn->kn_fop = &pipe_wfiltops;
1222 break;
1223 default:
1224 mutex_exit(lock);
1225 return (EINVAL);
1226 }
https://nxr.netbsd.org/xref/src/sys/kern/sys_pipe.c?r=1.174#1208
This is apparently in conflict with FreeBSD:
/*
* If a filter is requested that is not supported by this file
* descriptor, don't return an error, but also don't ever generate an
* event.
*/
if ((kn->kn_filter == EVFILT_READ) && !(fp->f_flag & FREAD)) {
kn->kn_fop = &pipe_nfiltops;
return (0);
}
if ((kn->kn_filter == EVFILT_WRITE) && !(fp->f_flag & FWRITE)) {
kn->kn_fop = &pipe_nfiltops;
return (0);
}
https://cgit.freebsd.org/src/tree/sys/kern/sys_pipe.c?h=release/15.1.0-p4&id=e38a7085f3a8ecd317c947591fe42b5ca9ab317b#n1791
The flurry of changes appear to have broken dovecot:
https://mail-index.netbsd.org/current-users/2026/10/05/msg047953.html
Review of a ktrace shows that SIGABRT happens shortly after
kevent(2) fails with EINVAL, which is consistent with this code
path showing that dovecot assumes EVFILT_READ on the write end
of a pipe will work when just the (dovecot-internal) event
condition IO_ERROR is requested:
if ((io->io.condition & (IO_READ | IO_ERROR)) != 0) {
MY_EV_SET(&ev, io->fd, EVFILT_READ, EV_ADD, 0, 0, io);
if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0)
i_panic("kevent(EV_ADD, READ, %d) failed: %m", io->fd);
}
if ((io->io.condition & IO_WRITE) != 0) {
MY_EV_SET(&ev, io->fd, EVFILT_WRITE, EV_ADD, 0, 0, io);
if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0)
i_panic("kevent(EV_ADD, WRITE, %d) failed: %m", io->fd);
}
https://github.com/dovecot/core/blob/2.3.21.1/src/lib/ioloop-kqueue.c#L64-L73
/* start listening errors for status fd, it means master died */
service->io_status_error = io_add(MASTER_DEAD_FD, IO_ERROR,
master_status_error, service);
https://github.com/dovecot/core/blob/2.3.21.1/src/lib-master/master-service.c#L688-L690
It's not clear that this isn't a dovecot bug, but there was
obviously an unexpected change in the NetBSD semantics which
now disagrees with FreeBSD.
>How-To-Repeat:
run mail/dovecot2
>Fix:
Replace these error branches by a null filterops that never
returns ready, like FreeBSD does -- and if we really want the
EINVAL semantics (which I tossed in without thinking much about
it just to detect what I assumed must be mistakes), that should
be done in a spearate intentional commit with supporting
documentation.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: kern-bug-people->riastradh
Responsible-Changed-By: riastradh@NetBSD.org
Responsible-Changed-When: Mon, 05 Oct 2026 19:23:04 +0000
Responsible-Changed-Why:
my bug, will add a test and fix shortly
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60851 CVS commit: src/tests/kernel/kqueue
Date: Mon, 5 Oct 2026 20:48:52 +0000
Module Name: src
Committed By: riastradh
Date: Mon Oct 5 20:48:52 UTC 2026
Modified Files:
src/tests/kernel/kqueue/read: t_pipe.c
src/tests/kernel/kqueue/write: t_pipe.c
Log Message:
tests/kernel/kqueue: Test EVFILT_READ/WRITE on wrong end of pipe.
PR kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/kernel/kqueue/read/t_pipe.c
cvs rdiff -u -r1.5 -r1.6 src/tests/kernel/kqueue/write/t_pipe.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60851 CVS commit: src
Date: Mon, 5 Oct 2026 20:49:13 +0000
Module Name: src
Committed By: riastradh
Date: Mon Oct 5 20:49:13 UTC 2026
Modified Files:
src/sys/kern: sys_pipe.c
src/tests/kernel/kqueue/read: t_pipe.c
src/tests/kernel/kqueue/write: t_pipe.c
Log Message:
pipe(2): Restore kevent EVFILT_READ/WRITE success on wrong pipe end.
In rev. 1.174, while cleaning up various issues in select/poll/kqueue
logic for pipes, I changed the behaviour of kevent when adding an
EVFILT_READ event for the write side of a pipe, or an EVFILT_WRITE
event for the read side of a pipe, to fail with EINVAL; previously it
would quietly be accepted and do nothing, which struck me, without much
thought, as uncontroversially wrong and unhelpful. But apparently
that's what FreeBSD and OpenBSD do too, and it seems that applications
such as mail/dovecot2 rely on it. So put it back.
PR kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
To generate a diff of this commit:
cvs rdiff -u -r1.179 -r1.180 src/sys/kern/sys_pipe.c
cvs rdiff -u -r1.3 -r1.4 src/tests/kernel/kqueue/read/t_pipe.c
cvs rdiff -u -r1.6 -r1.7 src/tests/kernel/kqueue/write/t_pipe.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60851 CVS commit: src/sys/kern
Date: Mon, 5 Oct 2026 21:14:15 +0000
Module Name: src
Committed By: riastradh
Date: Mon Oct 5 21:14:15 UTC 2026
Modified Files:
src/sys/kern: sys_pipe.c
Log Message:
pipe(2): Restore kevent EVFILT_READ/WRITE success on wrong pipe end.
Missed a spot when gathering the hunks in the previous change for
this.
PR kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
To generate a diff of this commit:
cvs rdiff -u -r1.182 -r1.183 src/sys/kern/sys_pipe.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Taylor R Campbell <riastradh@NetBSD.org>
To: Markus Kilbinger <mk@kilbi.de>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
Date: Tue, 6 Oct 2026 04:08:42 +0000
> Date: Mon, 5 Oct 2026 14:46:45 +0200
> From: Markus Kilbinger <mk@kilbi.de>
>
> Seems to stabilize my aarch64 machine, but does not solve the problem
> pkgsrc/mail/dovecot2 has:
>
> maillog excerpt:
> ... dovecot: master: Error: service(config): command startup failed,
> throttling for 60.000 secs
> ... dovecot: master: Error: service(stats): command startup failed,
> throttling for 60.000 secs
> ... dovecot: master: Error: service(imap-login): command startup
> failed, throttling for 60.000 secs
> ... dovecot: master: Error: service(config): command startup failed,
> throttling for 60.000 secs
Can you please update to the latest sys_pipe.c (1.186) and try dovecot
again?
From: Markus Kilbinger <mk@kilbi.de>
To: gnats-bugs@netbsd.org
Cc: riastradh@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
campbell+netbsd@mumble.net
Subject: Re: kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
Date: Tue, 6 Oct 2026 08:57:51 +0200
Am Di., 6. Okt. 2026 um 06:10 Uhr schrieb Taylor R Campbell via gnats
<gnats-admin@netbsd.org>:
>
> The following reply was made to PR kern/60851; it has been noted by GNATS.
>
> From: Taylor R Campbell <riastradh@NetBSD.org>
> To: Markus Kilbinger <mk@kilbi.de>
> Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
> Subject: Re: kern/60851: change in pipe kevent EVFILT_READ/WRITE on wrong end
> Date: Tue, 6 Oct 2026 04:08:42 +0000
> [...]
> > ... dovecot: master: Error: service(config): command startup failed,
> > throttling for 60.000 secs
>
> Can you please update to the latest sys_pipe.c (1.186) and try dovecot
> again?
Yes: For me it looks good so far:
- all subprocs are started now:
$ ps awx | grep dove
470 ? I 0:00.01 dovecot/imap
582 ? I 0:00.01 dovecot/log
2371 ? Is 0:00.04 /usr/pkg/sbin/dovecot
2373 ? I 0:00.01 dovecot/anvil
2377 ? I 0:00.03 dovecot/config
3872 ? I 0:00.02 dovecot/stats
14118 ? I 0:00.07 dovecot/auth -w
15839 ? I 0:00.02 dovecot/imap-login
20569 ? I 0:00.00 dovecot/auth
- ... and seem to react normally again (I can retrieve mails).
Thanks, Markus
State-Changed-From-To: open->closed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Thu, 08 Oct 2026 15:39:59 +0000
State-Changed-Why:
fixed in HEAD, and the changes it's based on probably won't get pulled up
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.