If WAYLAND_DEBUG contains the token "thread_id", and gettid() is
available, then include the current thread ID in the output from
wl_closure_print.
If multiple threads are sending requests, then those requests can get
interleaved. That's usually fine, but for wl_surface requests and
commits, that can cause problems ranging from incorrect behavior to
protocol errors.
Being able to see which requests are sent by different threads would
make such problems much easier to diagnose.
Signed-off-by: Kyle Brenneman <kbrenneman@nvidia.com>
Add a new function, wl_check_env_token, to scan for a token in a
comma-separated string.
Change wl_display_create in wayland-server.c and
wl_display_connect_to_fd in wayland-client.c to use that instead of a
simple substring search.
This means that WAYLAND_DEBUG will accept a value like "client,server"
but not "clientserver". But, this will make it easier to add other
tokens without worrying about overlap between them.
Signed-off-by: Kyle Brenneman <kbrenneman@nvidia.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>
atoi() has undefined behavior on invalid input, but here the input comes
from wayland-scanner, which is trusted.
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
Neither ring_buffer_put_iov() nor ring_buffer_get_iov() distinguishes
between a full wl_ring_buffer and an empty one. Instead, both just
assume that the returned iovec should not be empty. However, both have
only one caller, and that caller does guarantee that the ring buffer is
not full (for ring_buffer_put_iov()) or empty (for
ring_buffer_get_iov()). Therefore, the code is safe.
Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.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>
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>
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>
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>
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>
The usefulness of this is limited, and `libwayland-client` doesn't
provide a way to pass a null `new_id` since the id is generated by the
library and given to the caller as the return value.
Signed-off-by: Ian Douglas Scott <idscott@system76.com>
Nullable arrays, which are not used anywhere, were marshalled the same
way as an empty non-null array. The demarshalling logic did not
recognize anything as a null array. Given this, it seems better to just
explicitly not support it.
Fixes https://gitlab.freedesktop.org/wayland/wayland/-/issues/306.
Signed-off-by: Ian Douglas Scott <idscott@system76.com>
Initialiaze the entire msghdr struct to 0 before use.
Example of the report fixed with this change:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==20035==ERROR: AddressSanitizer: SEGV on unknown address 0x2dad4dbffffa0d (pc 0x0055555c7488 bp 0x007fffffc760 sp 0x007fffffc760 T0)
==20035==The signal is caused by a READ memory access.
#0 0x55555c7488 in read_msghdr(void*, __sanitizer::__sanitizer_msghdr*, long) (/home/ftrvx/w/_/uxn/bin/uxnemu+0x77488)
#1 0x55555c810c in sendmsg (/home/ftrvx/w/_/uxn/bin/uxnemu+0x7810c)
#2 0x7ff7f2db20 in wl_connection_flush /home/ftrvx/q/wayland/build/../src/connection.c:315:10
#3 0x7ff7f2d014 in wl_display_flush /home/ftrvx/q/wayland/build/../src/wayland-client.c:2154:9
#4 0x7ff7e80bc0 (/lib/libSDL2-2.0.so.0+0x104bc0)
#5 0x7ff7e523b0 (/lib/libSDL2-2.0.so.0+0xd63b0)
#6 0x7ff7e534e4 (/lib/libSDL2-2.0.so.0+0xd74e4)
#7 0x7ff7e535e8 (/lib/libSDL2-2.0.so.0+0xd75e8)
#8 0x7ff7daad54 (/lib/libSDL2-2.0.so.0+0x2ed54)
#9 0x7ff7dab130 (/lib/libSDL2-2.0.so.0+0x2f130)
#10 0x555565bb40 in main /home/ftrvx/w/_/uxn/src/uxnemu.c:519:2
#11 0x7ff7f62484 in libc_start_main_stage2 /builddir/musl-1.1.24/src/env/__libc_start_main.c:94:2
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/ftrvx/w/_/uxn/bin/uxnemu+0x77488) in read_msghdr(void*, __sanitizer::__sanitizer_msghdr*, long)
==20035==ABORTING
Signed-off-by: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
When multiple threads are used, output from different threads was intermixed in one line. That what breaking parsing of the log messages. Now, intermixing is prevented by using a memstream.
Signed-off-by: Alexander Irion <alexander_irion@mentor.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>
struct wl_buffer has other meaning in wayland, thus making this a pretty
confusing structure name. Function names like wl_buffer_put() just
compound the confusion.
Rename the struct and the associated functions (none of which are called
from outside this file anyway). The struct retains a wl_ prefix, as is
the custom for wayland internal data structures. The function names
have not retained this prefix, as we have many static function that
aren't prefixed.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Specifically, in the log formed when WAYLAND_DEBUG is set, this commit
ensures that floating point numbers are formatted using '.' instead of
the locale-specific decimal separator. As the debug logs are not
otherwise localized for end-users, and may be parsed by scripts, it is
better to have consistent output here.
The 24.8 fixed point numbers are now represented with 8 digits after
the decimal, since this is both exact and simpler to compute.
Signed-off-by: Manuel Stoeckl <code@mstoeckl.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>
Currently a null string passed into a non-nullable argument of a message
will decode succesfully, probably resulting in the handler function
crashing. Instead treat it the same way we do non-nullable objects and ids.
Signed-off-by: Fergus Dall <sidereal@google.com>
Instead, cleanly exit wl_closure_marshal and let the caller handler
the error. For wayland-client, the sole calling function will call
wl_abort() anyway. For wayland-server, the calling function will
cleanly shutdown the client.
This change ensures that compositors run with low file descriptor
limits or internal leaks need not crash suddenly (and sometimes
far from the problem) when space runs out.
Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
The size argument to wl_connection_demarshal() is taken from the message by the
caller wl_client_connection_data(), therefore 'size' is untrusted data
controllable by a Wayland client. The size should always be at least the header
size, otherwise the header is invalid.
If the size is smaller than header size, it leads to reading past the end of
allocated memory. Furthermore if size is zero, wl_closure_init() changes
behaviour and leaves num_arrays uninitialized, leading to access of arbitrary
memory.
Check that 'size' fits at least the header. The space for arguments is already
properly checked.
This makes the request_bogus_size test free of errors under Valgrind.
Fixes: https://gitlab.freedesktop.org/wayland/wayland/issues/52
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Calling printf("%s", NULL) is undefined behaviour.
Signed-off-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
If the remote side sends sufficiently large `length` field, it will
overflow the `p` pointer. Technically it is undefined behavior, in
practice it makes `p < end`, so the length check passes. Attempts to
access the data later causes crashes.
This issue manifests only on 32bit systems, but the behavior is
undefined everywhere.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Derek Foreman <derek.foreman.samsung@gmail.com>
The DIV_ROUNDUP macro would overflow when trying to round values higher
than MAX_UINT32 - (a - 1). The result is 0 after the division. This is
potential security issue when demarshalling an array because the length
check is performed with the overflowed value, but then the original huge
value is stored for later use.
The issue was present only on 32bit platforms. The use of size_t in the
DIV_ROUNDUP macro already promoted everything to 64 bit size on 64 bit
systems.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Derek Foreman <derek.foreman.samsung@gmail.com>
Style changes by Derek Foreman
Like the similar wl_log() message further into this function that was
fixed in commit 2fc248dc2c this should
be printing the sender_id saved earlier instead of *p.
Since p is incremented during the loop it would not only print an
incorrect object id, it could read past the end of the array.
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
commit 52609ddf79 was intended to
set fds to -1 in the arg list, however it failed to account for
version information at the start of signatures.
Most noticably, this broke mesa's create_prime_buffer by setting
width to -1 instead of the fd, as the width was the argument
following the fd, and the version was one byte long.
This should close https://bugs.kde.org/show_bug.cgi?id=389200
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Daniel Stone <daniels@collabora.com>
We need to close file descriptors sent to zombie proxies to avoid leaking
them, and perhaps more importantly, to prevent them from being dispatched
in events on other objects (since they would previously be left in the
buffer and potentially fed to following events destined for live proxies)
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Add a new map entry flag to indicate that the object received is valid,
but a zombie. Previously this relied on a fixed object pointer, but
future patches in this series will have map entries returning either
NULL, or a different structure type entirely, for zombie objects.
wl_object_is_zombie() now solely uses the new flag to determine whether
or not the object is a zombie.
[daniels: Extracted from Derek's bespoke-zombie patch as an intermediate
step.]
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Add a helper function which determines whether or not an object is a
zombie.
[daniels: Extracted from Derek's bespoke-zombie patch as an intermediate
step.]
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
When we have a closure that can't be dispatched for some reason, and it
contains file descriptors, we must close those descriptors to prevent
leaking them.
Previous commits ensure that only FDs belonging to this invocation of
the closure, i.e. not FDs provided by the client for marshalling, nor
FDs which have already been dispatched to either client or server, will
be left in the closure by destroy time.
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>