Commit 25172302 authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Ulrich Sibiller

integer overflows in TransFileName() [CVE-2013-1981 9/13]

When trying to process file paths the tokens %H, %L, & %S are expanded to $HOME, the standard compose file path & the xlocaledir path. If enough of these tokens are repeated and values like $HOME are set to very large values, the calculation of the total string size required to hold the expanded path can overflow, resulting in allocating a smaller string than the amount of data we'll write to it. Simply restrict all of these values, and the total path size to PATH_MAX, because really, that's all you should need for a filename path. Reported-by: 's avatarIlja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: 's avatarMatthieu Herrb <matthieu.herrb@laas.fr> Signed-off-by: 's avatarJulien Cristau <jcristau@debian.org> Backported-to-NX-by: 's avatarUlrich Sibiller <uli42@gmx.de>
parent 8468165a
...@@ -42,6 +42,7 @@ OR PERFORMANCE OF THIS SOFTWARE. ...@@ -42,6 +42,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
#include <sys/stat.h> #include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
#include "pathmax.h"
#define XLC_BUFSIZE 256 #define XLC_BUFSIZE 256
...@@ -305,9 +306,9 @@ static char* ...@@ -305,9 +306,9 @@ static char*
TransFileName(Xim im, char *name) TransFileName(Xim im, char *name)
{ {
char *home = NULL, *lcCompose = NULL; char *home = NULL, *lcCompose = NULL;
char dir[XLC_BUFSIZE]; char dir[XLC_BUFSIZE] = "";
char *i = name, *ret, *j; char *i = name, *ret = NULL, *j;
int l = 0; size_t l = 0;
while (*i) { while (*i) {
if (*i == '%') { if (*i == '%') {
...@@ -317,30 +318,51 @@ TransFileName(Xim im, char *name) ...@@ -317,30 +318,51 @@ TransFileName(Xim im, char *name)
l++; l++;
break; break;
case 'H': case 'H':
if (home == NULL)
home = getenv("HOME"); home = getenv("HOME");
if (home) if (home) {
l += strlen(home); size_t Hsize = strlen(home);
if (Hsize > PATH_MAX)
/* your home directory length is ridiculous */
goto end;
l += Hsize;
}
break; break;
case 'L': case 'L':
if (lcCompose == NULL) if (lcCompose == NULL)
lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE); lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE);
if (lcCompose) if (lcCompose) {
l += strlen(lcCompose); size_t Lsize = strlen(lcCompose);
if (Lsize > PATH_MAX)
/* your compose pathname length is ridiculous */
goto end;
l += Lsize;
}
break; break;
case 'S': case 'S':
if (dir[0] == '\0')
xlocaledir(dir, XLC_BUFSIZE); xlocaledir(dir, XLC_BUFSIZE);
l += strlen(dir); if (dir[0]) {
size_t Ssize = strlen(dir);
if (Ssize > PATH_MAX)
/* your locale directory path length is ridiculous */
goto end;
l += Ssize;
}
break; break;
} }
} else { } else {
l++; l++;
} }
i++; i++;
if (l > PATH_MAX)
/* your expanded path length is ridiculous */
goto end;
} }
j = ret = Xmalloc(l+1); j = ret = Xmalloc(l+1);
if (ret == NULL) if (ret == NULL)
return ret; goto end;
i = name; i = name;
while (*i) { while (*i) {
if (*i == '%') { if (*i == '%') {
...@@ -372,6 +394,7 @@ TransFileName(Xim im, char *name) ...@@ -372,6 +394,7 @@ TransFileName(Xim im, char *name)
} }
} }
*j = '\0'; *j = '\0';
end:
Xfree(lcCompose); Xfree(lcCompose);
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment