Talos Vulnerability Report

TALOS-2018-0523

Pixar Renderman IT Display Service 0x67 Command Denial of Service Vulnerability

June 14, 2018
CVE Number

CVE-2018-3840

Summary

A denial-of-service vulnerability exists in the Pixar Renderman IT Display Service 21.6. The vulnerability is present in the parsing of a network packet without proper validation of the packet. The data read by the application is not validated, and its use can lead to a null pointer dereference. The IT application is opened by a user and then listens for a connection on port 4001. An attacker can deliver an attack once the application has been opened.

Tested Versions

Renderman 21.6

Product URLs

https://renderman.pixar.com

CVSSv3 Score

5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

CWE

CWE-476: Null Pointer Dereference

Details

Renderman is a rendering application used in animation and film production. It is widely used for advanced rendering and shading in many large-scale environments. The application takes a custom file format known as a RIB, parses it, and then passes it along to one of various servers. An application included with Renderman is called the “IT Display Service”. This application accepts connections and receives a packet containing information about where to find the image for rendering. The application listens on port 4001 for connections from any host. An example of the communications is below.

00000000: 67dd dd                                  h..

The first byte is parsed in a command loop and functionality is called depending on the value. The vulnerability arises due to no validation after a direct socket read in the 0x67 command. The relevant code is shown below.

movsxd  rdx, dword ptr [r15+0B0h]   
mov     rdi, [r15+0A0h] ; this
mov     rsi, [r15+0C0h] ; char *
call    QIODevice::read(char *,long long)  [1]
sub     [r15+0B0h], eax                    [2]
jnz     loc_100096BC8

mov     rbx, [r15+0B8h]
lea     rdi, [rsp+518h+var_C8]
mov     dword ptr [rdi-24h], 0
lea     rsi, [rsp+518h+var_65]
mov     dword ptr [rsi-3Bh], 1
movzx   ecx, byte ptr [rbx]                [3]

At [1], a socket read takes place reading in controlled data. Looking at the documentation, we see that this function returns the number of bytes read or zero when there is no more data for reading. There is no check to verify any data has been read, [2]. This value is then dereferenced, [3], causing a null pointer dereference and a denial of service.

Crash Information

Crashed thread log =
: Dispatch queue: com.apple.main-thread
* thread #1: tid = 0x3067136, 0x00000001000968ce it`___lldb_unnamed_symbol1069$$it + 2078, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00000001000968ce it`___lldb_unnamed_symbol1069$$it + 2078
    frame #1: 0x0000000104e9409e libQtCore.dylib`QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 1566
    frame #2: 0x0000000103e24f11 libQtNetwork.dylib`QAbstractSocketPrivate::canReadNotification() + 657
    frame #3: 0x0000000103e2fdc9 libQtNetwork.dylib`QReadNotifier::event(QEvent*) + 41
    frame #4: 0x00000001040e05ed libQtGui.dylib`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 189
    frame #5: 0x00000001040e6c64 libQtGui.dylib`QApplication::notify(QObject*, QEvent*) + 1060

Timeline

2018-02-06 - Initial Vendor Contact
2018-02-06 - Vendor acknowledged (reports issued)
2018-04-06 - 60 day follow up with vendor
2018-06-14 - Public Release

Credit

Discovered by Tyler Bohan of Cisco Talos.