Zero-length WebSocket message causes ttyd crash / remote DoS
Describe the bug
A zero-length WebSocket message can cause ttyd to crash.
When ttyd receives an empty WebSocket text or binary message, the WebSocket receive handler allocates a zero-length buffer. Since xmalloc(0) returns NULL, the handler later dereferences pss->buffer[0], causing undefined behavior and a crash.
This can be triggered remotely by a connected WebSocket client. If ttyd is running without authentication, the crash is reachable without credentials. If authentication is enabled, it is reachable after successful authentication.
To Reproduce Steps to reproduce the behavior:
Start
ttyd, for example:ttyd -i 127.0.0.1 -p 17681 /bin/loginConnect to the WebSocket endpoint:
ws://127.0.0.1:17681/wsSend a zero-length WebSocket message, either empty text or empty binary.
Observe that
ttydcrashes.
With ASan/UBSan enabled, the crash is reported in the WebSocket receive handler. Example sanitizer output:
runtime error: null pointer passed as argument 1, which is declared to never be null
#0 in callback_tty src/protocol.c
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/protocol.cThe relevant code path appears to be:
if (pss->buffer == NULL) {
pss->buffer = xmalloc(len);
pss->len = len;
memcpy(pss->buffer, in, len);
}
const char command = pss->buffer[0];When len == 0, xmalloc(0) returns NULL, and pss->buffer[0] is later accessed.
Expected behavior
ttyd should handle zero-length WebSocket messages safely.
It should either ignore empty messages or close the WebSocket connection without crashing.
Screenshots Not applicable.
Environment:
- OS: Linux
- ttyd version: 1.7.7
- libwebsockets version: 4.3.3
- Browser: Not browser-specific; reproduced with a raw WebSocket client
- Build: Reproduced with ASan/UBSan enabled
Additional context
Suggested fix: reject or ignore zero-length WebSocket messages before allocation and before reading pss->buffer[0].
For example:
case LWS_CALLBACK_RECEIVE:
if (len == 0) {
lwsl_warn("ignored empty WS message\n");
return 0;
}It may also be safer to avoid returning NULL from xmalloc(0), or to ensure all callers handle zero-length allocations correctly before dereferencing the returned pointer.
Source: tsl0922/ttyd