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