connection: Do not busy-loop if a message exceeds the buffer size
If the length of a message exceeds the maximum length of the buffer, the
buffer size will reach its maximum value and stay there forever, with no
message ever being successfully processed. Since libwayland uses
level-triggered epoll, this will cause the compositor to loop forever
and consume CPU time. In libwayland 1.22 and below, there was an
explicit check that caused messages exceeding 4096 bytes to result in an
EOVERFLOW error, preventing the loop. However, this check was removed
between d074d5290263 ("connection: Dynamically resize connection buffers").
To prevent this problem, always limit the size of messages to 4096 bytes.
Since the default and minimum buffer size is 4096 bytes, this ensures
that a single message will always fit in the buffer. It would be
possible to allow larger messages if the buffer size was larger, but the
maximum size of a message should not depend on the buffer size chosen by
the compositor.
Rejecting messages that exceed 4092 bytes seems to have the advantage of
reserving 4 bits, not 3, in the size field for future use. However,
message sizes in the range [0x0, 0x7] are invalid, so one can obtain a
fourth bit by negating the meaning of bit 12 if bits 0 through 11
(inclusive) are 0. Allowing 4096-byte messages provides the far more
important advantage that regressions compared to 1.22 are impossible
and regressions compared to 1.23 are extremely unlikely. The only case
where a regression is possible is:
- The receiving side is using libwayland 1.23.
- The sending side is either using libwayland 1.23 or is not using
libwayland.
- The sender sends a message exceeding 4096 bytes.
- If the sender of the large message is the client, the server has
increased the buffer size from the default value.
This combination is considered extremely unlikely, as libwayland 1.22
and below would disconnect upon receiving such a large message.
4096-byte messages, however, have always worked, so there was no reason
to avoid sending them.
Fixes: d074d5290263 ("connection: Dynamically resize connection buffers").
Fixes: #494
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
(cherry picked from commit adf84614ca6189fa4efc522408ffbbc4b27ae497)
Wayland is a project to define a protocol for a compositor to talk to its clients as well as a library implementation of the protocol. The compositor can be a standalone display server running on Linux kernel modesetting and evdev input devices, an X application, or a wayland client itself. The clients can be traditional applications, X servers (rootless or fullscreen) or other display servers.
The wayland protocol is essentially only about input handling and buffer management. The compositor receives input events and forwards them to the relevant client. The clients creates buffers and renders into them and notifies the compositor when it needs to redraw. The protocol also handles drag and drop, selections, window management and other interactions that must go through the compositor. However, the protocol does not handle rendering, which is one of the features that makes wayland so simple. All clients are expected to handle rendering themselves, typically through cairo or OpenGL.
Building the wayland libraries is fairly simple, aside from libffi, they don't have many dependencies:
$ git clone https://gitlab.freedesktop.org/wayland/wayland $ cd wayland $ meson build/ --prefix=PREFIX $ ninja -C build/ install
where PREFIX is where you want to install the libraries.
See https://wayland.freedesktop.org for documentation.