<html>
    <head>
      <base href="https://bugs.freedesktop.org/">
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Heap buffer overflow at cairo-truetype-subset.c"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=101547#c1">Comment # 1</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Heap buffer overflow at cairo-truetype-subset.c"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=101547">bug 101547</a>
              from <span class="vcard"><a class="email" href="mailto:foca@salesforce.com" title="foca@salesforce.com <foca@salesforce.com>"> <span class="fn">foca@salesforce.com</span></a>
</span></b>
        <pre>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: <a href="https://stackoverflow.com/questions/1073157/zero-size-malloc">https://stackoverflow.com/questions/1073157/zero-size-malloc</a>

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_)</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>