Subject: Re: Time to fix a 25 year old misdesign
To: None <tech-kern@netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 10/16/2000 14:41:51
[ On Sunday, October 15, 2000 at 20:10:01 (+0200), Lennart Augustsson wrote: ]
> Subject: Re: Time to fix a 25 year old misdesign
>
> Here's what can happen:  A process opens a device and tells the driver
> it want's SIGIO notification.  It then forks and exits.  Since the
> driver is not notified that the original process has closed its descriptor
> it keeps the reference to the original process.  When this reference
> (proc pointer or pid) gets reused a totally unsuspecting process can
> get the signal.
> 
> I don't see how to implement this right unless the driver gets notified
> on each close so it can drop the reference to the process.

This would be trivial to implement with a simple extension to the driver
API, such as a "dev_sigio_set()" call that registers a process ID for
the driver interrupt routine to trigger SIGIO when the correct
conditions have been met at the hardware level.  The upper layer would
simply de-register the PID upon close(2), perhaps with a corresponding
"dev_sigio_unset()" call.

This of course would mean drivers supporting SIGIO would have to keep a
table of PIDs to signal, and to signal each and every one of them,
unless they forced exclusive access.  Note though that it doesn't really
make sense to have the kernel to wake every possible process up just so
that they can arbitrate amongst themselves as to which will actually
take advantage of the SIGIO condition -- it makes much more sense to
have the driver force exclusive access, and so as I note below perhaps
there's really no need to change anything.

Regardless there's no need to change the driver open() or close() calls
though.

> Am I mistaken, or has SIGIO been broken since its inception?
> (I could be mistaken, I've had enough coffee today. :)

I haven't had enough coffee yet today, but I think you're partly right,
though I don't think there's currently any possibility of the scenario
you described happening in currently implemented drivers (at least not
so far as I can find with grep).

It seems as though at least most drivers can only send SIGIO to one
process at a time (since they store the process to signal in a single
"struct proc *" field in their "struct softc"), and so long as those
drivers also all require exclusive access there's nothing literally
broken -- it's just that the design is perhaps an accident waiting to
happen because it depends upon a side-effect in the open() routine....

If anyone ever gets around to writing driver(9) this caveat of SIGIO
should be clearly documented....  :-)

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>