Package: mimetex
Version: 1.50-1
Severity: normal
Tags: patch
User: [email protected]
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: