GUACAMOLE-2262: Heap-allocate clipboard buffers to prevent stack overflow.#659
GUACAMOLE-2262: Heap-allocate clipboard buffers to prevent stack overflow.#659escra wants to merge 1 commit into
Conversation
…flow. The clipboard receive and send buffers in cliprdr.c were allocated on the stack using GUAC_COMMON_CLIPBOARD_MAX_LENGTH. Since configurable clipboard limits (GUACAMOLE-2002) raised this to 50 MiB while the default thread stack is only 8 MiB, large clipboard operations cause a stack overflow (SIGSEGV) that silently kills the connection. This change heap-allocates both buffers using guac_mem_alloc() and frees them on all exit paths.
|
@mike-jumper Any drawback that you can think of to allocating clipboard buffers based on the (dynamic) output buffer size rather than the (static) maximum length? |
eugen-keeper
left a comment
There was a problem hiding this comment.
@escra
Thank you for the fix.
Anyway, wouldn't it be better here to have something like int output_buf_size = clipboard->clipboard->available * 2?
If format_data_request->requestedFormatId == CF_UNICODETEXT, then one byte character may produce two byte UTF-16.
|
Good catch. You're right, Worst case with CRLF normalization enabled is 4x (a single I'll update to use |
|
FYI I made a VNC clipboard change from stack to heap based allocation in a PR (#669). I came across a downstream merge conflict which has lead me to this thread. I had a thought, re: Clipboard size: the UI (and the comment for GUAC_COMMON_CLIPBOARD_MAX_LENGTH) does specify the size in bytes, not # of characters. Also, worst case UTF-8 (and UTF-16) can be as much as 4 bytes. e.g. emojis. With a maximum of 50MB clipboard size, *4 is getting pretty big. Good news, though, is that for such large allocations RAM is only mapped for the address ranges actually accessed. |
Summary
The clipboard receive and send buffers in
cliprdr.cwere allocated on thestack using
GUAC_COMMON_CLIPBOARD_MAX_LENGTH. Since configurable clipboardlimits (GUACAMOLE-2002)
raised this to 50 MiB while the default thread stack is only 8 MiB, large
clipboard operations cause a stack overflow (SIGSEGV) that silently kills the
connection.
Root cause
guac_rdp_cliprdr_format_data_response()declares:c char received_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];With
GUAC_COMMON_CLIPBOARD_MAX_LENGTHat 50 MiB (52428800 bytes) and thedefault pthread stack size at 8 MiB, this overflows the stack immediately.
Similarly,
guac_rdp_cliprdr_format_data_request()heap-allocates the outputbuffer using
guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH)but could usethe actual configured clipboard size instead.
Fix
guac_mem_alloc()with the actual configuredclipboard size (
clipboard->clipboard->available) instead of the compile-timemaximum
formats)
Affected versions
staging/1.6.1andmain- any build with configurable clipboard limits(merged via PR GUACAMOLE-2002: Allow connection clipboard limits to be configured. #564)
JIRA
GUACAMOLE-2002 - this is
a regression from the configurable clipboard limits feature.
Test plan