Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Server/PeekExactTimeout(): Guard against inf. loop
If an ill-behaved RFB client preemptively sends fewer than 4 bytes of the RFB version header before receiving the version header from the server, then the first call to PeekExactTimeout() in webSocketsCheck() may get into an infinite loop. More specifically, when this happens, the recv() call in PeekExactTimeout() returns n < len with errno set to EAGAIN, PeekExactTimeout() falls through to the select() call, select() returns 1 with errno unchanged, and the loop repeats indefinitely because the client is waiting to receive the server's version header before it sends additional data. Such RFB clients are technically incorrect but work accidentally with most RFB servers, because most RFB servers don't peek the socket to check for a WebSocket header. This issue was known to affect certain versions of Apache Guacamole sporadically. However, the issue could reliably be triggered by running echo XX | netcat {TurboVNC_host} {TurboVNC_session_port} Thus, it represents a DoS vulnerability. The right thing to do seems to be to enforce the timeout ourselves if recv() returns n < len with errno set to EAGAIN or EWOULDBLOCK, and if select() subsequently returns 1. In that case, select() has not enforced the timeout for us. Fixes #427
- Loading branch information