[gcab/wip/hughsie/future: 18/18] Fix a large memory leak when parsing LZX cab files



commit d56d86dbc4170a3f0b582160ca2b50c5286c0761
Author: Richard Hughes <richard hughsie com>
Date:   Wed Dec 13 22:56:17 2017 +0000

    Fix a large memory leak when parsing LZX cab files

 libgcab/cabinet.c       |    7 +++++++
 libgcab/decomp.c        |    5 +++++
 libgcab/decomp.h        |    2 ++
 tests/CVE-2014-9556.cab |  Bin 0 -> 268 bytes
 tests/CVE-2014-9732.cab |  Bin 0 -> 1846 bytes
 tests/CVE-2015-4470.cab |  Bin 0 -> 212 bytes
 tests/CVE-2015-4471.cab |  Bin 0 -> 152 bytes
 7 files changed, 14 insertions(+), 0 deletions(-)
---
diff --git a/libgcab/cabinet.c b/libgcab/cabinet.c
index 90a296e..eca63b0 100644
--- a/libgcab/cabinet.c
+++ b/libgcab/cabinet.c
@@ -502,6 +502,11 @@ cdata_finish (cdata_t *cd, GError **error)
     z_stream *z = &cd->z;
     int zret;
 
+    if (cd->decomp.comptype == GCAB_COMPRESSION_LZX) {
+        LZXfdi_clear (&cd->decomp);
+        return;
+    }
+
     if (!z->opaque)
         return;
 
@@ -577,6 +582,7 @@ cdata_read (cdata_t *cd, guint8 res_data, gint comptype,
             cd->decomp.fdi = &cd->fdi;
             cd->decomp.inbuf = cd->in;
             cd->decomp.outbuf = cd->out;
+            cd->decomp.comptype = compression;
 
             ret = LZXfdi_init((comptype >> 8) & 0x1f, &cd->decomp);
             if (ret < 0)
@@ -592,6 +598,7 @@ cdata_read (cdata_t *cd, guint8 res_data, gint comptype,
         if (cd->in[0] != 'C' || cd->in[1] != 'K')
             goto end;
 
+        cd->decomp.comptype = compression;
         z_stream *z = &cd->z;
 
         z->avail_in = cd->ncbytes - 2;
diff --git a/libgcab/decomp.c b/libgcab/decomp.c
index ad59ad8..64d97f8 100644
--- a/libgcab/decomp.c
+++ b/libgcab/decomp.c
@@ -836,6 +836,11 @@ int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
   return DECR_OK;
 }
 
+void LZXfdi_clear(fdi_decomp_state *decomp_state) {
+  cab_UBYTE *window = LZX(window);
+  CAB(fdi)->free(window);
+}
+
 /*******************************************************
  * LZXfdi_decomp(internal)
  */
diff --git a/libgcab/decomp.h b/libgcab/decomp.h
index 78b1b76..041d60e 100644
--- a/libgcab/decomp.h
+++ b/libgcab/decomp.h
@@ -241,10 +241,12 @@ typedef struct fdi_cds_fwd {
         struct ZIPstate zip;
         struct LZXstate lzx;
     } methods;
+    int comptype;
 } fdi_decomp_state;
 
 int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state);
 int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state);
 int LZXfdi_init(int window, fdi_decomp_state *decomp_state);
+void LZXfdi_clear(fdi_decomp_state *decomp_state);
 
 #endif
diff --git a/tests/CVE-2014-9556.cab b/tests/CVE-2014-9556.cab
new file mode 100644
index 0000000..94e0fcd
Binary files /dev/null and b/tests/CVE-2014-9556.cab differ
diff --git a/tests/CVE-2014-9732.cab b/tests/CVE-2014-9732.cab
new file mode 100644
index 0000000..1f42eea
Binary files /dev/null and b/tests/CVE-2014-9732.cab differ
diff --git a/tests/CVE-2015-4470.cab b/tests/CVE-2015-4470.cab
new file mode 100644
index 0000000..5e2cb32
Binary files /dev/null and b/tests/CVE-2015-4470.cab differ
diff --git a/tests/CVE-2015-4471.cab b/tests/CVE-2015-4471.cab
new file mode 100644
index 0000000..bd6f25b
Binary files /dev/null and b/tests/CVE-2015-4471.cab differ


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]