eliminating MAXHEADERSIZE

Julien ÉLIE julien at trigofacile.com
Sat Jul 17 07:58:45 UTC 2010


Hi Florian,

I sometimes have security warnings with your signed mails.
Windows Mail complains that the expeditor is not the right one:
mismatch between "zedat.fu-berlin.de" and "CIS.FU-Berlin.DE".



> yes, and I think it's a good idea to call it something other than
> MAXHEADERSIZE - how about MAXARTLINELENGTH, or is there a reason why
> we'd speak of a line size rather than a line length?

MAXARTLINELENGTH is fine.  Adopted.



> Please be careful when carrying out the substitutions, though, I'm not
> really familiar with all the occurrences and I think I was wrong when I
> said above that innd/art.c:848 is the only place where it really means line
> length; I think innd/art.c:1438 should also become MAXARTLINELENGTH and
> not MED_BUFFER.

You're totally right.  We're checking the Xref: header field length
at line 1438.



Incidentally, isn't there two bugs in this function?

* When resizing the buffer, extra place for a CRLF that may be added
  by a continuation line is not taken into account.  Consequently,
  when p[0] = '\r' and p[1] = '\n' are used, a segfault may occur!

* When comparing to MAXARTLINELENGTH, the final CRLF is not taken into
  account ("+2" is missing in the count), so the generated Xref: header
  field might end up with 1002 bytes!


OK, these are very edge cases.  I bet they never happened in the wild
but better fix them!


Suggested fix:


@@ -1429,14 +1430,16 @@
       continue;
     }
     ngp->Filenum = ngp->Last;
-    /*  len  ' ' "news_groupname"  ':' "#" "\r\n" */
-    if (len + 1 + ngp->NameLength + 1 + 10 + 2 > data->XrefBufLength) {
-      data->XrefBufLength += MAXHEADERSIZE;
+    /*  len  ' ' "news_groupname"  ':' "#" "\r\n"
+        plus an extra 2 bytes for "\r\n" in case of a continuation line. */
+    if (len + 1 + ngp->NameLength + 1 + 10 + 2 + 2 > data->XrefBufLength) {
+      data->XrefBufLength += MED_BUFFER;
       data->Xref = xrealloc(data->Xref, data->XrefBufLength);
       p = data->Xref + len;
     }
-    if (linelen + 1 + ngp->NameLength + 1 + 10 > MAXHEADERSIZE) {
-      /* line exceeded */
+    /* Trailing CRLF is counted in the maximum length. */
+    if (linelen + 1 + ngp->NameLength + 1 + 10 + 2 > MAXARTLINELENGTH) {
+      /* Line exceeded. */
       sprintf(p, "\r\n %s:%lu", ngp->Name, ngp->Filenum);
       buflen = strlen(p);
       linelen = buflen - 2;
@@ -1449,10 +1452,11 @@
     p += buflen;
   }
   /* p[0] is replaced with '\r' to be wireformatted when stored.  p[1] needs to
-     be '\n' */
+     be '\n'.  We have enough place to modify p here (checked during the
+     reallocation above). */
   p[0] = '\r';
   p[1] = '\n';
-  /* data->XrefLength includes trailing "\r\n" */
+  /* data->XrefLength includes trailing "\r\n". */





I also see that supporting 64-bit article numbers without latent bugs
is far from easy...
This "+10" in the code is a great pitfall...

-- 
Julien ÉLIE

« Tous les champignons sont comestibles. Certains, une fois seulement. » 




More information about the inn-workers mailing list