[syslog-ng] Unpredictable log output when message has many newlines
Balazs Scheidler
bazsi at balabit.hu
Fri Mar 21 12:37:22 CET 2008
On Fri, 2008-03-21 at 12:21 +0100, Balazs Scheidler wrote:
> On Sun, 2008-03-16 at 16:38 +0100, Jean-Baptiste Quenot wrote:
> > Hi there,
> >
> > Thanks for the great syslog-ng program, it rocks.
> >
> > I have a step-by-step recipe below that yields unpredictable results
> > in the syslog output, and this worries me a bit as in my company we
> > have similar messages sent to syslog by PHP's print_r() function. The
> > example is simplified to a message that consists of 40 occurences of
> > an incrementing number, with a newline separating each number. Let's
> > call it syslog_overflow.txt:
> >
>
> This seems to be a genuine bug in syslog-ng.
>
> It is related to the fact that syslog-ng tries to fetch multiple
> messages at a single poll iteration, and that reading EOF from a stream
> results in the remainder message to be flushed unconditonally.
>
> This is what happens:
> * the complete 0-39 sequence of numbers is sent to syslog-ng in a
> single "packet", which is read by syslog-ng as one packet
> * syslog-ng then reads an EOF while there are still some messages in
> the incoming queue
>
> But on the reception of an EOF, syslog-ng takes the remainder of the
> buffer as a single message. This assumption is wrong.
>
> The problem is in log_reader_fetch_log() message and the way EOF is
> handled.
>
> For some reason I can't reproduce the same problem with 2.1 and I still
> can't see why.
>
> I'll give it a spin to fix this.
>
>
Can you check if this patch fixes it?
diff --git a/src/logreader.c b/src/logreader.c
index 11b84bb..a723b1c 100644
--- a/src/logreader.c
+++ b/src/logreader.c
@@ -416,10 +416,14 @@ log_reader_fetch_log(LogReader *self, FDRead *fd)
msg_verbose("EOF occurred while reading",
evt_tag_int(EVT_TAG_FD, fd->fd),
NULL);
- log_reader_iterate_buf(self, NULL, TRUE, &msg_count);
- log_pipe_notify(self->control, &self->super.super, NC_CLOSE, self);
+ log_reader_iterate_buf(self, NULL, FALSE, &msg_count);
g_sockaddr_unref(sa);
- return FALSE;
+ if (self->ofs == 0)
+ {
+ log_pipe_notify(self->control, &self->super.super, NC_CLOSE, self);
+ return FALSE;
+ }
+ break;
}
else
{
I'm unable to test personally as my perl interpreter appends a '\0' character at
the end of the log message and in that case (this is done by recent libc versions),
syslog-ng considers it to be terminated by NUL, instead of NL.
--
Bazsi
More information about the syslog-ng
mailing list