bb_sanitize_stdio_maybe_daemonize faulty logic...

David Daney ddaney at avtrex.com
Tue Feb 13 10:28:13 PST 2007


Consider this program:

---------------------------------------
#include <stdio.h>
#include <sys/socket.h>


static int open_a_socket()
{
     int s = socket(PF_INET, SOCK_DGRAM, 0);
     printf("Opened on fd %d\n", s);
     return s;
}


int
main(int argc, char *argv[])
{
     int c;

     open_a_socket();
     open_a_socket();
     open_a_socket();
     open_a_socket();
     open_a_socket();
     open_a_socket();
     c = open_a_socket();
     open_a_socket();
     open_a_socket();
     open_a_socket();
     open_a_socket();

     close(c);
     open_a_socket();

     return 0;
}
-----------------------------------

Note that the last open reuses the fd of the closed socket, but there 
are a lot of open sockets with fd values greater than the last socket 
opened.

Now look at bb_sanitize_stdio_maybe_daemonize:

-----------------------------------------
void bb_sanitize_stdio_maybe_daemonize(int daemonize)
{
         int fd;
         /* Mega-paranoid */
         fd = xopen(bb_dev_null, O_RDWR);
         while ((unsigned)fd < 2)
                 fd = dup(fd); /* have 0,1,2 open at least to /dev/null */
         if (daemonize) {
                 pid_t pid = fork();
                 if (pid < 0) /* wtf? */
                         bb_perror_msg_and_die("fork");
                 if (pid) /* parent */
                         exit(0);
                 /* child */
                 /* if daemonizing, make sure we detach from stdio */
                 setsid();
                 dup2(fd, 0);
                 dup2(fd, 1);
                 dup2(fd, 2);
         }
         while (fd > 2)
                 close(fd--); /* close everything after fd#2 */
}
-----------------------------------------

The result of the first xopen is used as a marker to try to find the 
highest active descriptor.  Then all descriptors greater than 2 and less 
than the marker are closed.

The problem is that the marker could fall in a hole in the middle of the 
range of open descriptors (as in the top example), in which case 
bb_sanitize_stdio_maybe_daemonize could leave some descriptors open that 
should have been closed.

David Daney


More information about the busybox mailing list