40 lines
1.5 KiB
Diff
40 lines
1.5 KiB
Diff
|
From 1e07c98dfcbd8ac10ee02088f08235f5e1700148 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <dan.cermak@cgc-instruments.com>
|
||
|
Date: Wed, 27 Sep 2017 23:38:49 +0200
|
||
|
Subject: Fixed wrong brackets: size*count + pad can overflow before the cast
|
||
|
|
||
|
=> Should fix #76 (most of the work has been done by Robin Mills in
|
||
|
6e3855aed7ba8bb4731fc4087ca7f9078b2f3d97)
|
||
|
|
||
|
The problem with #76 is the contents of the 26th IFD, with the
|
||
|
following contents:
|
||
|
tag: 0x8649
|
||
|
type: 0x1
|
||
|
count: 0xffff ffff
|
||
|
offset: 0x4974
|
||
|
|
||
|
The issue is the size of count (uint32_t), as adding anything to it
|
||
|
causes an overflow. Especially the expression:
|
||
|
(size*count + pad+20)
|
||
|
results in an overflow and gives 20 as a result instead of
|
||
|
0x100000014, thus the condition in the if in the next line is false
|
||
|
and the program continues to run (until it crashes at io.read).
|
||
|
|
||
|
To properly account for the overflow, the brackets have to be removed,
|
||
|
as then the result is saved in the correctly sized type and not cast
|
||
|
after being calculated in the smaller type.
|
||
|
|
||
|
diff --git a/src/image.cpp b/src/image.cpp
|
||
|
index ec5b873e..199671b9 100644
|
||
|
--- a/src/image.cpp
|
||
|
+++ b/src/image.cpp
|
||
|
@@ -401,7 +401,7 @@ namespace Exiv2 {
|
||
|
// if ( offset > io.size() ) offset = 0; // Denial of service?
|
||
|
|
||
|
// #55 memory allocation crash test/data/POC8
|
||
|
- long long allocate = (long long) (size*count + pad+20);
|
||
|
+ long long allocate = (long long) size*count + pad+20;
|
||
|
if ( allocate > (long long) io.size() ) {
|
||
|
throw Error(57);
|
||
|
}
|