Bug in stock ezmlm-0.53

Bruce Guenter <[email protected]> Fri, 4 Apr 2008 15:59:44 -0600
Newsgroups gmane.mail.ezmlm
Message-ID <[email protected]>
Hi.

I just found a bug in stock ezmlm-0.53, and would like some more
eyeballs to see if my solution makes sense.  The same bug likely also
affects ezmlm-idx, but I haven't had time to check yet.

ezmlm-manage, ezmlm-send, and ezmlm-warn all use 1-byte buffers with
substdio to "fake" an output buffer.  The substdio routines, when
presented with write requests larger than the output buffer size, skip
saving data into the buffer and call the output function directly.  When
the presented write fits into the output buffer, it gets stored there.
None of these three programs flush the output buffer.  So, if there is
exactly one byte more than the input buffer size to copy, that last byte
never gets output.

All three of the programs use 1024 byte input buffers, so the input has
to be exactly one byte larger than a multiple of 1024 to hit the bug.
ezmlm-manage uses the buffers to copy an input message into the output.
A single byte lost there will never be noticed.  ezmlm-warn uses the
buffers to copy files from DIR/text into the output.  Skipping the last
byte just means the messages will be missing a newline.  However,
ezmlm-send uses the buffers to copy subscribers.  If the last subscriber
file hits the bug, qmail-queue will fail, since its envelope input will
not be properly terminated.

Attached is a patch that shrinks the buffers to zero bytes.  From my
reading of the logic, this will force all writes to skip the buffer,
which seems to be the intent.

Does this make sense?

-- 
Bruce Guenter <[email protected]>                http://untroubled.org/

diff a/ezmlm-manage.c b/ezmlm-manage.c
--- a/ezmlm-manage.c
+++ b/ezmlm-manage.c
@@ -77,7 +77,7 @@ int qqwrite(fd,buf,len) int fd; char *buf; unsigned int len;
   qmail_put(&qq,buf,len);
   return len;
 }
-char qqbuf[1];
+char qqbuf[0];
 substdio ssqq = SUBSTDIO_FDBUF(qqwrite,-1,qqbuf,sizeof(qqbuf));
 
 char inbuf[1024];
diff a/ezmlm-send.c b/ezmlm-send.c
--- a/ezmlm-send.c
+++ b/ezmlm-send.c
@@ -54,7 +54,7 @@ struct qmail qq;
 substdio ssin;
 char inbuf[1024];
 substdio ssout;
-char outbuf[1];
+char outbuf[0];
 
 int mywrite(fd,buf,len)
 int fd;
diff a/ezmlm-warn.c b/ezmlm-warn.c
--- a/ezmlm-warn.c
+++ b/ezmlm-warn.c
@@ -53,7 +53,7 @@ int qqwrite(fd,buf,len) int fd; char *buf; unsigned int len;
   qmail_put(&qq,buf,len);
   return len;
 }
-char qqbuf[1];
+char qqbuf[0];
 substdio ssqq = SUBSTDIO_FDBUF(qqwrite,-1,qqbuf,sizeof(qqbuf));
 struct datetime dt;
 char date[DATE822FMT];
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFH9qTQ6W+y3GmZgOgRArE2AJ9LwK2G4foo2jJ0IwGBkR2IpNPAFACfdoad
PosSYlOFgF5vRFkSQmBEzmY=
=T7X3
-----END PGP SIGNATURE-----