CLD-385 Details
Other IDs this deficiency may be known by:
Basic Information:
Affected Package(s) |
cairo |
Deficiency Type |
SECURITY |
Date Created |
2018-05-09 21:09:32 |
Date Last Modified |
2018-05-10 11:46:26 |
Version Specific Information:
Cucumber 1.0 i686 | fixed in cairo-1.14.8-i686-4 |
Cucumber 1.0 x86_64 | fixed in cairo-1.14.8-x86_64-4 and cairo-lib_i686-1.14.8-lib_i686-4 |
Cucumber 1.1 i686 |
fixed in cairo-1.14.8-i686-4 |
Cucumber 1.1 x86_64 |
fixed in cairo-1.14.8-x86_64-4 and cairo-lib_i686-1.14.8-lib_i686-4 |
Details:
=================================== Overview ===================================
cairo-truetype-subset.c in cairo 1.15.6 and earlier allows remote attackers to
cause a denial of service (out-of-bounds read) because of mishandling of an
unexpected malloc(0) call.
================================ Initial Report ================================
From https://bugs.freedesktop.org/show_bug.cgi?id=101547:
The CVE-2017-9814 has been assigned to this vulnerability.
There is a read out of bounds bug at cairo-truetype-subset.c:1299:
1293 size = be16_to_cpu (map->length);
1294 map = malloc (size);
1295 if (unlikely (map == NULL))
1296 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1297
1298 status = backend->load_truetype_table (scaled_font,
1299 TT_TAG_cmap, table_offset,
1300 (unsigned char *) map,
1301 &size);
1302 if (unlikely (status))
1303 goto fail;
1304
1305 num_segments = be16_to_cpu (map->segCountX2)/2;
The bug happens because in some scenarios the variable size can have a value of
0 at line 1288. And malloc(0) is not returning NULL as some people could
expect: https://stackoverflow.com/questions/1073157/zero-size-malloc
malloc(0) returns the smallest chunk possible. So the line 1290 with the return
is not execute. And the execution continues with an invalid map.
Since the size is 0 the variable map is not initialized correctly at
load_trutype_table. So, later when the variable map is accessed previous values
from a freed chunk are used. This could allows an attacker to control the
variable map.
There is a check performed just after the bug:
1309 if (size < (8 + 4*num_segments)*sizeof(uint16_t))
1310 return CAIRO_INT_STATUS_UNSUPPORTED;
So it's likely the attacker can't control the variable num_segments, and he
can't trigger additional functionality to leverage this.
The solution could be to check for the size, or to use a malloc wrapper that
handle the size = 0 case and returns NULL.
This bug was found when using a poppler util, pdftocairo. A PoC is attached. To
reproduce the bug use:
pdftocairo -svg PoC.pdf
This vulnerability has been found by Offensive Research at Salesforce.com:
Alberto Garcia (@algillera), Francisco Oca (@francisco_oca) & Suleman Ali
(@Salbei_)
================================= Our Analysis =================================
----- Affected Products -----
It is reported that cairo up to and including 1.15.6 that have not been
speficially patched against this vulnerability are vulnerable. We have
confirmed that unpatched cairo 1.14.8 is vulnerable in our lab environment.
This includes cairo as orignally packaged with Cucumber Linux 1.0 and 1.1.
----- Scope and Impact of this Vulnerability -----
Could possibly allow for a denial of service (application crash). Note that we
have failed to produce a crash in our lab environment.
----- Testing if you are Affected -----
1. Download PoC.pdf from https://bugs.freedesktop.org/attachment.cgi?id=132557.
2. Run the command `valgrind pdftocairo -svg PoC.pdf`.
* Note: this will require you to install valgrind either from source or from
the ports tree.
If the output of valgrind contains 'Invalid read of size 2', then you are
vulnerable.
----- Fix for this Vulnerability -----
This vulnerability can be fixed by applying the patch from commit
https://cgit.freedesktop.org/cairo/commit/?id=199823938780c8e50099b627d3e9137acba7a263.
We had to modify this patch to get it to work on Cucumber Linux 1.x. The
modified patch can be found at
https://mirror.cucumberlinux.com/cucumber/cucumber-1.1/source/x-base/cairo/patches/00020_CVE-2017-9814_199823938780c8e50099b627d3e9137acba7a263.patch
This vulnerability has been fixed by adding an additional check to several
malloc()'s. Namely, malloc has been replaced with _cairo_malloc in severl
places, which checks and adiquately protects against a malloc(0) whereas the
former does not.
================================= Our Solution =================================
We have applied the patch from
https://mirror.cucumberlinux.com/cucumber/cucumber-1.1/source/x-base/cairo/patches/00020_CVE-2017-9814_199823938780c8e50099b627d3e9137acba7a263.patch
and rebuilt.