bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS) does not close extra fds
Denys Vlasenko
vda.linux at googlemail.com
Fri Mar 15 09:30:20 UTC 2019
On Thu, Mar 14, 2019 at 4:35 PM Arnout Vandecappelle <arnout at mind.be> wrote:
> I've noticed that bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS +
> DAEMON_DEVNULL_STDIO) does not actually close all fds. This is what gets called
> by start-stop-daemon -b, so it means that start-stop-daemon will propagate all
> non-CLOEXEC fds from the parent.
>
> To test:
>
> sh -c 'exec 3>&1; busybox start-stop-daemon -S -b -x /bin/sleep -- 10000'
> ls -l /proc/$(pidof sleep)/fd
Does debian ssd close fd#3 in this case?
> This happens because we do:
>
> if (flags & DAEMON_DEVNULL_STDIO) {
> close(0);
> close(1);
> close(2);
> }
>
> fd = open(bb_dev_null, O_RDWR);
> ...
> while (fd > 2) {
> close(fd--);
> }
>
> Since we just did close(0), fd will be 0.
You skipped this part:
fd = open(bb_dev_null, O_RDWR);
....
while ((unsigned)fd < 2)
fd = dup(fd); /* have 0,1,2 open at least to /dev/null */
fd will be >= 2, not 0.
> The problem is that the assumption that open() returns an fd that is larger
> than all existing fds is simply wrong.
>
> I think that there is no other way to close all open fds than to iterate over
> /proc/self/fd. But that is of course not very portable.
Yes, there is no easy way to close all fds. Usually people go with
something like
fd = 1024;
while (fd) close(fd--);
More information about the busybox
mailing list