On 2014-11-17 Jakub Wilk wrote:

> The attached tarball contains 3 test cases that crash formail:
> 
> $ formail < test1
> *** Error in `formail': malloc(): memory corruption: 0x0933c018 ***
> Aborted
> 
> $ formail < test2
> *** Error in `formail': free(): invalid next size (fast): 0x08a321b0 ***
> Aborted
> 
> $ formail < test3
> formail: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char 
> *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, 
> fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned 
> long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 
> *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size 
> & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
> Aborted

The attached patch seems to fix these. Feel free to use it. But
better make sure that it does the right thing, because C is not my
first language.

What the patch does:
* allocate enough memory to add angle brackets to From line values
* do not "skip" the last character of a string
diff -ur procmail-3.22-22.orig/src/formail.c procmail-3.22-22/src/formail.c
--- procmail-3.22-22.orig/src/formail.c	2015-02-07 17:04:31.000000000 +0100
+++ procmail-3.22-22/src/formail.c	2015-02-07 16:46:35.663935802 +0100
@@ -219,7 +219,7 @@
   if(i>=0&&(i!=maxindex(sest)||fldp==rdheader))		  /* found anything? */
    { char*saddr;char*tmp;			     /* determine the weight */
      nowm=areply&&headreply?headreply==1?sest[i].wrepl:sest[i].wrrepl:i;chp+=j;
-     tmp=malloc(j=fldp->Tot_len-j);tmemmove(tmp,chp,j);(chp=tmp)[j-1]='\0';
+     tmp=malloc((j=fldp->Tot_len-j) + 1);tmemmove(tmp,chp,j);(chp=tmp)[j-1]='\0';
      if(sest[i].head==From_)
       { char*pastad;
 	if(strchr(saddr=chp,'\n'))		     /* multiple From_ lines */
diff -ur procmail-3.22-22.orig/src/formisc.c procmail-3.22-22/src/formisc.c
--- procmail-3.22-22.orig/src/formisc.c	2015-02-07 17:04:31.000000000 +0100
+++ procmail-3.22-22/src/formisc.c	2015-02-07 15:14:56.941053913 +0100
@@ -66,7 +66,7 @@
 retz:	      *target='\0';
 ret:	      return start;
 	    }
-	   if(*start=='\\')
+	   if(*start=='\\' && *(start + 1))
 	      *target++='\\',start++;
 	   hitspc=2;
 	   goto normal;					      /* normal word */

Reply via email to