Subject: MSG_CTRUNC vs SCM_RIGHTS
To: None <tech-net@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 04/12/2004 02:30:38
I'm building some code that uses SCM_RIGHTS file-descriptor passing.
I've run into a problem, though, and I'm wondering what the correct
approach is.

Most basically, the problem is that once unp_externalize has been
called for a message, the process has the descriptors - but if the
control buffer is too small, the process won't find out the file
descriptor numbers of all of them.

This makes it difficult to build protocols involving fd passing which
must withstand potentially malicious clients, since a malicious sender
can dump an effectively unlimited number of extra file descriptors into
the receiver's open file table, and the victim has no easy way to tell
which oens they are or even how many of them there are.  (It's not
quite impossible; with the help of another process such an attack can
at least be withstood, but I haven't found a way that costs less than
one fork per malicious send.)

So I was looking at the socket code.  It looks hard to avoid giving the
process those file descriptors in the first place (unp_externalize
can't easily be made to know how much space is available), but it looks
relatively easy to clean up after the fact, closing the descriptors
that are being (at least partially) truncated away.

The reason I'm writing here is to ask, would doing that be fixing a bug
or breaking a feature?  I have trouble imagining a use for receiving
file descriptors without being told what they are, but it wouldn't be
the first time I'd been unable to see a use for something that actually
was useful.  If the current behaviour is considered a feature, what
would people think of a recv flag to get the other behaviour?  (And
does anyone have a better name than MSG_CLOSE_TRUNCATED_DESCRIPTORS for
it in that case? :-)

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B