For dispatching messages on a queue with a timeout.
This slightly changes the samantics of wl_display_dispatch. Previously
it was possible for it to return even though there wasn't a single
dispatched event. The function correctly returned 0 in this case but it
is now used to indicate a timeout.
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
Makes it possible to e.g. `call wl_client_get_credentials` with a `const
struct wl_client *` from a global filter callback.
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
when cast double to fixed pointer, there will be big
error, eg 1919.9998 to 1919. Call round before cast
to get nearest value 1920 of 1919.9998
Signed-off-by: Haihua Hu <jared.hu@nxp.com>
Prevents undefined behavior if there is not enough space in the buffer
for a queued message.
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
Creating a pointer that is more than one element past the end of an
array is undefined behavior, even if the pointer is not dereferenced.
Avoid this undefined behavior by using `p >= end` instead of
`p + 1 > end` and `SOMETHING > end - p` instead of
`p + SOMETHING > end`.
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
libwayland cannot construct these messages as it uses strlen() to
determine string lengths. libwayland is also guaranteed to misinterpret
these messages, since message handlers only get a pointer and no length.
Therefore, reject strings containing NUL bytes.
Also remove a redundant check from the unmarshalling code. The
zero-length case has already been checked for.
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
The log that appears before a display_error can be captured as crash
signature. Useful to know what it is.
This is cherry-picked from chromium https://crrev.com/c/4697877
Signed-off-by: Fangzhou Ge <fangzhoug@chromium.org>
From cleanup commit 0cecde304:
assert()s can be compiled away by #defining NDEBUG. Some build systems
do this. Using wl_abort gives a human readable error message and it
isn't compiled away.
That commit missed one final assert, presumably due to missing it with
grep because of a coding style issue. Fix that up, and remove inclusion
of <assert.h> as appropriate.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
wl_proxy_get_queue can return NULL if the queue of the proxy was already
destroyed with wl_event_queue_destroy. In this case, the queue also has
no name anymore.
Fixes: b42218f ("client: Allow setting names for queues")
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
assert()s can be compiled away by #defining NDEBUG. Some build systems
do this. Using wl_abort gives a human readable error message and it
isn't compiled away. This commit closes issue #230.
Signed-off-by: meltq <tejasvipin76@gmail.com>
Bitfields are valid if the value only contains bits inside of
the supported entries for the given version.
Signed-off-by: Simon Ser <contact@emersion.fr>
It's unclear whether one needs to call close() if wl_client_create()
fails. Hopefully this change makes it more clear.
Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Currently WAYLAND_DEBUG text ignores events that have no listener.
It can be helpful to know when you're receiving unhandled events,
as you may have forgotten to add a listener, or adding a dispatch
may have magically seemed to fix code that doesn't appear to be
dispatching anything.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Fixes the following warning:
src/wayland-client-core.h:125: warning: Found non-existing group 'wl_proxy' for the command '@ingroup', ignoring command
"\memberof" cannot be used here because it only works on functions.
The docs for "\memberof" say that "\relates" works in a similar way.
While at it, use a "\" command instead of a "@" command for
consistency with the rest of the file.
Signed-off-by: Simon Ser <contact@emersion.fr>
This marks a request, event or enum entry as deprecated since a
given version.
Note that it's not clear what it means if an entry is deprecated
at some version, and the enum is used from some completely different
interface than where it was defined. However, that's a more general
issue with enums, see:
https://gitlab.freedesktop.org/wayland/wayland/-/issues/435
Signed-off-by: Simon Ser <contact@emersion.fr>
References: https://gitlab.freedesktop.org/wayland/wayland/-/issues/89
Right now compositors need to manually check that enum values sent
by the client are valid. In particular:
- Check that the value sent by the client is not outside of the enum.
- Check that the version of the enum entry is consistent with the
object version.
Automatically generate validator functions to perform these tasks.
Signed-off-by: Simon Ser <contact@emersion.fr>
Closes: https://gitlab.freedesktop.org/wayland/wayland/-/issues/104
When using fixed size connection buffers, if either the client or the
server is sending requests faster than the other end can cope with, the
connection buffers will fill up, eventually killing the connection.
This can be a problem for example with Xwayland mapping a lot of
windows, faster than the Wayland compositor can cope with, or a
high-rate mouse flooding the Wayland client with pointer events.
To avoid the issue, resize the connection buffers dynamically when they
get full.
Both data and fd buffers are resized on demand.
The default max buffer size is controlled via the wl_display interface
while each client's connection buffer size is adjustable for finer
control.
The purpose is to explicitly have larger connection buffers for specific
clients such as Xwayland, or set a larger buffer size for the client
with pointer focus to deal with a higher input events rate.
v0: Manuel:
Dynamically resize connection buffers - Both data and fd buffers are
resized on demand.
v1: Olivier
1. Add support for unbounded buffers on the client side and growable
(yet limited) connection buffers on the server side.
2. Add the API to set the default maximum size and a limit for a given
client.
3. Add tests for growable connection buffers and adjustable limits.
v2: Additional fixes by John:
1. Fix the size calculation in ring_buffer_check_space()
2. Fix wl_connection_read() to return gracefully once it has read up to
the max buffer size, rather than returning an error.
3. If wl_connection_flush() fails with EAGAIN but the transmit
ring-buffer has space remaining (or can be expanded),
wl_connection_queue() should store the message rather than
returning an error.
4. When the receive ring-buffer is at capacity but more data is
available to be read, wl_connection_read() should attempt to
expand the ring-buffer in order to read the remaining data.
v3: Thomas Lukaszewicz <tluk@chromium.org>
Add a test for unbounded buffers
v4: Add a client API as well to force bounded buffers (unbounded
by default (Olivier)
v5: Simplify ring_buffer_ensure_space() (Sebastian)
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: John Lindgren <john@jlindgren.net>
Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net>
Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: John Lindgren <john@jlindgren.net>
Signed-off-by: Sebastian Wick <sebastian@sebastianwick.net>
Closes: https://gitlab.freedesktop.org/wayland/wayland/-/issues/237
This generates a header with only enum definitions. This is useful
to share enum headers between libraries and library users.
Signed-off-by: Simon Ser <contact@emersion.fr>
If a wl_array has size zero, wl_array_for_each computes NULL + 0 to get
to the end pointer. This should be fine, and indeed it would be fine in
C++. But the C specification has a mistake here and it is actually
undefined behavior. See
https://davidben.net/2024/01/15/empty-slices.html
Clang's -fsanitize=undefined flags this. I ran into this in Chromium's
build with wayland-scanner on one of our XML files.
../../third_party/wayland/src/src/scanner.c:1853:2: runtime error: applying zero offset to null pointer
#0 0x55c979b8e02c in emit_code third_party/wayland/src/src/scanner.c:1853:2
#1 0x55c979b89323 in main third_party/wayland/src/src/scanner.c
#2 0x7f8dfdb8c6c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#3 0x7f8dfdb8c784 in __libc_start_main csu/../csu/libc-start.c:360:3
#4 0x55c979b70f39 in _start (...)
An empty XML file is sufficient to hit this case, so I've added it as a
test. To reproduce, undo the fix and include only the test, then build
with:
CC=clang CFLAGS="-fno-sanitize-recover=undefined" meson build/ -Db_sanitize=undefined -Db_lundef=false
ninja -C build test
Signed-off-by: David Benjamin <davidben@google.com>
This is less cryptic to read than letters, and allows the compiler
to check switch statements exhaustiveness.
Signed-off-by: Simon Ser <contact@emersion.fr>
There are situations in which a call into wl_client_destroy() can
result in a reentrant call into wl_client_destroy() - which
results in UAF / double free crashes.
For example, this can occur in the following scenario.
1. Server receives a message notifying it that a client has
disconnected (WL_EVENT_HANGUP [1])
2. This beings client destruction with a call to wl_client_destroy()
3. wl_client_destroy() kicks off callbacks as client-associated
resources are cleaned up and their destructors and destruction
signals are invoked.
4. These callbacks eventually lead to an explicit call to
wl_display_flush_clients() as the server attempts to flush
events to other connected clients.
5. Since the client has already begun destruction, when it is
reached in the iteration the flush fails wl_client_destroy()
is called again [2].
This patch guards against this reentrant condition by removing
the client from the display's client list when wl_client_destroy()
is first called. This prevents access / iteration over the client
after wl_client_destroy() is called.
In the example above, wl_display_flush_clients() will pass over
the client currently undergoing destruction and the reentrant
call is avoided.
[1] 8f499bf404/src/wayland-server.c (L342)
[2] 8f499bf404/src/wayland-server.c (L1512)
Signed-off-by: Thomas Lukaszewicz [thomaslukaszewicz@gmail.com](mailto:thomaslukaszewicz@gmail.com)
- wayland-egl-abi-check: try to use llvm-nm first instead of BSD nm (incompatible options)
- avoid forcing _POSIX_C_SOURCE=200809L (SOCK_CLOEXEC become available)
- epoll(7) is provided by a userspace wrapper around kqueue(2) as FreeBSD
- when using SO_PEERCRED, the struct to use is `struct sockpeercred` instead of `struct ucred` on OpenBSD
- provide a compatibility layer for count_open_fds() using sysctl(2) as FreeBSD
Signed-off-by: Sebastien Marie <semarie@online.fr>
The only way to attach some data to a wl_client seems to be setting up a
destroy listener and use wl_container_of. Let's make it straight forward
to attach some data.
Having an explicit destroy callback for the user data makes managing the
user data lifetime much more convenient. All other callbacks, be they
wl_resource request listeners, destroy listeners or destructors, or
wl_client destroy listeners, can assume that the wl_client user data
still exists if it was set. Otherwise making that guarantee would be
complicated.
Co-authored-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Sebastian Wick <sebastian@sebastianwick.net>
Currently it is possible to iterate over client-owned resources
during client destruction that have had their associated memory
released.
This can occur when client code calls wl_client_destroy(). The
following sequence illustrates how this may occur.
1. The server initiates destruction of the connected client via
call to wl_client_destroy().
2. Resource destroy listeners / destructors are invoked and
resource memory is freed one resource at a time [1].
3. If a listener / destructor for a resource results in a call
to wl_client_for_each_resource(), the iteration will proceed
over resources that have been previously freed in step 2,
resulting in UAFs / crashes.
The issue is that resources remain in the client's object map
even after they have had their memory freed, and are removed
from the map only after each individual resource has had its
memory released.
This patch corrects this by ensuring resource destruction first
invokes listeners / destructors and then removing them from the
client's object map before releasing the associated memory.
[1] https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/src/wayland-server.c?ref_type=heads#L928
Signed-off-by: Thomas Lukaszewicz thomaslukaszewicz@gmail.com
Allow setting a name for an event queue. The queue is used only for
printing additional debug information.
Debug output can now show the name of the event queue an event is
dispatched from, or the event queue of a proxy when a request is made.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Some code paths that lead to a client error and connection termination
have no associated logging, or insufficient logging. This makes it
difficult to understand what went wrong. This commit adds or supplements
logging for all these code paths.
Signed-off-by: Erik Chen <erikchen@chromium.org>
wl_connection_write() contained an exact copy of the logic in
wl_connection_queue(). Simplify things by just calling
wl_connection_queue() from wl_connection_write().
Signed-off-by: John Lindgren <john@jlindgren.net>
For libs/cflags this is done automatically, but not for manually accessed
variables. This matches what wayland-protocols does.
Signed-off-by: Andreas Cord-Landwehr <cordlandwehr@kde.org>
This was hardcoded to 1 regardless of the version passed to the
callback or the version of the parent resource.
Signed-off-by: Simon Ser <contact@emersion.fr>
Due to what is arguably a mistake in the C language specification,
passing NULL to memcpy and friends is undefined behavior (UB) even when
the count is 0. C additionally mistakenly leaves NULL + 0 and NULL -
NULL undefined. (C++ fixes this mistake.) These are very problematic
because (NULL, 0) is a natural representation of the empty slice.
Some details:
https://github.com/llvm/llvm-project/issues/49459https://www.imperialviolet.org/2016/06/26/nonnull.html
Unfortunately, despite how clearly this is a mistake, glibc headers and
GCC now try to exploit this specification mistake and will miscompile
code, so C projects need to workaround this. In particular, UBSan from
Clang will flag this as a bug (although Clang itself has the good sense
to never lean on this bug). We've run into a few UBSan errors in
Chromium stemming from Wayland's memcpy calls. Add runtime guards as
needed to avoid these cases.
Note: Chromium's copy of wayland has
https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/188
applied. It is possible the ring_buffer_copy UB cases are only reachable
with that MR applied, I'm not sure. But it seemed simplest to just add
the fix to wayland as-is. Then when/if that MR lands, it will pick this
up.
Signed-off-by: David Benjamin <davidben@google.com>