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