Telnetd should close stray descriptors in its children

Doug Graham dgraham at nortel.com
Thu Jun 11 15:53:48 UTC 2009


Denys Vlasenko wrote:
> On Tue, Jun 9, 2009 at 11:45 PM, Doug Graham<dgraham at nortel.com> wrote:
>
>   
>> Oops.  In that case, scratch some of my previous reply too.  I'll give it a
>> try, but
>> I have to say that I still like my patch more.  It makes it clear that the
>> child only
>> gets descriptors 0, 1, and 2, and it's simpler.  Your patch is more precise
>> about
>> what it closes, but that means that if, say, telnetd itself inherited a
>> descriptor from
>> its invoker,
>>     
>
> Yes, your code works.
>
> By this logic almost every program has to do the same when it starts.
>   

Nah, this really only applies to applications that need to set up 
pristine and secure
environments for other applications to run in.  Dtach, screen, login, 
sshd/telnetd etc.

> Another drawback is that ~1020 close() calls is a bit much.
>   

It does seems a bit drastic, doesn't it?  But a close that fails with EBADF
should be cheap.

> Pity there is no way to ask "what is the highest open fd#?" in Unix.
>   
I suppose you could read /proc/self/fd, but that would be nonportable, a bit
complicated, and probably slower than just closing everything up to
_SC_OPEN_MAX.  I didn't steal that idea from glibc (I thought it up
all by myself :-)), but afterwards, I went looking through glibc to see if
there's anything in there that might do the job, and came across some 
interesting
code in nscd.c.  It actually does scan /proc/self/fd to get the descriptors
to close.  If opening /proc/self/fd fails, it falls back to closing 
everything
up to getdtablesize().  I guess that's more scalable, but it does seems like
a lot of extra work for probably no benefit most of the time.  Especially
in the case of nscd, which only needs to do this once at startup time.

Anyway, I see that you eventually went with calling close_on_exec_on().

--Doug.




More information about the busybox mailing list