RFC: chop down fakeidentd?

Denis Vlasenko vda.linux at googlemail.com
Sat Jan 13 00:10:06 UTC 2007


On Saturday 13 January 2007 00:15, Luciano Miguel Ferreira Rocha wrote:
> On Fri, Jan 12, 2007 at 11:28:18PM +0100, Denis Vlasenko wrote:
> > On Friday 12 January 2007 21:07, Luciano Miguel Ferreira Rocha wrote:
> > > > But we open syslog with openlog(), not open(). While we suspect that
> > > > it internally does open() a fd, it is just a guess.
> > > 
> > > It opens a socket to syslog.
> > 
> > Nothing guarantees that.
> 
> No, but it needs to communicate with outside, and that usually happens
> via file descriptors.

Care to look at the code?

        fd = create_and_bind_stream_or_die(bind_ip_address, bb_lookup_port("identd", "tcp", 113));
        xlisten(fd, 5);

        pid = fork();
        if (pid < 0)
                bb_perror_msg_and_die("fork");
        if (pid != 0) /* parent */
                exit(0);
        /* child */
        setsid();
        movefd(fd, 0);
        while (fd)
                close(fd--);

Here we have only one open descriptor - 0.

        openlog(applet_name, 0, LOG_DAEMON);

Now openlog MAYBE opens fd 1. Or maybe it does not.
Hell, it can even open several descriptors for some obscure reason.
Ww simply don't know.

        logmode = LOGMODE_SYSLOG;

        /* main loop where we process all events and never exit */
        while (1) {
		...
                select(G.conncnt + FCS, &rfds, NULL, NULL, G.conncnt? &tv: NULL);

FCS is constant 2. Code EXPECTS that all all fds
open using accept start from 2.

                for (i = G.conncnt - 1; i >= 0; i--) {
                        int s = i + FCS;
                        if (FD_ISSET(s, &rfds)) {
				...read...
                        } else {
				...check timeout...
                        }
                }
                if (FD_ISSET(0, &rfds)) {
                        int s = accept(0, NULL, 0);

Here accept may return 2, if openlog() did open fd# 1,
or 1, if openlog() didnt. If it will return 1, all hell
will broke loose.

                        if (s < 0) {
                                if (errno != EINTR)
                                        bb_perror_msg("accept");

We call syslog() inside bb_perror_msg().
What if in glibc 2.5.2 openlog() does NOT open the fd,
but instead the first syslog() call does that?

If I understand this correctly this code will fail horribly then.
--
vda



More information about the busybox mailing list