Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates-src > by-pkgid > e292cda8ad33284786d7f1384ee2e82d > files > 4

ming-0.4.5-14.1.mga6.src.rpm

From 7fed314748be817c7ded84854acb649786625cb6 Mon Sep 17 00:00:00 2001
From: Hugo Lefeuvre <hle@debian.org>
Date: Sun, 1 Oct 2017 17:09:45 +0200
Subject: [PATCH 11/29] Fix various overflows in util/ (CVE-2017-11704)

* Add a check in decompileIF to avoid overflows.

    Avoid processing block when sact->numActions is 0, as
    sact->numActions - 1 may be used as index when accessing
    sact->Actions array.

* Fix overflow in readUInt32.

    o Fix declaration of readUInt32 and readSInt32 in util/read.h:
      return types should be unsigned long and long.
    o readUInt32: Avoid calling all readUInt8(f) in one line, order of
      evaluation is not guaranteed in the C standard.
    o readUInt32: Cast result of readUInt8(f) before << 24 to avoid
      overflow.

* Fix overflow in readMovie.

    length has int type but according to the specification it should be able
    to store unsigned 32bit numbers. Instead of changing the type of
    length, which would be a major refactoring, we verify that the value
    returned by readUInt32 is smaller than INT_MAX and update length if
    it's the case. Otherwise we print a warning and ignore the block.

This commit fixes CVE-2017-11704.
---
 util/decompile.c |  5 +++++
 util/main.c      | 11 ++++++++++-
 util/read.c      |  6 +++++-
 util/read.h      |  4 ++--
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/util/decompile.c b/util/decompile.c
index c844fa49..60785e29 100644
--- a/util/decompile.c
+++ b/util/decompile.c
@@ -2197,6 +2197,11 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
 	int j,i=0;
 	struct strbufinfo origbuf;
 	OUT_BEGIN2(SWF_ACTIONIF);
+
+        if (sact->numActions < 1) {
+            return 0;
+        }
+
 	/*
 	* IF is used in various way to implement different types
 	* of loops. We try to detect these different types of loops
diff --git a/util/main.c b/util/main.c
index cb277804..923d4c75 100644
--- a/util/main.c
+++ b/util/main.c
@@ -253,7 +253,16 @@ static void readMovie(FILE *f)
 		{
 			if(filelen_check_fails(4))
 				break;
-			length = readUInt32 (f);
+			unsigned long real_length = readUInt32 (f);
+
+                        if (real_length > INT_MAX) {
+		            SWF_warn(" Could not process long block with length %lu:"
+                                     " blocks with length > %d not supported on this system\n",
+                                     real_length, INT_MAX);
+                            continue;
+                        } else {
+                            length = (int) real_length;
+                        }
 		}
 		
 		//      printf ("Found Block: %s (%i), %i bytes\n", blockName (type), type, length);
diff --git a/util/read.c b/util/read.c
index 852cb657..1cd0a0f8 100644
--- a/util/read.c
+++ b/util/read.c
@@ -163,7 +163,11 @@ long readSInt32(FILE *f)
 
 unsigned long readUInt32(FILE *f)
 {
-  return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
+  int part1 = readUInt8(f);
+  int part2 = readUInt8(f) << 8;
+  int part3 = readUInt8(f) << 16;
+  unsigned long part4 = ((unsigned long)readUInt8(f)) << 24;
+  return part1 + part2 + part3 + part4;
 }
 
 double readDouble(FILE *f)
diff --git a/util/read.h b/util/read.h
index 1cb6c5e5..e8d485fd 100644
--- a/util/read.h
+++ b/util/read.h
@@ -15,8 +15,8 @@ int readUInt8(FILE *f);
 int readSInt8(FILE *f);
 int readUInt16(FILE *f);
 int readSInt16(FILE *f);
-int readUInt32(FILE *f);
-int readSInt32(FILE *f);
+unsigned long readUInt32(FILE *f);
+long readSInt32(FILE *f);
 unsigned long readEncUInt32(FILE *f);
 unsigned long readEncUInt30(FILE *f);
 long readEncSInt32(FILE *f);
-- 
2.14.3