An SIGFPE is raised in function onGetPixels of SkRawCodec.cpp when the mediaserver try to parse a craft TIFF file with zero height dimensions.

  • CVE ID: CVE-2017-0497;
  • Android ID: A-33300701;
  • Severity: Moderate;
  • Updated Google devices: All;
  • Updated AOSP versions: 7.0, 7.1.1.

Description

http://androidxref.com/7.0.0_r1/xref/external/skia/src/codec/SkRawCodec.cpp#689

1
2
3
4
if (imageSize.h / width > maxDiffRatio || imageSize.h < width ||
imageSize.v / height > maxDiffRatio || imageSize.v < height) {
return SkCodec::kInvalidScale;
}

The width and height could be zero without a check for size information of the TIFF file.

Attack vector

You can click here to get the poc.

The easily way to trigger this vulnerability is as follows.

1
BitmapFactory.decodeFile("CVE-2017-0497.tiff");

Patch

Verify the size information.

https://android.googlesource.com/platform/external/skia/+/8888cbf8e74671d44e9ff92ec3847cd647b8cdfb%5E%21/#F1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index ab2c55d..eea551e 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -542,13 +542,15 @@
(header[0] == 0x4D && header[1] == 0x4D && header[2] == 0x00 && header[3] == 0x2A);
}
- void init(const int width, const int height, const dng_point& cfaPatternSize) {
+ bool init(const int width, const int height, const dng_point& cfaPatternSize) {
fImageInfo = SkImageInfo::Make(width, height, kN32_SkColorType, kOpaque_SkAlphaType);
// The DNG SDK scales only during demosaicing, so scaling is only possible when
// a mosaic info is available.
fIsScalable = cfaPatternSize.v != 0 && cfaPatternSize.h != 0;
fIsXtransImage = fIsScalable ? (cfaPatternSize.v == 6 && cfaPatternSize.h == 6) : false;
+
+ return width > 0 && height > 0;
}
bool initFromPiex() {
@@ -558,15 +560,9 @@
if (::piex::IsRaw(&piexStream)
&& ::piex::GetPreviewImageData(&piexStream, &imageData) == ::piex::Error::kOk)
{
- // Verify the size information, as it is only optional information for PIEX.
- if (imageData.full_width == 0 || imageData.full_height == 0) {
- return false;
- }
-
dng_point cfaPatternSize(imageData.cfa_pattern_dim[1], imageData.cfa_pattern_dim[0]);
- this->init(static_cast<int>(imageData.full_width),
- static_cast<int>(imageData.full_height), cfaPatternSize);
- return true;
+ return this->init(static_cast<int>(imageData.full_width),
+ static_cast<int>(imageData.full_height), cfaPatternSize);
}
return false;
}
@@ -594,10 +590,9 @@
if (fNegative->GetMosaicInfo() != nullptr) {
cfaPatternSize = fNegative->GetMosaicInfo()->fCFAPatternSize;
}
- this->init(static_cast<int>(fNegative->DefaultCropSizeH().As_real64()),
- static_cast<int>(fNegative->DefaultCropSizeV().As_real64()),
- cfaPatternSize);
- return true;
+ return this->init(static_cast<int>(fNegative->DefaultCropSizeH().As_real64()),
+ static_cast<int>(fNegative->DefaultCropSizeV().As_real64()),
+ cfaPatternSize);
} catch (...) {
return false;
}

Acknowledgement

This vulnerability was credited to Zinuo Han from Chengdu Security Response Center of Qihoo 360 Technology Co. Ltd.

Timeline

2016-12-02: ele7enxxh reported the vulnerability to Google;
2017-01-24: Google rated it as a Moderate vulnerability;
2017-01-31: Google assigned CVE-2017-0497 for this vulnerability;
2017-03-07: Google released the patch and disclosed the details of CVE-2017-0497 on Android Security Bulletin-March 2017.