From: Matthias Andree <matthias.andree@xxxxxx>
Date: Wed, 06 Nov 2002 22:12:36 +0100

On Wed, 06 Nov 2002, Junjiro Okajima wrote:

> Is this ML alive?

Indeed, it is.

> My friend told me and pointed out there is a small bug in
> qmail-local.c in qmail-1.03.
> in main(), line 648, he guesses this code is to skip some white characters,
>
>      while ((k > i) && (cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t'))
>
> should be
>
>      while ((k > i) && ((cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t')))
>
> since tab character can be matched if 'k' is less than or equal to
> 'i'.

Indeed, that's a bug, it might make qmail-local scribble over memory when it
should not. To trigger this, edit .qmail local to have the first line
contain just tabs, try:

printf '\t\n' >~/.qmail-testme

then send a mail to address-testme, replacing address by your local
mail address.

It will not crash, but write an additional NUL character into ueo.a. On
intel and other little endian machines, (that store LSB first and MSB
last), it won't usually matter unless the sender is VERY long. If ueo.a
is reused, bad things happen, but it looks as though it was not.

On big endian machines (m68k, sparc, maybe others), this may however
reset ueo.a to zero for typical setups, but it looks as though ueo.a was
not used any more. Plus, qmail-local runs as the user who owns the
.qmail file, and even if qmail-local crashed, the user would (worst
case) only lose his own mail, and there are easier ways to achieve this,
for example: echo "|exit 0" >~/.qmail-testme

> As I read that point and found that the condition is bad, but the
> value of 'i' is initialized and nothing bad will happen.
> Is it right?

The reason for "nothing bad will happen" is wrong. See above.

--
Matthias Andree


--- qmail-local.c	Wed Jan 23 14:57:03 2002
+++ -	Mon Jan 13 10:33:01 2003
@@ -645,7 +645,7 @@
     {
      cmds.s[j] = 0;
      k = j;
-     while ((k > i) && (cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t'))
+     while ((k > i) && ((cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t')))
        cmds.s[--k] = 0;
      switch(cmds.s[i])
       {


