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(
XrmDatabase db,
_Xconst char *base,
_Xconst char *fname,
int fnamelen);
int fnamelen,
int depth);
static void GetDatabase(
XrmDatabase db,
_Xconst register char *str,
_Xconst char *filename,
Bool doall)
Bool doall,
int depth)
{
char *rhs;
char *lhs, lhs_s[DEF_BUFF_SIZE];
......@@ -1203,7 +1205,8 @@ static void GetDatabase(
} while (c != '"' && !is_EOL(bits));
/* must have an ending " */
if (c == '"')
GetIncludeFile(db, filename, fname, str - len - fname);
GetIncludeFile(db, filename, fname, str - len - fname,
depth);
}
}
/* spin to next newline */
......@@ -1544,7 +1547,7 @@ XrmPutLineResource(
{
if (!*pdb) *pdb = NewDatabase();
_XLockMutex(&(*pdb)->linfo);
GetDatabase(*pdb, line, (char *)NULL, False);
GetDatabase(*pdb, line, (char *)NULL, False, 0);
_XUnlockMutex(&(*pdb)->linfo);
}
......@@ -1556,7 +1559,7 @@ XrmGetStringDatabase(
db = NewDatabase();
_XLockMutex(&db->linfo);
GetDatabase(db, data, (char *)NULL, True);
GetDatabase(db, data, (char *)NULL, True, 0);
_XUnlockMutex(&db->linfo);
return db;
}
......@@ -1633,7 +1636,8 @@ GetIncludeFile(
XrmDatabase db,
_Xconst char *base,
_Xconst char *fname,
int fnamelen)
int fnamelen,
int depth)
{
int len;
char *str;
......@@ -1641,6 +1645,8 @@ GetIncludeFile(
if (fnamelen <= 0 || fnamelen >= BUFSIZ)
return;
if (depth >= MAXDBDEPTH)
return;
if (*fname != '/' && base && (str = strrchr(base, '/'))) {
len = str - base + 1;
if (len + fnamelen >= BUFSIZ)
......@@ -1654,7 +1660,7 @@ GetIncludeFile(
}
if (!(str = ReadInFile(realfname)))
return;
GetDatabase(db, str, realfname, True);
GetDatabase(db, str, realfname, True, depth + 1);
Xfree(str);
}
......@@ -1670,7 +1676,7 @@ XrmGetFileDatabase(
db = NewDatabase();
_XLockMutex(&db->linfo);
GetDatabase(db, str, filename, True);
GetDatabase(db, str, filename, True, 0);
_XUnlockMutex(&db->linfo);
Xfree(str);
return db;
......@@ -1694,7 +1700,7 @@ XrmCombineFileDatabase(
} else
db = NewDatabase();
_XLockMutex(&db->linfo);
GetDatabase(db, str, filename, True);
GetDatabase(db, str, filename, True, 0);
_XUnlockMutex(&db->linfo);
Xfree(str);
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