CVE-2015-0823: Other (NVD-CWE-Other)
value: Multiple use-after-free vulnerabilities in OpenType Sanitiser, as used in Mozilla Firefox before 36.0, might allow remote attackers to trigger problematic Developer Console information or possibly have unspecified other impact by leveraging incorrect macro expansion, related to the ots::ots_gasp_parse function.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Published: 2015-02-25T11:59Z
Repository: https://github.com/khaledhosny/ots
Language: C++
Files changed: src/gasp.cc, src/gdef.cc, src/gpos.cc, src/gsub.cc, src/hdmx.cc, src/kern.cc, src/ltsh.cc, src/math.cc, src/vdmx.cc, src/vorg.cc
Commit date: 2014-11-15 04:29:36 +0200
Commit message: [ots] Fix (potential) use-after-free bugs

Make sure we don’t try to access the table after deleting it. Not all
the changed files are affected, but I changed them all for the sake of
consistency.

Diff: diff --git a/src/gasp.cc b/src/gasp.cc
index 91e19e4..1e2327f 100644
--- a/src/gasp.cc
+++ b/src/gasp.cc
@@ -9,14 +9,14 @@
 
 #define TABLE_NAME "gasp"
 
 #define DROP_THIS_TABLE(...) \
   do { \
-    delete file->gasp; \
-    file->gasp = 0; \
     OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \
     OTS_FAILURE_MSG("Table discarded"); \
+    delete file->gasp; \
+    file->gasp = 0; \
   } while (0)
 
 namespace ots {
 
 bool ots_gasp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/gdef.cc b/src/gdef.cc
index 523d384..4553d58 100644
--- a/src/gdef.cc
+++ b/src/gdef.cc
@@ -229,13 +229,13 @@ bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data,
 
 }  // namespace
 
 #define DROP_THIS_TABLE(msg_) \
   do { \
+    OTS_FAILURE_MSG(msg_ ", table discarded"); \
     file->gdef->data = 0; \
     file->gdef->length = 0; \
-    OTS_FAILURE_MSG(msg_ ", table discarded"); \
   } while (0)
 
 namespace ots {
 
 bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/gpos.cc b/src/gpos.cc
index 314cf29..a2b9687 100644
--- a/src/gpos.cc
+++ b/src/gpos.cc
@@ -675,13 +675,13 @@ bool ParseExtensionPositioning(const ots::OpenTypeFile *file,
 
 }  // namespace
 
 #define DROP_THIS_TABLE(msg_) \
   do { \
+    OTS_FAILURE_MSG(msg_ ", table discarded"); \
     file->gpos->data = 0; \
     file->gpos->length = 0; \
-    OTS_FAILURE_MSG(msg_ ", table discarded"); \
   } while (0)
 
 namespace ots {
 
 // As far as I checked, following fonts contain invalid GPOS table and
diff --git a/src/gsub.cc b/src/gsub.cc
index 4ff4214..af31144 100644
--- a/src/gsub.cc
+++ b/src/gsub.cc
@@ -528,13 +528,13 @@ bool ParseReverseChainingContextSingleSubstitution(
 
 }  // namespace
 
 #define DROP_THIS_TABLE(msg_) \
   do { \
+    OTS_FAILURE_MSG(msg_ ", table discarded"); \
     file->gsub->data = 0; \
     file->gsub->length = 0; \
-    OTS_FAILURE_MSG(msg_ ", table discarded"); \
   } while (0)
 
 namespace ots {
 
 // As far as I checked, following fonts contain invalid values in GSUB table.
diff --git a/src/hdmx.cc b/src/hdmx.cc
index 0e37724..098802b 100644
--- a/src/hdmx.cc
+++ b/src/hdmx.cc
@@ -11,14 +11,14 @@
 
 #define TABLE_NAME "hdmx"
 
 #define DROP_THIS_TABLE(...) \
   do { \
-    delete file->hdmx; \
-    file->hdmx = 0; \
     OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \
     OTS_FAILURE_MSG("Table discarded"); \
+    delete file->hdmx; \
+    file->hdmx = 0; \
   } while (0)
 
 namespace ots {
 
 bool ots_hdmx_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/kern.cc b/src/kern.cc
index a8c2a75..744c057 100644
--- a/src/kern.cc
+++ b/src/kern.cc
@@ -9,13 +9,13 @@
 
 #define TABLE_NAME "kern"
 
 #define DROP_THIS_TABLE(msg_) \
   do { \
+    OTS_FAILURE_MSG(msg_ ", table discarded"); \
     delete file->kern; \
     file->kern = 0; \
-    OTS_FAILURE_MSG(msg_ ", table discarded"); \
   } while (0)
 
 namespace ots {
 
 bool ots_kern_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/ltsh.cc b/src/ltsh.cc
index 9532b4b..418c159 100644
--- a/src/ltsh.cc
+++ b/src/ltsh.cc
@@ -11,14 +11,14 @@
 
 #define TABLE_NAME "LTSH"
 
 #define DROP_THIS_TABLE(...) \
   do { \
-    delete file->ltsh; \
-    file->ltsh = 0; \
     OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \
     OTS_FAILURE_MSG("Table discarded"); \
+    delete file->ltsh; \
+    file->ltsh = 0; \
   } while (0)
 
 namespace ots {
 
 bool ots_ltsh_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/math.cc b/src/math.cc
index 97aa313..9124a88 100644
--- a/src/math.cc
+++ b/src/math.cc
@@ -516,13 +516,13 @@ bool ParseMathVariantsTable(const ots::OpenTypeFile *file,
 
 }  // namespace
 
 #define DROP_THIS_TABLE(msg_) \
   do { \
+    OTS_FAILURE_MSG(msg_ ", table discarded"); \
     file->math->data = 0; \
     file->math->length = 0; \
-    OTS_FAILURE_MSG(msg_ ", table discarded"); \
   } while (0)
 
 namespace ots {
 
 bool ots_math_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/vdmx.cc b/src/vdmx.cc
index e737a8b..4853d63 100644
--- a/src/vdmx.cc
+++ b/src/vdmx.cc
@@ -9,14 +9,14 @@
 
 #define TABLE_NAME "VDMX"
 
 #define DROP_THIS_TABLE(...) \
   do { \
-    delete file->vdmx; \
-    file->vdmx = 0; \
     OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \
     OTS_FAILURE_MSG("Table discarded"); \
+    delete file->vdmx; \
+    file->vdmx = 0; \
   } while (0)
 
 namespace ots {
 
 bool ots_vdmx_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
diff --git a/src/vorg.cc b/src/vorg.cc
index d3ce72a..2662067 100644
--- a/src/vorg.cc
+++ b/src/vorg.cc
@@ -11,14 +11,14 @@
 
 #define TABLE_NAME "VORG"
 
 #define DROP_THIS_TABLE(...) \
   do { \
-    delete file->vorg; \
-    file->vorg = 0; \
     OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \
     OTS_FAILURE_MSG("Table discarded"); \
+    delete file->vorg; \
+    file->vorg = 0; \
   } while (0)
 
 namespace ots {
 
 bool ots_vorg_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {

Vulnerable code:     delete file->gasp; \
    file->gasp = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->hdmx; \
    file->hdmx = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->ltsh; \
    file->ltsh = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->vdmx; \
    file->vdmx = 0; \
    delete file->vorg; \
    file->vorg = 0; \
Fixed code:     delete file->gasp; \
    file->gasp = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->hdmx; \
    file->hdmx = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->ltsh; \
    file->ltsh = 0; \
    OTS_FAILURE_MSG(msg_ ", table discarded"); \
    delete file->vdmx; \
    file->vdmx = 0; \
    delete file->vorg; \
    file->vorg = 0; \