Bug 8006

Summary: CID-keyed Fonts 'scan_cidfont()' Integer Overflow Vulnerability
Product: xorg Reporter: Alan Coopersmith <alan.coopersmith>
Component: Lib/XfontAssignee: X.Org Security <xorg_security>
Status: RESOLVED DUPLICATE QA Contact:
Severity: blocker    
Priority: highest CC: ajax, xorg_security
Version: git   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Alan Coopersmith 2006-08-25 11:28:27 UTC
Per iDefense [IDEF1691]:

The vulnerability specifically exists in the handling of 'CMap' and 'CIDFont' 
font data. When parsing this information no checks are made that the count of 
items for the 'begincodespacerange', 'cidrange' and 'notdefrange' sections. The 
following section of code shows where the vulnerability is:

=== X.Org/xc/lib/font/Type1/scanfont.c ===

     1621  int
     1622  scan_cidfont(cidfont *CIDFontP, cmapres *CMapP)
     1623  {
      ...
     1704    if (!(fileP1 = fopen(cmapfile,filetype)))
     1705      return(SCAN_FILE_OPEN_ERROR);
     1706    
     1707    objFormatFile(inputP,fileP1);
      ...
     1716    do {
     1717      /* Scan the next token */
     1718      scan_token(inputP);
     1719      if (tokenType == TOKEN_INTEGER)
[1]  1720        rangecnt = tokenValue.integer;
      ...
     1725      switch (tokenType) {
      ...
     1742        case TOKEN_NAME:
     1743          if (0 == strncmp(tokenStartP,"begincodespacerange",19)) {
      ...
     1752            spacerangeP->spacecode =
[2]  1753              (spacerangecode *)vm_alloc(rangecnt*sizeof(spacerangecode));
     1754            if (!spacerangeP->spacecode) {
     1755              rc = SCAN_OUT_OF_MEMORY;
     1756              break;
     1757            }
[3]  1758            for (i = 0; i < rangecnt; i++) {
     1759              scan_token(inputP);
[4]  1760              if (tokenType != TOKEN_HEX_STRING) {
     1761                rc = SCAN_ERROR;
     1762                break;
     1763              }
      ...

At [1] the count of array items 'rangecnt' is loaded. This can have any integer 
value, including negative numbers. Then, at [2], the memory for the array data 
is allocated. If 'rangecnt' is chosen such that when it is multiplied by the 
size of the structure it is too big to completely fit in an integer, less memory 
than is requested will be allocated. The program then attempts [3] to read in 
'rangecnt' elements, but will stop reading values in if there is an error in the 
input. This error checking means a controlled amount of data can be used to 
overwrite the heap.

In addition to a 'standard' integer overflow, the implementation of 'vm_alloc()' 
makes it possible to overwrite memory before the allocated region.

=== X.Org/xc/lib/font/Type1/util.c ===

       98  char *
       99  vm_alloc(int bytes)
      100  {
      101    char *answer;
      102
      103    /* Round to next word multiple */
      104    bytes = (bytes + 7) & ~7;
      105
      106    /* Allocate the space, if it is available */
[1]   107    if (bytes <= vm_free) {
[2]   108      answer = vm_next;
[3]   109      vm_free -= bytes;
[4]   110      vm_next += bytes;
      111    }
      112    else
      113      answer = NULL;
      114    
      115    return(answer);
      116  }

If this function is called with a negative value for 'bytes', the check at [1] 
passes, the response is set to the current end of the allocated pool at [2], the 
amount of free space available is increased at [3] and the pointer to use next 
time is moved backwards at [4] into already used memory.
Comment 1 Alan Coopersmith 2006-08-25 13:56:59 UTC
Looks like this code came in the SGI CID support donated to XFree86 in 1999,
during the 3.9 development releases, so would be present in XFree86 4.0 & later
and X11R6.7 & later.
Comment 2 Alan Coopersmith 2006-08-28 14:17:51 UTC

*** This bug has been marked as a duplicate of 8000 ***
Comment 3 Matthieu Herrb 2006-08-28 14:19:44 UTC
Heh

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.