Package: mimetex Version: 1.50-1 Severity: normal Tags: patch User: ubuntu-de...@lists.ubuntu.com Usertags: origin-ubuntu karmic ubuntu-patch
*** /tmp/tmpXGbr7m In Ubuntu, we've applied the attached patch to achieve the following: * SECURITY UPDATE: arbitrary code execution via long picture, circle and input tags - mimetex.c: replace strcpy with strninit macro that uses strncpy, adjust some buffer sizes. - CVE-2009-1382 * SECURITY UPDATE: information disclosure via input and counter tags - mimetex.c: disable input and counter tags. - CVE-2009-2459 We thought you might be interested in doing the same. -- System Information: Debian Release: squeeze/sid APT prefers karmic-updates APT policy: (500, 'karmic-updates'), (500, 'karmic-security'), (500, 'karmic') Architecture: amd64 (x86_64) Kernel: Linux 2.6.31-11-generic (SMP w/2 CPU cores) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash
diff -u mimetex-1.50/debian/changelog mimetex-1.50/debian/changelog only in patch2: unchanged: --- mimetex-1.50.orig/mimetex.c +++ mimetex-1.50/mimetex.c @@ -378,6 +378,22 @@ #endif #include "mimetex.h" +/* --- + * internal buffer sizes + * --------------------- */ +#if !defined(MAXEXPRSZ) + #define MAXEXPRSZ (32768-1) /*max #bytes in input tex expression*/ +#endif +#if !defined(MAXSUBXSZ) + #define MAXSUBXSZ (((MAXEXPRSZ+1)/2)-1)/*max #bytes in input subexpression*/ +#endif +#if !defined(MAXTOKNSZ) + #define MAXTOKNSZ (((MAXSUBXSZ+1)/4)-1) /* max #bytes in input token */ +#endif +#if !defined(MAXFILESZ) + #define MAXFILESZ (65536-1) /*max #bytes in input (output) file*/ +#endif + /* ------------------------------------------------------------------------- adjustable default values -------------------------------------------------------------------------- */ @@ -563,6 +579,15 @@ { char *p; while((p=strchr((s),(c)))!=NULL) strcpy(p,p+1); } else #define slower(s) if ((s)!=NULL) /* lowercase all chars in s */ \ { char *p=(s); while(*p!='\000'){*p=tolower(*p); p++;} } else +/* --- check if a string is empty --- */ +#define isempty(s) ((s)==NULL?1:(*(s)=='\000'?1:0)) +/* --- strncpy() n bytes and make sure it's null-terminated --- */ +#define strninit(target,source,n) if( (target)!=NULL && (n)>=0 ) { \ + char *thissource = (source); \ + (target)[0] = '\000'; \ + if ( (n)>0 && thissource!=NULL ) { \ + strncpy((target),thissource,(n)); \ + (target)[(n)] = '\000'; } } /* --- * PART2 @@ -7008,7 +7033,7 @@ -------------------------------------------------------------------------- */ char *texsubexpr(), picexpr[2049], *picptr=picexpr, /* picture {expre} */ putexpr[256], *putptr,*multptr, /*[multi]put (x,y[;xinc,yinc;num])*/ - pream[64], *preptr, /* optional put preamble */ + pream[96], *preptr, /* optional put preamble */ picelem[1025]; /* picture element following put */ subraster *rasterize(), *picelemsp=NULL, /* rasterize picture elements */ *new_subraster(), *picturesp=NULL, /* subraster for entire picture */ @@ -7085,11 +7110,13 @@ *pream = '\000'; /* init preamble as empty string */ if ( (putptr=strchr(putexpr,'$')) != NULL ) /*check for $ pream terminator*/ { *putptr++ = '\000'; /* replace $ by '\0', bump past $ */ - strcpy(pream,putexpr); } /* copy leading preamble from put */ + strninit(pream,putexpr,92); } /* copy leading preamble from put */ else /* look for any non-digit preamble */ - { for ( preptr=pream,putptr=putexpr; ; putptr++ ) + { int npream = 0; /* #chars in preamble */ + for ( preptr=pream,putptr=putexpr; ; npream++,putptr++ ) if ( *putptr == '\000' /* end-of-putdata signalled */ - || !isalpha((int)(*putptr)) ) break; /* or found non-alpha char */ + || !isalpha((int)(*putptr)) /* or found non-alpha char */ + || npream > 92 ) break; /* or preamble too long */ else *preptr++ = *putptr; /* copy alpha char to preamble */ *preptr = '\000'; } /* null-terminate preamble */ /* --- interpret preamble --- */ @@ -7130,7 +7157,7 @@ } /* --- end-of-if(*preptr!='\000') --- */ if ( msgfp!=NULL && msglevel>=29 ) /* debugging */ fprintf(msgfp, - "picture> pream;x,y;xinc,yinc;num=\"%s\";%.2lf,%.2lf;%.2lf,%.2lf;%d\n", + "picture> pream;x,y;xinc,yinc;num=\"%s\";%.2f,%.2f;%.2f,%.2f;%d\n", pream,x,y,xinc,yinc,num); /* ----------------------------------------------------------------------- now obtain {...} picture element following [multi]put, and rasterize it @@ -7171,7 +7198,7 @@ ypos = height - iy; } /* so set for upper instead */ if ( msgfp!=NULL && msglevel>=29 ) /* debugging */ fprintf(msgfp, - "picture> inum,x,y,ix,iy,xpos,ypos=%d,%.2lf,%.2lf,%d,%d,%d,%d\n", + "picture> inum,x,y,ix,iy,xpos,ypos=%d,%.2f,%.2f,%d,%d,%d,%d\n", inum,x,y,ix,iy,xpos,ypos); /* --- embed token raster at xpos,ypos, and quit if out-of-bounds --- */ if ( !rastput(picturerp,picelemsp->image,ypos,xpos,0) ) break; @@ -7362,7 +7389,7 @@ /* --- now interpret xdiam[,ydiam] returned in circexpr --- */ if ( (qptr=strchr(circexpr,';')) != NULL ) /* semicolon signals quads data */ { *qptr = '\000'; /* replace semicolon by '\0' */ - strcpy(quads,qptr+1); /* save user-requested quads */ + strninit(quads,qptr+1,128); /* save user-requested quads */ if ( (qptr=strchr(quads,',')) != NULL ) /* have theta0,theta1 instead */ { *qptr = '\000'; /* replace , with null */ theta0 = strtod(quads,NULL); /* theta0 precedes , */ @@ -7842,11 +7869,11 @@ /* ------------------------------------------------------------------------- Allocations and Declarations -------------------------------------------------------------------------- */ -char *texsubexpr(), tag[512]="\000", filename[1024]="\000"; /* args */ +char *texsubexpr(), tag[1024]="\000", filename[1024]="\000"; /* args */ subraster *rasterize(), *inputsp=NULL; /* rasterized input image */ int status, rastreadfile(); /* read input file */ int format=0, npts=0; /* don't reformat (numerical) input */ -char subexpr[8192], /* concatanated lines from input file */ +char subexpr[MAXFILESZ+1] = "\000", /* concatanated lines from input file */ *mimeprep(), /* preprocess inputted data */ *dtoa(), *reformat=NULL; /* reformat numerical input */ /* ------------------------------------------------------------------------- @@ -7854,14 +7881,14 @@ -------------------------------------------------------------------------- */ /* --- parse for optional [tag] or [fmt] arg, bump expression past it --- */ if ( *(*expression) == '[' ) /* check for []-enclosed value */ - { char argfld[2048]; /* optional argument field */ + { char argfld[MAXTOKNSZ+1]; /* optional argument field */ *expression = texsubexpr(*expression,argfld,"[","]",0,0); if ( (reformat=strstr(argfld,"dtoa")) != NULL ) /* dtoa requested */ { format = 1; /* signal dtoa() format */ if ( (reformat=strchr(reformat,'=')) != NULL ) /* have dtoa= */ npts = (int)strtol(reformat+1,NULL,0); } /* so set npts */ if ( format == 0 ) /* reformat not requested */ - strcpy(tag,argfld); } /* so interpret arg as tag */ + strninit(tag,argfld,1020); } /* so interpret arg as tag */ /* --- parse for {filename} arg, and bump expression past it --- */ *expression = texsubexpr(*expression,filename,"{","}",0,0); /* --- check for alternate filename:tag --- */ @@ -7870,10 +7897,11 @@ { char *delim = strchr(filename,':'); /* look for : in filename:tag */ if ( delim != (char *)NULL ) /* found it */ { *delim = '\000'; /* null-terminate filename at : */ - strcpy(tag,delim+1); } } /* and stuff after : is tag */ + strninit(tag,delim+1,1020); } } /* and stuff after : is tag */ /* -------------------------------------------------------------------------- Read file and rasterize constructed subexpression -------------------------------------------------------------------------- */ +if ( 0 ) { /* Disabled to fix CVE-2009-2459 */ status = rastreadfile(filename,tag,subexpr); /* read file */ if ( *subexpr == '\000' ) goto end_of_job; /* quit if problem */ /* --- rasterize input subexpression --- */ @@ -7883,6 +7911,13 @@ if ( d != 0.0 ) /* conversion to double successful */ if ( (reformat=dtoa(d,npts)) != NULL ) /* reformat successful */ strcpy(subexpr,reformat); } /*replace subexpr with reformatted*/ + } + +/* Send an error message to the user */ +sprintf(subexpr, +"\\ \\text{[\\backslash input\\lbrace %.128s\\rbrace\\ not permitted]}\\ ", +(isempty(filename)?"???":filename)); + inputsp = rasterize(subexpr,size); /* rasterize subexpression */ /* --- return input image to caller --- */ end_of_job: @@ -7923,7 +7958,7 @@ Allocations and Declarations -------------------------------------------------------------------------- */ char *texsubexpr(), filename[1024]="\000", /* counter file */ - logfile[1024]="\000", tag[512]="\000"; /* log file and tag */ + logfile[1024]="\000", tag[1024]="\000"; /* log file and tag */ subraster *rasterize(), *countersp=NULL; /* rasterized counter image */ FILE *fp=NULL, *logfp=NULL; /* counter and log file pointers */ int rastreadfile(), rastwritefile(); /* to read and write counter file */ @@ -7981,6 +8016,13 @@ /* -------------------------------------------------------------------------- Read and parse file, increment and rewrite counter (with optional underscore) -------------------------------------------------------------------------- */ + +/* Disabled to fix CVE-2009-2459 */ +sprintf(text, +"\\ \\text{[\\backslash counter\\lbrace %.128s\\rbrace\\ not permitted]}\\ ", +(isempty(filename)?"???":filename)); +goto rasterize_counter; /* rasterize error message */ + if ( strlen(filename) > 1 ) /* make sure we got {filename} arg */ { /* --- read and interpret first (and only) line from counter file --- */ @@ -8042,6 +8084,7 @@ strcat(text,ordinal[ordindex]); /* then st,nd,rd, or th */ strcat(text,"}}"); } /* finish with }} */ /* --- rasterize it --- */ +rasterize_counter: countersp = rasterize(text,size); /* rasterize counter subexpression */ /* --- return counter image to caller --- */ end_of_job: