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

Unbounded recursion in GetDatabase() when parsing include files [CVE-2013-2004 1/2]

GetIncludeFile() can call GetDatabase() which can call GetIncludeFile() which can call GetDatabase() which can call GetIncludeFile() .... eventually causing recursive stack overflow and crash. Easily reproduced with a resource file that #includes itself. Limit is set to a include depth of 100 files, which should be enough for all known use cases, but could be adjusted later if necessary. 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 dbc11719
...@@ -1087,13 +1087,15 @@ static void GetIncludeFile( ...@@ -1087,13 +1087,15 @@ static void GetIncludeFile(
XrmDatabase db, XrmDatabase db,
_Xconst char *base, _Xconst char *base,
_Xconst char *fname, _Xconst char *fname,
int fnamelen); int fnamelen,
int depth);
static void GetDatabase( static void GetDatabase(
XrmDatabase db, XrmDatabase db,
_Xconst register char *str, _Xconst register char *str,
_Xconst char *filename, _Xconst char *filename,
Bool doall) Bool doall,
int depth)
{ {
char *rhs; char *rhs;
char *lhs, lhs_s[DEF_BUFF_SIZE]; char *lhs, lhs_s[DEF_BUFF_SIZE];
...@@ -1203,7 +1205,8 @@ static void GetDatabase( ...@@ -1203,7 +1205,8 @@ static void GetDatabase(
} while (c != '"' && !is_EOL(bits)); } while (c != '"' && !is_EOL(bits));
/* must have an ending " */ /* must have an ending " */
if (c == '"') if (c == '"')
GetIncludeFile(db, filename, fname, str - len - fname); GetIncludeFile(db, filename, fname, str - len - fname,
depth);
} }
} }
/* spin to next newline */ /* spin to next newline */
...@@ -1544,7 +1547,7 @@ XrmPutLineResource( ...@@ -1544,7 +1547,7 @@ XrmPutLineResource(
{ {
if (!*pdb) *pdb = NewDatabase(); if (!*pdb) *pdb = NewDatabase();
_XLockMutex(&(*pdb)->linfo); _XLockMutex(&(*pdb)->linfo);
GetDatabase(*pdb, line, (char *)NULL, False); GetDatabase(*pdb, line, (char *)NULL, False, 0);
_XUnlockMutex(&(*pdb)->linfo); _XUnlockMutex(&(*pdb)->linfo);
} }
...@@ -1556,7 +1559,7 @@ XrmGetStringDatabase( ...@@ -1556,7 +1559,7 @@ XrmGetStringDatabase(
db = NewDatabase(); db = NewDatabase();
_XLockMutex(&db->linfo); _XLockMutex(&db->linfo);
GetDatabase(db, data, (char *)NULL, True); GetDatabase(db, data, (char *)NULL, True, 0);
_XUnlockMutex(&db->linfo); _XUnlockMutex(&db->linfo);
return db; return db;
} }
...@@ -1633,7 +1636,8 @@ GetIncludeFile( ...@@ -1633,7 +1636,8 @@ GetIncludeFile(
XrmDatabase db, XrmDatabase db,
_Xconst char *base, _Xconst char *base,
_Xconst char *fname, _Xconst char *fname,
int fnamelen) int fnamelen,
int depth)
{ {
int len; int len;
char *str; char *str;
...@@ -1641,6 +1645,8 @@ GetIncludeFile( ...@@ -1641,6 +1645,8 @@ GetIncludeFile(
if (fnamelen <= 0 || fnamelen >= BUFSIZ) if (fnamelen <= 0 || fnamelen >= BUFSIZ)
return; return;
if (depth >= MAXDBDEPTH)
return;
if (*fname != '/' && base && (str = strrchr(base, '/'))) { if (*fname != '/' && base && (str = strrchr(base, '/'))) {
len = str - base + 1; len = str - base + 1;
if (len + fnamelen >= BUFSIZ) if (len + fnamelen >= BUFSIZ)
...@@ -1654,7 +1660,7 @@ GetIncludeFile( ...@@ -1654,7 +1660,7 @@ GetIncludeFile(
} }
if (!(str = ReadInFile(realfname))) if (!(str = ReadInFile(realfname)))
return; return;
GetDatabase(db, str, realfname, True); GetDatabase(db, str, realfname, True, depth + 1);
Xfree(str); Xfree(str);
} }
...@@ -1670,7 +1676,7 @@ XrmGetFileDatabase( ...@@ -1670,7 +1676,7 @@ XrmGetFileDatabase(
db = NewDatabase(); db = NewDatabase();
_XLockMutex(&db->linfo); _XLockMutex(&db->linfo);
GetDatabase(db, str, filename, True); GetDatabase(db, str, filename, True, 0);
_XUnlockMutex(&db->linfo); _XUnlockMutex(&db->linfo);
Xfree(str); Xfree(str);
return db; return db;
...@@ -1694,7 +1700,7 @@ XrmCombineFileDatabase( ...@@ -1694,7 +1700,7 @@ XrmCombineFileDatabase(
} else } else
db = NewDatabase(); db = NewDatabase();
_XLockMutex(&db->linfo); _XLockMutex(&db->linfo);
GetDatabase(db, str, filename, True); GetDatabase(db, str, filename, True, 0);
_XUnlockMutex(&db->linfo); _XUnlockMutex(&db->linfo);
Xfree(str); Xfree(str);
if (!override) if (!override)
......
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