Menu

#1657 Viewer shows garbled pixels or crashes with ZRLE-encoded sessions (2.8.87)

open
nobody
7
1 day ago
1 day ago
No

I was looking through the viewer source and noticed that the ZRLE decoder
(viewer-core/ZrleDecoder.cpp) doesn't validate palette indices before using
them to look up colours.

In readPaletteRleTile(), the subencoding type byte controls how many palette
entries exist (type - 128, range 2-127). The colour index byte is also
server-controlled; after stripping the high bit it can be 0-127 - but
there's no check it's less than the palette size before the memcpy on
line 315. Sending a 2-entry palette with index 127 reads 500 bytes past
the allocation end and copies them into the framebuffer.

Same flaw in readPackedPaletteTile() line 264: type=5 gives paletteSize=5
but the 0x0F bitmask allows color 0-15.

Steps to reproduce (custom server):

  1. Send ZRLE FramebufferUpdate, subencoding=130 (paletteSize=2).
  2. 2 palette entries only.
  3. Colour run byte 0xFF (index=127 after high-bit strip).
  4. Connect TightVNC 2.8.87 viewer.
  5. Viewer shows garbage or crashes.

Expected: decoder throws/skips out-of-range indices.
Actual: reads past end of palette allocation.

Attached PoCs demonstrate both the heap infoleak and the crash.
Version: 2.8.87.

Discussion


Log in to post a comment.

MongoDB Logo MongoDB