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>
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>
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>
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>
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 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)
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>
Wayland debug logs resemble email addresses. This is a problem when
anonymizing logs from users. For example:
[2512874.343] xdg_surface@700.configure(333)
In the above log line, the substring "surface@700.config" can be
mistaken for an email address and redacted during anonymization.
Signed-off-by: Alex Yang <aycyang@google.com>
Use bool instead of int for boolean values, to make it more
explicit what the field contains. For instance "error" is not to
be confused with an error code.
This is all private API.
Signed-off-by: Simon Ser <contact@emersion.fr>
If wl_event_loop_dispatch() fails, we could enter an infinite loop,
repeatedly calling a failing wl_event_loop_dispatch() forever.
Signed-off-by: Simon Ser <contact@emersion.fr>
display->id is initialized to 1, making 0 a convenient value to
indicate an invalid global name. Make sure to not return a zero
global name on overflow. Moreover, if we wrap around, we might
cycle back to a global name which is already in-use.
Signed-off-by: Simon Ser <contact@emersion.fr>
A late-destroy listener for a client is called after all the client's
resources have been destroyed and the destroy callbacks emitted. This
lives in parallel to the existing client destroy listener, called
immediately before the client's objects get destroyed.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Fixes: wayland/wayland#207
Fixes the following warnings:
src/wayland-server.c:1152: warning: documented empty return type of wl_display::wl_display_destroy
src/wayland-server.c:1193: warning: documented empty return type of wl_display::wl_display_set_global_filter
Signed-off-by: Simon Ser <contact@emersion.fr>
Typically this is a number between 0 and 32. Just that the compiler doesn't
know that well. Make the string buffer a bit larger, so that it fits the
longer integers. Fixes build warnings like:
../subprojects/wayland/src/wayland-server.c: In function ‘wl_display_add_socket_auto’:
../subprojects/wayland/src/wayland-server.c:1649:70: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 8 [-Werror=format-truncation=]
1649 | snprintf(display_name, sizeof display_name, "wayland-%d", displayno);
| ^~
../subprojects/wayland/src/wayland-server.c:1649:61: note: directive argument in the range [-2147483647, 32]
1649 | snprintf(display_name, sizeof display_name, "wayland-%d", displayno);
| ^~~~~~~~~~~~
../subprojects/wayland/src/wayland-server.c:1649:17: note: ‘snprintf’ output between 10 and 20 bytes into a destination of size 16
1649 | snprintf(display_name, sizeof display_name, "wayland-%d", displayno);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Seen in GTK CI.
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
See the previous discussion at [1]: libwayland incorrectly skips
the visibility checks when sending global/global_remove events.
The check is only performed when a client performs a
wl_display.get_registry request.
[1]: https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/148
Signed-off-by: Simon Ser <contact@emersion.fr>
The [spec][1] reads:
> All paths set in these environment variables must be absolute. If an
> implementation encounters a relative path in any of these variables it should
> consider the path invalid and ignore it.
and
> If $XDG_DATA_HOME is either not set or empty, a default equal to
> $HOME/.local/share should be used.
Testing that the path is absolute also entails that is is non-empty.
[1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
Signed-off-by: Antonin Décimo <antonin.decimo@gmail.com>
Add a helper to check the advertised version of a global. This can
be handy when checking whether a compositor feature is supported,
instead of having to store the version passed to wl_global_create
separately.
Signed-off-by: Simon Ser <contact@emersion.fr>
wl_signal_emit doesn't handle well situations where a listener removes
another listener. This can happen in practice: wlroots and Weston [1]
both have private helpers to workaround this defect.
wl_signal_emit can't be fixed without breaking the API. Instead,
introduce a new function. Callers need to make sure to always remove
listeners when they are free'd.
[1]: https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/457
Signed-off-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
When allocating memory for structs, use zalloc instead of malloc.
This ensures the memory is zero-initialized, and reduces the risk
of forgetting to initialize all struct fields.
Signed-off-by: Simon Ser <contact@emersion.fr>
The client side closure traces have incorrect object ids for new server
generated objects. This is because create_proxies() overwrites the id in
'n' type arguments by storing a pointer to the actual object in the 'o'
field of the union.
Getting back to an id from this pointer requires accessing a structure
that isn't visible outside of wayland-client.c.
Add a function pointer to fish the correct value out of the argument and
pass it to wl_closure_print.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Calling wl_display_terminate() will exit the wl_display event loop
at the start of the next loop iteration. This works fine when
wl_display_terminate() is called after the event loop wakes up
from polling on the added event sources. If, however, it is
called before polling starts, the event loop will not exit until
one or more event sources trigger. Depending on the types of event
sources, they may never trigger (or may not trigger for a long time),
so the event loop may never exit.
Add an extra event source to the wl_display event loop that will trigger
whenever wl_display_terminate() is called, so that the event loop will
always exit.
Fixes#201
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
On FreeBSD we have to use getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED)
instead. This change is based on a downstream patch in FreeBSD ports.
Co-authored-by: Greg V <greg@unrelenting.technology>
Co-authored-by: Koop Mast <kwm@rainbow-runner.nl>
Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
This function constructs a socket path in sun_path using snprintf, which
returns the amount of space that would have been used if the buffer was
large enough. It then checks if this is larger then the actual buffer size
and, if so, returns ENAMETOOLONG. This is correct.
However, after calling snprintf and before checking that the length isn't too
long, it tries to compute a pointer to the part of the path that matches the
input name. It does this by adding the computed path length to the pointer to
the start of the path buffer, which will take it to one-past the null
terminator, and then walking backwards. If the path fits in the buffer, this
will take it at most one-past-the-end of the allocation, which is allowed, but
if the path is longer then the buffer then the pointer addition is undefined behavior.
Fix this by moving the display name computation past the check that the path
length is not too long.
This is detected by the test socket_path_overflow_server_create under ubsan.
Signed-off-by: Fergus Dall <sidereal@google.com>
Before this patch, setting WAYLAND_DEBUG=1 or WAYLAND_DEBUG=client made
a program log all requests sent and events that it processes. However,
some events received are not processed. This can happen when a Wayland
server sends an event to an object that does not exist, or was recently
destroyed by the client program (either before the event was decoded,
or after being decoded but before being dispatched.)
This commit prints all discarded messages in the debug log, producing
lines like:
[1234567.890] discarded [unknown]@42.[event 0](0 fd, 12 byte)
[1234567.890] discarded wl_callback@3.done(34567)
[1234567.890] discarded [zombie]@13.[event 1](3 fd, 8 byte)
The first indicates an event to an object that does not exist; the
second, an event to an object that was deleted after decoding, but
before dispatch; the third, an event to an object that left a
'zombie' marker behind to indicate which events have associated
file descriptors.
Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
This can be useful if the compositor wants to call wl_global_destroy() with some
delay but it doesn't have the wl_display object associated with the global,
which is needed to get access to the event loop.
Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
The compositor should handle absolute paths in WAYLAND_DISPLAY like the clients, ie not
adding the XDG_RUNTIME_DIR prefix if it's an absolute path.
This allows to create the wayland socket in a separate directory for system compositors if
desired. Clients could then directly inherit the environment variable.
Signed-off-by: Loïc Yhuel <loic.yhuel@softathome.com>
Including wayland-server-core.h in wayland-private.h is problematic
because wayland-private.h is included by wayland-scanner which should be
able to build against non-POSIX platforms (e.g. MinGW). The only reason
that wayland-server-core.h was included in wayland-private.h was for the
wl_private_signal definitions, so move those to a
wayland-server-private.h file that can be included by both
wayland-server.c and the tests.
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
This commit adds a new wl_global_remove function that just sends a global
remove event without destroying it. See [1] for details.
Removing a global is racy, because clients have no way to acknowledge they
received the removal event.
It's possible to mitigate the issue by sending the removal event, waiting a
little and then destructing the global for real. The "wait a little" part is
compositor policy.
[1]: https://gitlab.freedesktop.org/wayland/wayland/issues/10
Signed-off-by: Simon Ser <contact@emersion.fr>
When implementing a workaround for [1], one needs to accept a global to be
bound even though it has become stale.
Often, a global's user data is free'd when the global needs to be destroyed.
Being able to set the global's user data (e.g. to NULL) can help preventing a
use-after-free.
(The alternative is to make the compositor responsible for keeping track of
stale user data objects via e.g. refcounting.)
[1]: https://gitlab.freedesktop.org/wayland/wayland/issues/10
Signed-off-by: Simon Ser <contact@emersion.fr>
The interface name provided by the client isn't used at all.
Check it matches the global's interface name to prevent object interface
mismatches between the client and the server. These are especially easy to get
when mixing up global names and other IDs in the client.
Signed-off-by: Simon Ser <simon.ser@intel.com>
Closes: https://gitlab.freedesktop.org/wayland/wayland/issues/113
In the current workflow, socket file will be deleted if it already exists.
However, if the socket file is a symbolic link and the file that it refers
to doesn't exist, we will got "Address already in use" because bind()
thinks the socket file exists and won't create it.
Now, use lstat() to determine whether the socket file exists.
Signed-off-by: Liu Wenlong <liuwl.fnst@cn.fujitsu.com>