CVE-2018-3835
An exploitable out of bounds write vulnerability exists in version 2.2 of the Per Face Texture mapping application known as PTEX. The vulnerability is present in the reading of a file without proper parameter checking. The value read in, is not verified to be valid and its use can lead to a buffer overflow, potentially resulting in code execution.
Walt Disney Animation Studios PTEX 2.2
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-121: Stack-based Buffer Overflow
PTEX is a texture mapping system developed by Walt Disney Animation Studios for production-quality rendering. PTEX is able to store hundreds of thousands of texture mappings in a single file. This library is used in many applications including Pixar’s RenderMan, giving it a large user base thus making it a valuable target.
The vulnerability arises when the value, faceinfosize
, is read in from the file header and used without verification.
bool PtexReader::open(const char* pathArg, Ptex::String& error)
{
...
memset(&_header, 0, sizeof(_header));
readBlock(&_header, HeaderSize); [0]
...
// compute offsets of various blocks
FilePos pos = HeaderSize + _header.extheadersize;
_faceinfopos = pos; pos += _header.faceinfosize; [1]
...
// read basic file info
readFaceInfo(); [2]
At location 0, the header is being read into the structure. Then, at 1, the position of the face information is calculated and the function readFaceInfo()
is called, at 2.
void PtexReader::readFaceInfo()
{
...
readZipBlock(&_faceinfo[0], _header.faceinfosize, (int)(sizeof(FaceInfo) * nfaces)); [3]
At 3, the faceinfosize
value is used directly from the header and has not been verified for validity. Looking at the readZipBlock
function the vulnerability becomes apparent.
bool PtexReader::readZipBlock(void* data, int zipsize, int unzipsize) [4]
{
...
while (1) {
int size = (zipsize < BlockSize) ? zipsize : BlockSize; [5]
zipsize -= size;
if (!readBlock(buff, size)) break; [6]
The value zipsize
is of the type integer, 4, thus allowing it to potentially be a negative number. If this value is negative then it will always pass the check at 5. It is then converted to a large positive number implicitly when used for reading. This allows attacker controlled data to be read in beyond the bounds of the buffer leading to a buffer overflow and an exploitable condition.
There is a patch file included to check to ensure the zipsize
is greater than 0 before processing the vulnerable block.
Crashed thread log =
: Dispatch queue: com.apple.main-thread
* thread #1: tid = 0x12c2345, 0x00007fff9ed74fbf libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 287
* frame #0: 0x00007fff9ed74fbf libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 287
frame #1: 0x00007fff9ebd650e libsystem_c.dylib`__fread + 375
frame #2: 0x00007fff9ebd6380 libsystem_c.dylib`fread + 48
frame #3: 0x0000000100011ed4 ptxinfo-debug`Ptex::v2_2::PtexReader::DefaultInputHandler::read
frame #4: 0x0000000100009cbc ptxinfo-debug`Ptex::v2_2::PtexReader::readBlocksize
frame #5: 0x000000010000b4fe ptxinfo-debug`Ptex::v2_2::PtexReader::readZipBlock
exception=EXC_BAD_ACCESS:signal=11:is_exploitable= yes:instruction_disassembly=vmovaps %ymm2,
0x20(%rdi):instruction_address=0x00000007fff9ed74fbf:access_type=write:access_address=0x7fff5fbfffe0:
2018-01-22 - Vendor Disclosure
2018-01-26 - Public Release
Discovered by Tyler Bohan of Cisco Talos .