summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-02 12:01:39 -0800
committerAlan Coopersmith <alan.coopersmith@oracle.com>2013-05-09 18:59:52 -0700
commit236b603d235dc264d1c6250dca09c745458a9088 (patch)
treea80d778be29d154b3da18286c877a790a4506f82
parent076428918e6c35f66b9b55c3fa097ff06496d155 (diff)
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: Ilja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: Matthieu Herrb <matthieu.herrb@laas.fr>
-rw-r--r--src/Xrm.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/Xrm.c b/src/Xrm.c
index 3e29ab0f..2c0c324c 100644
--- a/src/Xrm.c
+++ b/src/Xrm.c
@@ -1088,13 +1088,15 @@ static void GetIncludeFile(
1088 XrmDatabase db, 1088 XrmDatabase db,
1089 _Xconst char *base, 1089 _Xconst char *base,
1090 _Xconst char *fname, 1090 _Xconst char *fname,
1091 int fnamelen); 1091 int fnamelen,
1092 int depth);
1092 1093
1093static void GetDatabase( 1094static void GetDatabase(
1094 XrmDatabase db, 1095 XrmDatabase db,
1095 _Xconst char *str, 1096 _Xconst char *str,
1096 _Xconst char *filename, 1097 _Xconst char *filename,
1097 Bool doall) 1098 Bool doall,
1099 int depth)
1098{ 1100{
1099 char *rhs; 1101 char *rhs;
1100 char *lhs, lhs_s[DEF_BUFF_SIZE]; 1102 char *lhs, lhs_s[DEF_BUFF_SIZE];
@@ -1204,7 +1206,8 @@ static void GetDatabase(
1204 } while (c != '"' && !is_EOL(bits)); 1206 } while (c != '"' && !is_EOL(bits));
1205 /* must have an ending " */ 1207 /* must have an ending " */
1206 if (c == '"') 1208 if (c == '"')
1207 GetIncludeFile(db, filename, fname, str - len - fname); 1209 GetIncludeFile(db, filename, fname, str - len - fname,
1210 depth);
1208 } 1211 }
1209 } 1212 }
1210 /* spin to next newline */ 1213 /* spin to next newline */
@@ -1545,7 +1548,7 @@ XrmPutLineResource(
1545{ 1548{
1546 if (!*pdb) *pdb = NewDatabase(); 1549 if (!*pdb) *pdb = NewDatabase();
1547 _XLockMutex(&(*pdb)->linfo); 1550 _XLockMutex(&(*pdb)->linfo);
1548 GetDatabase(*pdb, line, (char *)NULL, False); 1551 GetDatabase(*pdb, line, (char *)NULL, False, 0);
1549 _XUnlockMutex(&(*pdb)->linfo); 1552 _XUnlockMutex(&(*pdb)->linfo);
1550} 1553}
1551 1554
@@ -1557,7 +1560,7 @@ XrmGetStringDatabase(
1557 1560
1558 db = NewDatabase(); 1561 db = NewDatabase();
1559 _XLockMutex(&db->linfo); 1562 _XLockMutex(&db->linfo);
1560 GetDatabase(db, data, (char *)NULL, True); 1563 GetDatabase(db, data, (char *)NULL, True, 0);
1561 _XUnlockMutex(&db->linfo); 1564 _XUnlockMutex(&db->linfo);
1562 return db; 1565 return db;
1563} 1566}
@@ -1636,7 +1639,8 @@ GetIncludeFile(
1636 XrmDatabase db, 1639 XrmDatabase db,
1637 _Xconst char *base, 1640 _Xconst char *base,
1638 _Xconst char *fname, 1641 _Xconst char *fname,
1639 int fnamelen) 1642 int fnamelen,
1643 int depth)
1640{ 1644{
1641 int len; 1645 int len;
1642 char *str; 1646 char *str;
@@ -1644,6 +1648,8 @@ GetIncludeFile(
1644 1648
1645 if (fnamelen <= 0 || fnamelen >= BUFSIZ) 1649 if (fnamelen <= 0 || fnamelen >= BUFSIZ)
1646 return; 1650 return;
1651 if (depth >= MAXDBDEPTH)
1652 return;
1647 if (*fname != '/' && base && (str = strrchr(base, '/'))) { 1653 if (*fname != '/' && base && (str = strrchr(base, '/'))) {
1648 len = str - base + 1; 1654 len = str - base + 1;
1649 if (len + fnamelen >= BUFSIZ) 1655 if (len + fnamelen >= BUFSIZ)
@@ -1657,7 +1663,7 @@ GetIncludeFile(
1657 } 1663 }
1658 if (!(str = ReadInFile(realfname))) 1664 if (!(str = ReadInFile(realfname)))
1659 return; 1665 return;
1660 GetDatabase(db, str, realfname, True); 1666 GetDatabase(db, str, realfname, True, depth + 1);
1661 Xfree(str); 1667 Xfree(str);
1662} 1668}
1663 1669
@@ -1673,7 +1679,7 @@ XrmGetFileDatabase(
1673 1679
1674 db = NewDatabase(); 1680 db = NewDatabase();
1675 _XLockMutex(&db->linfo); 1681 _XLockMutex(&db->linfo);
1676 GetDatabase(db, str, filename, True); 1682 GetDatabase(db, str, filename, True, 0);
1677 _XUnlockMutex(&db->linfo); 1683 _XUnlockMutex(&db->linfo);
1678 Xfree(str); 1684 Xfree(str);
1679 return db; 1685 return db;
@@ -1697,7 +1703,7 @@ XrmCombineFileDatabase(
1697 } else 1703 } else
1698 db = NewDatabase(); 1704 db = NewDatabase();
1699 _XLockMutex(&db->linfo); 1705 _XLockMutex(&db->linfo);
1700 GetDatabase(db, str, filename, True); 1706 GetDatabase(db, str, filename, True, 0);
1701 _XUnlockMutex(&db->linfo); 1707 _XUnlockMutex(&db->linfo);
1702 Xfree(str); 1708 Xfree(str);
1703 if (!override) 1709 if (!override)