Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-18 Thread Martin Pieuchot
On 18/06/20(Thu) 09:03, Martin Pieuchot wrote:
> On 17/06/20(Wed) 11:50, Martin Pieuchot wrote:
> > On 16/06/20(Tue) 06:18, Todd C. Miller wrote:
> > > On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> > > 
> > > > The diff below implements DragonFly's approach of adding a new kind of
> > > > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > > > existing kqueue interface which is questionable.  On the one hand this
> > > > allows userland programs to use kevent(2) to check for this conditions.
> > > > One the other hand this is not supported by any other BSD and thus non
> > > > standard.
> > > 
> > > Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> > > the first OS to implement poll in terms of kqueue as far as I know.
> > > I don't think there is a problem extended kqueue with EVFILT_EXCEPT.
> > > 
> > > > In the tree there's two poll handlers that set the POLLPRI & POLLRDBAND
> > > > bits as illustrated by the diff below.
> > > >
> > > > Do we see value in this new type of filter?  Should I document it and
> > > > put it in?  Or should I restrict it to the __EV_POLL for now?  In the
> > > > latter case should we pick a different name and/or prefix it?
> > > 
> > > I think EVFILT_EXCEPT should be exposed to userland.  It is not our
> > > own invention and two other OSes support it.
> > 
> > Updated diff below addresses multiples comments and implements the
> > common functionalities of EVFILT_EXCEPT supported by both DragonFly
> > and xnu.  Changes compared to the previous version include:
> > 
> > - Introduction of NOTE_OOB which should be set in `fflags' according to
> >   other implementations
> > - Set `kn_data' to the value of `so_oobmark' for sockets.  This matches
> >   xnu behavior, the arbitrary value was also questioned by visa@.
> > - Adds a missing break pointed out by anton@
> > - Set NOTE_OOB for pty as well, this isn't supported by DragonFly nor
> >   xnu but I don't see the point of introducing something different.
> > - Document the new filter
> > 
> > Note that the last available version of Xnu available on github, from
> > late 2018, has the following behavior which this diff doesn't implement:
> > 
> > If the read direction of the socket has shutdown, then
> > the filter also sets EV_EOF in flags, and returns the
> > socket error (if any) in fflags
> 
> Simpler version that re-use the read filters.  This one checks for NOTE_OOB
> in `kn_sfflags' like it is done for all other flags (pointed out by visa@). 

New version that properly handles the case where NOTE_OOB is not set,
pointed out by visa@.


Index: sys/kern/kern_event.c
===
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.139
diff -u -p -r1.139 kern_event.c
--- sys/kern/kern_event.c   15 Jun 2020 15:42:11 -  1.139
+++ sys/kern/kern_event.c   17 Jun 2020 09:35:42 -
@@ -158,6 +158,7 @@ const struct filterops *const sysfilt_op
_filtops,   /* EVFILT_SIGNAL */
_filtops, /* EVFILT_TIMER */
_filtops,  /* EVFILT_DEVICE */
+   _filtops,  /* EVFILT_EXCEPT */
 };
 
 void
Index: sys/kern/tty_pty.c
===
RCS file: /cvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.100
diff -u -p -r1.100 tty_pty.c
--- sys/kern/tty_pty.c  15 Jun 2020 15:29:40 -  1.100
+++ sys/kern/tty_pty.c  18 Jun 2020 14:42:33 -
@@ -668,6 +668,16 @@ filt_ptcread(struct knote *kn, long hint
tp = pti->pt_tty;
kn->kn_data = 0;
 
+   if (kn->kn_sfflags & NOTE_OOB) {
+   /* If in packet or user control mode, check for data. */
+   if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+   ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) {
+   kn->kn_fflags |= NOTE_OOB;
+   kn->kn_data = 1;
+   return (1);
+   }
+   return (0);
+   }
if (ISSET(tp->t_state, TS_ISOPEN)) {
if (!ISSET(tp->t_state, TS_TTSTOP))
kn->kn_data = tp->t_outq.c_cc;
@@ -733,6 +743,13 @@ const struct filterops ptcwrite_filtops 
.f_event= filt_ptcwrite,
 };
 
+const struct filterops ptcexcept_filtops = {
+   .f_flags= FILTEROP_ISFD,
+   .f_attach   = NULL,
+   .f_detach   = filt_ptcrdetach,
+   .f_event= filt_ptcread,
+};
+
 int
 ptckqfilter(dev_t dev, struct knote *kn)
 {
@@ -748,6 +765,10 @@ ptckqfilter(dev_t dev, struct knote *kn)
case EVFILT_WRITE:
klist = >pt_selw.si_note;
kn->kn_fop = _filtops;
+   break;
+   case EVFILT_EXCEPT:
+   klist = >pt_selr.si_note;
+   kn->kn_fop = _filtops;
break;
default:
return (EINVAL);
Index: 

Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-18 Thread Martin Pieuchot
On 17/06/20(Wed) 11:50, Martin Pieuchot wrote:
> On 16/06/20(Tue) 06:18, Todd C. Miller wrote:
> > On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> > 
> > > The diff below implements DragonFly's approach of adding a new kind of
> > > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > > existing kqueue interface which is questionable.  On the one hand this
> > > allows userland programs to use kevent(2) to check for this conditions.
> > > One the other hand this is not supported by any other BSD and thus non
> > > standard.
> > 
> > Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> > the first OS to implement poll in terms of kqueue as far as I know.
> > I don't think there is a problem extended kqueue with EVFILT_EXCEPT.
> > 
> > > In the tree there's two poll handlers that set the POLLPRI & POLLRDBAND
> > > bits as illustrated by the diff below.
> > >
> > > Do we see value in this new type of filter?  Should I document it and
> > > put it in?  Or should I restrict it to the __EV_POLL for now?  In the
> > > latter case should we pick a different name and/or prefix it?
> > 
> > I think EVFILT_EXCEPT should be exposed to userland.  It is not our
> > own invention and two other OSes support it.
> 
> Updated diff below addresses multiples comments and implements the
> common functionalities of EVFILT_EXCEPT supported by both DragonFly
> and xnu.  Changes compared to the previous version include:
> 
> - Introduction of NOTE_OOB which should be set in `fflags' according to
>   other implementations
> - Set `kn_data' to the value of `so_oobmark' for sockets.  This matches
>   xnu behavior, the arbitrary value was also questioned by visa@.
> - Adds a missing break pointed out by anton@
> - Set NOTE_OOB for pty as well, this isn't supported by DragonFly nor
>   xnu but I don't see the point of introducing something different.
> - Document the new filter
> 
> Note that the last available version of Xnu available on github, from
> late 2018, has the following behavior which this diff doesn't implement:
> 
>   If the read direction of the socket has shutdown, then
>   the filter also sets EV_EOF in flags, and returns the
>   socket error (if any) in fflags

Simpler version that re-use the read filters.  This one checks for NOTE_OOB
in `kn_sfflags' like it is done for all other flags (pointed out by visa@). 

ok?

Index: sys/kern/kern_event.c
===
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.139
diff -u -p -r1.139 kern_event.c
--- sys/kern/kern_event.c   15 Jun 2020 15:42:11 -  1.139
+++ sys/kern/kern_event.c   17 Jun 2020 09:35:42 -
@@ -158,6 +158,7 @@ const struct filterops *const sysfilt_op
_filtops,   /* EVFILT_SIGNAL */
_filtops, /* EVFILT_TIMER */
_filtops,  /* EVFILT_DEVICE */
+   _filtops,  /* EVFILT_EXCEPT */
 };
 
 void
Index: sys/kern/tty_pty.c
===
RCS file: /cvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.100
diff -u -p -r1.100 tty_pty.c
--- sys/kern/tty_pty.c  15 Jun 2020 15:29:40 -  1.100
+++ sys/kern/tty_pty.c  18 Jun 2020 07:00:32 -
@@ -668,6 +668,15 @@ filt_ptcread(struct knote *kn, long hint
tp = pti->pt_tty;
kn->kn_data = 0;
 
+   if (kn->kn_sfflags & NOTE_OOB) {
+   /* If in packet or user control mode, check for data. */
+   if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+   ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) {
+   kn->kn_fflags |= NOTE_OOB;
+   kn->kn_data = 1;
+   return (1);
+   }
+   }
if (ISSET(tp->t_state, TS_ISOPEN)) {
if (!ISSET(tp->t_state, TS_TTSTOP))
kn->kn_data = tp->t_outq.c_cc;
@@ -733,6 +742,13 @@ const struct filterops ptcwrite_filtops 
.f_event= filt_ptcwrite,
 };
 
+const struct filterops ptcexcept_filtops = {
+   .f_flags= FILTEROP_ISFD,
+   .f_attach   = NULL,
+   .f_detach   = filt_ptcrdetach,
+   .f_event= filt_ptcread,
+};
+
 int
 ptckqfilter(dev_t dev, struct knote *kn)
 {
@@ -748,6 +764,10 @@ ptckqfilter(dev_t dev, struct knote *kn)
case EVFILT_WRITE:
klist = >pt_selw.si_note;
kn->kn_fop = _filtops;
+   break;
+   case EVFILT_EXCEPT:
+   klist = >pt_selr.si_note;
+   kn->kn_fop = _filtops;
break;
default:
return (EINVAL);
Index: sys/kern/uipc_socket.c
===
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.245
diff -u -p -r1.245 uipc_socket.c
--- sys/kern/uipc_socket.c  15 Jun 2020 15:29:40 

Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-17 Thread Martin Pieuchot
On 16/06/20(Tue) 06:18, Todd C. Miller wrote:
> On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> 
> > The diff below implements DragonFly's approach of adding a new kind of
> > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > existing kqueue interface which is questionable.  On the one hand this
> > allows userland programs to use kevent(2) to check for this conditions.
> > One the other hand this is not supported by any other BSD and thus non
> > standard.
> 
> Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> the first OS to implement poll in terms of kqueue as far as I know.
> I don't think there is a problem extended kqueue with EVFILT_EXCEPT.
> 
> > In the tree there's two poll handlers that set the POLLPRI & POLLRDBAND
> > bits as illustrated by the diff below.
> >
> > Do we see value in this new type of filter?  Should I document it and
> > put it in?  Or should I restrict it to the __EV_POLL for now?  In the
> > latter case should we pick a different name and/or prefix it?
> 
> I think EVFILT_EXCEPT should be exposed to userland.  It is not our
> own invention and two other OSes support it.

Updated diff below addresses multiples comments and implements the
common functionalities of EVFILT_EXCEPT supported by both DragonFly
and xnu.  Changes compared to the previous version include:

- Introduction of NOTE_OOB which should be set in `fflags' according to
  other implementations
- Set `kn_data' to the value of `so_oobmark' for sockets.  This matches
  xnu behavior, the arbitrary value was also questioned by visa@.
- Adds a missing break pointed out by anton@
- Set NOTE_OOB for pty as well, this isn't supported by DragonFly nor
  xnu but I don't see the point of introducing something different.
- Document the new filter

Note that the last available version of Xnu available on github, from
late 2018, has the following behavior which this diff doesn't implement:

If the read direction of the socket has shutdown, then
the filter also sets EV_EOF in flags, and returns the
socket error (if any) in fflags

ok?

Index: sys/kern/kern_event.c
===
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.139
diff -u -p -r1.139 kern_event.c
--- sys/kern/kern_event.c   15 Jun 2020 15:42:11 -  1.139
+++ sys/kern/kern_event.c   17 Jun 2020 09:35:42 -
@@ -158,6 +158,7 @@ const struct filterops *const sysfilt_op
_filtops,   /* EVFILT_SIGNAL */
_filtops, /* EVFILT_TIMER */
_filtops,  /* EVFILT_DEVICE */
+   _filtops,  /* EVFILT_EXCEPT */
 };
 
 void
Index: sys/kern/tty_pty.c
===
RCS file: /cvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.100
diff -u -p -r1.100 tty_pty.c
--- sys/kern/tty_pty.c  15 Jun 2020 15:29:40 -  1.100
+++ sys/kern/tty_pty.c  17 Jun 2020 09:34:02 -
@@ -107,6 +107,7 @@ voidfilt_ptcrdetach(struct knote *);
 intfilt_ptcread(struct knote *, long);
 void   filt_ptcwdetach(struct knote *);
 intfilt_ptcwrite(struct knote *, long);
+intfilt_ptcexcept(struct knote *, long);
 
 static struct pt_softc **ptyarralloc(int);
 static int check_pty(int);
@@ -719,6 +720,25 @@ filt_ptcwrite(struct knote *kn, long hin
return (kn->kn_data > 0);
 }
 
+int
+filt_ptcexcept(struct knote *kn, long hint)
+{
+   struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
+   struct tty *tp;
+
+   tp = pti->pt_tty;
+   kn->kn_data = 0;
+
+   /* If in packet or user control mode, check for data. */
+   if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+   ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) {
+   kn->kn_fflags |= NOTE_OOB;
+   kn->kn_data = 1;
+   }
+
+   return (kn->kn_data > 0);
+}
+
 const struct filterops ptcread_filtops = {
.f_flags= FILTEROP_ISFD,
.f_attach   = NULL,
@@ -733,6 +753,13 @@ const struct filterops ptcwrite_filtops 
.f_event= filt_ptcwrite,
 };
 
+const struct filterops ptcexcept_filtops = {
+   .f_flags= FILTEROP_ISFD,
+   .f_attach   = NULL,
+   .f_detach   = filt_ptcrdetach,
+   .f_event= filt_ptcexcept,
+};
+
 int
 ptckqfilter(dev_t dev, struct knote *kn)
 {
@@ -748,6 +775,10 @@ ptckqfilter(dev_t dev, struct knote *kn)
case EVFILT_WRITE:
klist = >pt_selw.si_note;
kn->kn_fop = _filtops;
+   break;
+   case EVFILT_EXCEPT:
+   klist = >pt_selr.si_note;
+   kn->kn_fop = _filtops;
break;
default:
return (EINVAL);
Index: sys/kern/uipc_socket.c
===
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.245

Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread William Ahern
On Tue, Jun 16, 2020 at 06:18:13AM -0600, Todd C. Miller wrote:
> On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> 
> > The diff below implements DragonFly's approach of adding a new kind of
> > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > existing kqueue interface which is questionable.  On the one hand this
> > allows userland programs to use kevent(2) to check for this conditions.
> > One the other hand this is not supported by any other BSD and thus non
> > standard.
> 
> Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> the first OS to implement poll in terms of kqueue as far as I know.
> I don't think there is a problem extended kqueue with EVFILT_EXCEPT.

macOS also has EV_OOBAND as an analog to EV_EOF, but the addition caught
people by surprise:

  https://bugs.chromium.org/p/chromium/issues/detail?id=437642
  https://nvd.nist.gov/vuln/detail/CVE-2015-1105

I would guess EV_OOBAND was intended to behave like POLLRDBAND, and
considering that POLLRDBAND is in POLLIN it made some sense to signal
EV_OOBAND by default. Likewis for EV_EOF, which is also always signaled,
though ignoring it is benign. It all seems logical (notwithstanding the
inability to mask it), but only if that was the behavior from day 1.
Surprising people with it doesn't seem like a good idea.



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Vitaliy Makkoveev
On Tue, Jun 16, 2020 at 03:10:02PM +0200, Martin Pieuchot wrote:
> On 16/06/20(Tue) 06:18, Todd C. Miller wrote:
> > On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> > 
> > > The diff below implements DragonFly's approach of adding a new kind of
> > > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > > existing kqueue interface which is questionable.  On the one hand this
> > > allows userland programs to use kevent(2) to check for this conditions.
> > > One the other hand this is not supported by any other BSD and thus non
> > > standard.
> > 
> > Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> > the first OS to implement poll in terms of kqueue as far as I know.
> > I don't think there is a problem extended kqueue with EVFILT_EXCEPT.
> 
> Interesting, is there any open source code from Apple that you could
> point me at?  I'd be interested to study their kqueue interface.
> 

https://github.com/apple/darwin-xnu



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Todd C . Miller
On Tue, 16 Jun 2020 10:13:11 -0600, "Theo de Raadt" wrote:

> Everytime someone did poll on select, or select on poll, or something
> on something, the emulation ended up being dangerously buggy in the
> first round.

Agreed.

> I hope such emulation isn't a goal in libc.  What happens in the kernel
> back side, tho, could do with some simplication.

No one has proposed emulating poll/select in libc.  That is something
I would object to quite strongly.

 - todd



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Theo de Raadt
Todd C. Miller  wrote:

> On Tue, 16 Jun 2020 16:21:14 +0300, Vitaliy Makkoveev wrote:
> 
> > https://github.com/apple/darwin-xnu
> 
> Note that the poll emulation in xnu was incomplete the last time I
> checked.  Granted, that was 10 years ago so it might be better now,
> but at the time you couldn't poll much more than sockets.  I got
> burned trying to poll tty devices which simply didn't work.  The
> select system call doesn't use kqueue as a backend, though.
> 
> According the the man pages this is still the case:
> 
> BUGS
>  The poll() system call currently does not support devices.

Everytime someone did poll on select, or select on poll, or something
on something, the emulation ended up being dangerously buggy in the
first round.

I hope such emulation isn't a goal in libc.  What happens in the kernel
back side, tho, could do with some simplication.



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Todd C . Miller
On Tue, 16 Jun 2020 16:21:14 +0300, Vitaliy Makkoveev wrote:

> https://github.com/apple/darwin-xnu

Note that the poll emulation in xnu was incomplete the last time I
checked.  Granted, that was 10 years ago so it might be better now,
but at the time you couldn't poll much more than sockets.  I got
burned trying to poll tty devices which simply didn't work.  The
select system call doesn't use kqueue as a backend, though.

According the the man pages this is still the case:

BUGS
 The poll() system call currently does not support devices.

 - todd



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Martin Pieuchot
On 16/06/20(Tue) 06:18, Todd C. Miller wrote:
> On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:
> 
> > The diff below implements DragonFly's approach of adding a new kind of
> > filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> > existing kqueue interface which is questionable.  On the one hand this
> > allows userland programs to use kevent(2) to check for this conditions.
> > One the other hand this is not supported by any other BSD and thus non
> > standard.
> 
> Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
> the first OS to implement poll in terms of kqueue as far as I know.
> I don't think there is a problem extended kqueue with EVFILT_EXCEPT.

Interesting, is there any open source code from Apple that you could
point me at?  I'd be interested to study their kqueue interface.



Re: New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Todd C . Miller
On Tue, 16 Jun 2020 12:48:58 +0200, Martin Pieuchot wrote:

> The diff below implements DragonFly's approach of adding a new kind of
> filter, EVFILT_EXCEPT, to report such conditions.  This extends the
> existing kqueue interface which is questionable.  On the one hand this
> allows userland programs to use kevent(2) to check for this conditions.
> One the other hand this is not supported by any other BSD and thus non
> standard.

Actually, it looks like macOS uses EVFILT_EXCEPT too.  They were
the first OS to implement poll in terms of kqueue as far as I know.
I don't think there is a problem extended kqueue with EVFILT_EXCEPT.

> In the tree there's two poll handlers that set the POLLPRI & POLLRDBAND
> bits as illustrated by the diff below.
>
> Do we see value in this new type of filter?  Should I document it and
> put it in?  Or should I restrict it to the __EV_POLL for now?  In the
> latter case should we pick a different name and/or prefix it?

I think EVFILT_EXCEPT should be exposed to userland.  It is not our
own invention and two other OSes support it.

OK millert@

 - todd



New EVFILT_EXCEPT for POLLPRI & POLLRDBAND

2020-06-16 Thread Martin Pieuchot
The kqueue subsystem has no mechanism to indicate "exceptional conditions",
that is the equivalent of poll(2)'s POLLPRI & POLLRDBAND and select(2)'s
`exceptfds'.

The diff below implements DragonFly's approach of adding a new kind of
filter, EVFILT_EXCEPT, to report such conditions.  This extends the
existing kqueue interface which is questionable.  On the one hand this
allows userland programs to use kevent(2) to check for this conditions.
One the other hand this is not supported by any other BSD and thus non
standard.

In the tree there's two poll handlers that set the POLLPRI & POLLRDBAND
bits as illustrated by the diff below.

Do we see value in this new type of filter?  Should I document it and
put it in?  Or should I restrict it to the __EV_POLL for now?  In the
latter case should we pick a different name and/or prefix it?

Index: kern/kern_event.c
===
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.139
diff -u -p -r1.139 kern_event.c
--- kern/kern_event.c   15 Jun 2020 15:42:11 -  1.139
+++ kern/kern_event.c   16 Jun 2020 10:32:45 -
@@ -158,6 +158,7 @@ const struct filterops *const sysfilt_op
_filtops,   /* EVFILT_SIGNAL */
_filtops, /* EVFILT_TIMER */
_filtops,  /* EVFILT_DEVICE */
+   _filtops,  /* EVFILT_EXCEPT */
 };
 
 void
Index: kern/tty_pty.c
===
RCS file: /cvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.100
diff -u -p -r1.100 tty_pty.c
--- kern/tty_pty.c  15 Jun 2020 15:29:40 -  1.100
+++ kern/tty_pty.c  16 Jun 2020 10:32:45 -
@@ -107,6 +107,7 @@ voidfilt_ptcrdetach(struct knote *);
 intfilt_ptcread(struct knote *, long);
 void   filt_ptcwdetach(struct knote *);
 intfilt_ptcwrite(struct knote *, long);
+intfilt_ptcexcept(struct knote *, long);
 
 static struct pt_softc **ptyarralloc(int);
 static int check_pty(int);
@@ -719,6 +720,23 @@ filt_ptcwrite(struct knote *kn, long hin
return (kn->kn_data > 0);
 }
 
+int
+filt_ptcexcept(struct knote *kn, long hint)
+{
+   struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
+   struct tty *tp;
+
+   tp = pti->pt_tty;
+   kn->kn_data = 0;
+
+   /* If in packet or user control mode, check for data. */
+   if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+   ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
+   kn->kn_data = 1;
+
+   return (kn->kn_data > 0);
+}
+
 const struct filterops ptcread_filtops = {
.f_flags= FILTEROP_ISFD,
.f_attach   = NULL,
@@ -733,6 +751,13 @@ const struct filterops ptcwrite_filtops 
.f_event= filt_ptcwrite,
 };
 
+const struct filterops ptcexcept_filtops = {
+   .f_flags= FILTEROP_ISFD,
+   .f_attach   = NULL,
+   .f_detach   = filt_ptcrdetach,
+   .f_event= filt_ptcexcept,
+};
+
 int
 ptckqfilter(dev_t dev, struct knote *kn)
 {
@@ -749,6 +774,9 @@ ptckqfilter(dev_t dev, struct knote *kn)
klist = >pt_selw.si_note;
kn->kn_fop = _filtops;
break;
+   case EVFILT_EXCEPT:
+   klist = >pt_selr.si_note;
+   kn->kn_fop = _filtops;
default:
return (EINVAL);
}
Index: kern/uipc_socket.c
===
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.245
diff -u -p -r1.245 uipc_socket.c
--- kern/uipc_socket.c  15 Jun 2020 15:29:40 -  1.245
+++ kern/uipc_socket.c  16 Jun 2020 10:32:45 -
@@ -71,6 +71,7 @@ int   filt_soread(struct knote *kn, long h
 void   filt_sowdetach(struct knote *kn);
 intfilt_sowrite(struct knote *kn, long hint);
 intfilt_solisten(struct knote *kn, long hint);
+intfilt_soexcept(struct knote *kn, long hint);
 
 const struct filterops solisten_filtops = {
.f_flags= FILTEROP_ISFD,
@@ -93,6 +94,12 @@ const struct filterops sowrite_filtops =
.f_event= filt_sowrite,
 };
 
+const struct filterops soexcept_filtops = {
+   .f_flags= FILTEROP_ISFD,
+   .f_attach   = NULL,
+   .f_detach   = filt_sordetach,
+   .f_event= filt_soexcept,
+};
 
 #ifndef SOMINCONN
 #define SOMINCONN 80
@@ -2026,6 +2033,10 @@ soo_kqfilter(struct file *fp, struct kno
kn->kn_fop = _filtops;
sb = >so_snd;
break;
+   case EVFILT_EXCEPT:
+   kn->kn_fop = _filtops;
+   sb = >so_rcv;
+   break;
default:
return (EINVAL);
}
@@ -2137,6 +2148,21 @@ filt_solisten(struct knote *kn, long hin
if ((hint & NOTE_SUBMIT) == 0)
s = solock(so);
kn->kn_data = so->so_qlen;
+   if ((hint & NOTE_SUBMIT) == 0)
+