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 */