[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