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.
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.
*** This bug has been marked as a duplicate of 8000 ***
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.