Submitted By: Ken Moffat Date: 2018-02-10 Initial Package Version: 3.22 Upstream Status: Defunct Origin: Found at fedora, some are originally from debian. Description: After noticing Arch had picked up a CVE fix from debian, I looked at what distros are doing. Fedora have several patches of apparent relevance: procmail-3.22-truncate.patch procmail-3.22-CVE-2014-3618.patch procmail-3.22-crash-fix.patch (buffer overflows, memory corruption) procmail-3.22-loadbuf_fix.patch (CVE-2017-16844). They also have a consolidated patch from debian_3.22-8, but that includes many things which do not appear to be problem fixes. I then took a look at debian's procmail_3.22-26 patches and selected the following items which are within fedora's debian patch (unfortunately the patch names are just numbers): 10 (segfault in mailfold.c) 14 http://bugs.debian.org/171514 allocate wrong amount of memory in a pipe 17 http://bugs.debian.org/217853 - formail prints body if content length header is found diff -Naur a/src/cstdio.c b/src/cstdio.c --- a/src/cstdio.c 2000-12-31 06:08:20.000000000 +0000 +++ b/src/cstdio.c 2018-02-09 03:01:55.445270475 +0000 @@ -144,7 +144,7 @@ { case '\n':case EOF:*q='\0'; return overflow?-1:p!=q; /* did we read anything at all? */ } - if(q==end) /* check here so that a trailing backslash won't be lost */ + if(q>=end) /* check here so that a trailing backslash won't be lost */ q=p,overflow=1; *q++=i; } @@ -199,7 +199,7 @@ if(*(target=strchr(target,'\0')-1)=='\\') { if(chp2!=target) /* non-empty line? */ target++; /* then preserve the backslash */ - if(target>end-2) /* space enough for getbl? */ + if(target>=end-2) /* space enough for getbl? */ target=end-linebuf,overflow=1; /* toss what we have */ continue; } diff -Naur a/src/formail.c b/src/formail.c --- a/src/formail.c 2001-09-11 05:57:32.000000000 +0100 +++ b/src/formail.c 2018-02-09 03:13:54.650374132 +0000 @@ -219,7 +219,8 @@ 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'; + chp[j]='\0'; if(sest[i].head==From_) { char*pastad; if(strchr(saddr=chp,'\n')) /* multiple From_ lines */ @@ -364,7 +365,7 @@ int main(lastm,argv)int lastm;const char*const argv[]; { int i,split=0,force=0,bogus=1,every=0,headreply=0,digest=0,nowait=0,keepb=0, - minfields=(char*)progid-(char*)progid,conctenate=0,babyl=0,babylstart, + minfields=(char*)progid-(char*)progid,conctenate=0,babyl=0,babylstart=0, berkeley=0,forgetclen; long maxlen,ctlength;FILE*idcache=0;pid_t thepid; size_t j,lnl,escaplen;char*chp,*namep,*escap=ESCAP; @@ -758,9 +759,9 @@ lputssn(buf,buffilled),ctlength-=buffilled,buffilled=lnl=0; ;{ int tbl=buflast,lwr='\n'; while(--ctlength>=0&&tbl!=EOF) /* skip Content-Length: bytes */ - lnl=lwr==tbl&&lwr=='\n',putcs(lwr=tbl),tbl=getchar(); + lnl=lwr==tbl&&lwr=='\n',lputcs(lwr=tbl),tbl=getchar(); if((buflast=tbl)=='\n'&&lwr!=tbl) /* just before a line break? */ - putcs('\n'),buflast=getchar(); /* wrap up loose end */ + lputcs('\n'),buflast=getchar(); /* wrap up loose end */ } if(!quiet&&ctlength>0) { charNUM(num,ctlength); diff -Naur a/src/formisc.c b/src/formisc.c --- a/src/formisc.c 2001-06-29 03:20:45.000000000 +0100 +++ b/src/formisc.c 2018-02-09 03:03:48.643338792 +0000 @@ -66,7 +66,7 @@ retz: *target='\0'; ret: return start; } - if(*start=='\\') + if(*start=='\\' && *(start + 1)) *target++='\\',start++; hitspc=2; goto normal; /* normal word */ @@ -84,12 +84,11 @@ case '"':*target++=delim='"';start++; } ;{ int i; - do + while(*start) /* anything? */ if((i= *target++= *start++)==delim) /* corresponding delimiter? */ break; else if(i=='\\'&&*start) /* skip quoted character */ *target++= *start++; - while(*start); /* anything? */ } hitspc=2; } @@ -104,7 +103,7 @@ } /* append to buf */ void loadbuf(text,len)const char*const text;const size_t len; -{ if(buffilled+len>buflen) /* buf can't hold the text */ +{ while(buffilled+len>buflen) /* buf can't hold the text */ buf=realloc(buf,buflen+=Bsize); tmemmove(buf+buffilled,text,len);buffilled+=len; } diff -Naur a/src/mailfold.c b/src/mailfold.c --- a/src/mailfold.c 2001-09-11 05:58:34.000000000 +0100 +++ b/src/mailfold.c 2018-02-09 03:13:29.705919868 +0000 @@ -30,6 +30,7 @@ int logopened,rawnonl; off_t lasttell; +static int trunced; static long lastdump; static volatile int mailread; /* if the mail is completely read in already */ static struct dyna_array confield; /* escapes, concatenations */ @@ -81,6 +82,7 @@ long len; { int i;long part; lasttell=i= -1;SETerrno(EBADF); + trunced=0; if(s>=0) { if(ft_lock(type)&&(lseek(s,(off_t)0,SEEK_END),fdlock(s))) nlog("Kernel-lock failed\n"); @@ -120,13 +122,18 @@ } writefin: i=type!=ft_PIPE&&fsync(s)&&errno!=EINVAL; /* EINVAL => wasn't a file */ + if ((i||len)&&lasttell>=0) + { int serrno=errno; + if(!ftruncate(s,lasttell)) trunced=1; + SETerrno(serrno); + } if(ft_lock(type)) { int serrno=errno; /* save any error information */ if(fdunlock()) nlog("Kernel-unlock failed\n"); SETerrno(serrno); } - i=rclose(s)||i; + i=rclose(s)||i; /* if this fails, we should truncate, but it's too late */ } /* return an error even if nothing was to be sent */ return i&&!len?-1:len; } @@ -237,7 +244,7 @@ #endif default:writeerr(buf); } - if(lasttell>=0&&!truncate(boxname,lasttell)&&(logopened||verbose)) + if(lasttell>=0&&trunced&&(logopened||verbose)) nlog("Truncated file to former size\n"); /* undo garbage */ ret0: return 0; } @@ -378,7 +385,8 @@ dfilled=mailread=0; else if(rhead) /* only read in a new header */ { memblk new; - dfilled=mailread=0;makeblock(&new,0);readdyn(&new,&dfilled,0); + dfilled=mailread=0;makeblock(&new,0); + readdyn(&new,&dfilled,thebody-themail.p); if(tobesent>dfilled&&isprivate) /* put it in place here */ { tmemmove(themail.p+dfilled,thebody,filled-=tobesent); tmemmove(themail.p,new.p,dfilled); diff -Naur a/src/pipes.c b/src/pipes.c --- a/src/pipes.c 2001-09-11 05:58:44.000000000 +0100 +++ b/src/pipes.c 2018-02-09 03:13:43.654173861 +0000 @@ -194,7 +194,7 @@ makeblock(&temp,Stdfilled); tmemmove(temp.p,Stdout,Stdfilled); readdyn(&temp,&Stdfilled,Stdfilled+backlen+1); - Stdout=realloc(Stdout,&Stdfilled+1); + Stdout=realloc(Stdout,Stdfilled+1); tmemmove(Stdout,temp.p,Stdfilled+1); freeblock(&temp); retStdout(Stdout,pwait&&pipw,!backblock);