This is to make sure the hardware gets the device states regardless
whether the internal state has changed or not, to overcome situations
that device LEDs are out of sync e.g. switching between VTs.
Signed-off-by: Yao Wei (魏銘廷) <yao.wei@canonical.com>
The increment sign wasn't taking into account when checking if the next
value is past our current value. The result was that for negative
increments, we kept looping indefinitely, locking up the server.
Easiest to reproduce with the evdev driver which has a negative
increment on the y axis.
Fixes 0a22502c34
dix: switch scroll button emulation to multiples of increment
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The current algorithm triggers a bug in Xwayland when two devices have
different granularity of scrolling. In Xwayland, the scroll increment is
1 and all physical devices scroll through the same (x)wayland pointer
device.
This may cause events to get lost when changing devices:
- mouse scrolls by full increment, current value is 1.0
last scroll button was sent for valuator value 0.0,
delta is 1.0 and we emulate a button event.
- touchpad scrolls by partial increment, current value is 1.3
last scroll button was sent for valuator value 1.0, delta is 0.3
and no button event is emulated
- mouse scrolls by full increment, current value is -0.7,
last scroll button was sent for valuator value 1.0, delta is -0.7
and no button event is emulated
Thus the wheel event appears to get lost. Xwayland cannot reliably
detect this case because we don't see the physical devices.
We can work around this by instead emulating buttons whenever we cross
a multiple of increment. However, this has a drawback:
high-resolution scroll devices can now trigger a button event storm by
jittering across the multiple of increment. e.g. in the example above
the touchpad moving from 1.3 to 1.0 would cause a click, despite this
being a third of an increment.
Fixes#1339
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
storeLastValuators() takes the index in the mask for the x and y axis.
Completely pointless because any device that doesn't have x/y on 0 and
1, respectively, is going to break in fun ways anyway. And we only have
two callers two this function, both of which hardcode 0 and 1.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The code in AttachDevice() may free the dev->spriteInfo->sprite under
some circumstances and later call GetCurrentRootWindow() which uses
the same dev->spriteInfo->sprite.
While it seems unlikely that this is actually an issue, considering the
cases where one or the other get called, it still makes the code look
suspicious.
Make sure to clear set dev->spriteInfo->sprite to NULL immediately
after it's freed to avoid any confusion, even if only to clarify the
code.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1436
The event might be a DeviceEvent allocated on the stack, in
AccessXKeyboardEvent for instance. Fixes out-of-bounds read.
Signed-off-by: Mike Gorse <mgorse@suse.com>
This updates rootless to treat pixmaps consistently with COMPOSITE,
using the screen_x and screen_y values rather than doing hacky math.
This will allow for proper bounds checking on a given PixmapRec.
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
The X server swapping code is a huge attack surface, much of this code
is untested and prone to security issues. The use-case of byte-swapped
clients is very niche, so let's disable this by default and allow it
only when the respective config option or commandline flag is given.
For Xorg, this adds the ServerFlag "AllowByteSwappedClients" "on".
For all DDX, this adds the commandline options +byteswappedclients and
-byteswappedclients to enable or disable, respectively.
Fixes#1201https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1029
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The minimal performance wins we gain by recycling pixmaps at this layer are
not worth the code complexity nor the interference with memory analysis
tools like malloc history, ASan, etc.
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
PixmapDirtyCopyArea() is about to be used outside of pixmap.c, so fix up
its interface by specifying the dirty area directly rather than passing a
`PixmapDirtyUpdatePtr`. This makes it easier to use outside of pixmap.c, as
the caller doesn't need to create a bulky PixmapDirtyUpdateRec to use this
function.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
This fixes an OOB read and the resulting information disclosure.
Length calculation for the request was clipped to a 32-bit integer. With
the correct stuff->num_items value the expected request size was
truncated, passing the REQUEST_FIXED_SIZE check.
The server then proceeded with reading at least stuff->num_items bytes
(depending on stuff->format) from the request and stuffing whatever it
finds into the property. In the process it would also allocate at least
stuff->num_items bytes, i.e. 4GB.
The same bug exists in ProcChangeProperty and ProcXChangeDeviceProperty,
so let's fix that too.
CVE-2022-46344, ZDI-CAN 19405
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Despite e957a2e5dd ("dix: Add hybrid full-size/empty-clip mode to
SetRootClip"), I was still seeing all X11 client windows flashing when
the root window size changes with rootless Xwayland (e.g. due to
hotplugging a monitor).
Skipping this code for ROOT_CLIP_INPUT_ONLY fixes the issue for me.
Most of these came from a mass bcopy() -> memmove() substitution in 1993
with a commit comment of "Ansification (changed bfuncs -> mfuncs)"
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Commit c7311654 cached the value of ResourceClientBits(), but that value
depends on the `MaxClients` value set either from the command line or
from the configuration file.
For the latter, a call to ResourceClientBits() is issued before the
configuration file is read, meaning that the cached value is from the
default, not from the maximum number of clients set in the configuration
file.
That obviously causes all sort of issues, including memory corruption
and crashes of the Xserver when reaching the default limit value.
To avoid that issue, also keep the LimitClient value, and recompute the
ilog2() value if that changes, as on startup when the value is set from
the the xorg.conf ServerFlags section.
v2: Drop the `cache == 0` test
Rename cache vars
Fixes: c7311654 - dix: cache ResourceClientBits() value
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1310
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
GTK3 menu widget creates a selection for touch and other events and
after receiving touch events creates an async grab that excludes touch
events. Unfortunately it relies on X server not sending the touch end
event in order to function properly. Sending touch end event will cause
it to think that the initiating touch ended and when it actually ends,
the ButtonRelease event will make it think that the menu should be
closed. As a result, the menu will be open only for the duration of the
touch making it useless.
This commit reverts f682e0563f.
Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1255
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
This fixes access to freed heap memory via dev->master. E.g. when
running BarrierNotify.ReceivesNotifyEvents/7 test from
xorg-integration-tests:
==24736==ERROR: AddressSanitizer: heap-use-after-free on address
0x619000065020 at pc 0x55c450e2b9cf bp 0x7fffc532fd20 sp 0x7fffc532fd10
READ of size 4 at 0x619000065020 thread T0
#0 0x55c450e2b9ce in GetMaster ../../../dix/devices.c:2722
#1 0x55c450e9d035 in IsFloating ../../../dix/events.c:346
#2 0x55c4513209c6 in GetDeviceUse ../../../Xi/xiquerydevice.c:525
../../../Xi/xichangehierarchy.c:95
#4 0x55c450e3455c in RemoveDevice ../../../dix/devices.c:1204
../../../hw/xfree86/common/xf86Xinput.c:1142
#6 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
#7 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
#8 0x55c450e837ef in dix_main ../../../dix/main.c:302
#9 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#11 0x55c450d0113d in _start (/usr/lib/xorg/Xorg+0x117713d)
0x619000065020 is located 160 bytes inside of 912-byte region
[0x619000064f80,0x619000065310)
freed by thread T0 here:
(/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
#1 0x55c450e19f1c in CloseDevice ../../../dix/devices.c:1014
#2 0x55c450e343a4 in RemoveDevice ../../../dix/devices.c:1186
../../../hw/xfree86/common/xf86Xinput.c:1142
#4 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
#5 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
#6 0x55c450e837ef in dix_main ../../../dix/main.c:302
#7 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)
previously allocated by thread T0 here:
(/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10ddc6)
#1 0x55c450e1c57b in AddInputDevice ../../../dix/devices.c:259
#2 0x55c450e34840 in AllocDevicePair ../../../dix/devices.c:2755
#3 0x55c45130318f in add_master ../../../Xi/xichangehierarchy.c:152
../../../Xi/xichangehierarchy.c:465
#5 0x55c4512cb9f5 in ProcIDispatch ../../../Xi/extinit.c:390
#6 0x55c450e6a92b in Dispatch ../../../dix/dispatch.c:551
#7 0x55c450e834b7 in dix_main ../../../dix/main.c:272
#8 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)
The problem is caused by dev->master being not reset when disabling the
device, which then causes dangling pointer when the master device itself
is being deleted when exiting whole server.
Note that RecalculateMasterButtons() requires dev->master to be still
valid, so we can reset it only at the end of function.
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
When processing events we operate on InternalEvent pointers. They may
actually refer to a an instance of DeviceEvent, GestureEvent or any
other event that comprises the InternalEvent union. This works well in
practice because we always look into event type before doing anything,
except in the case of copying the event.
*dst_event = *src_event would copy whole InternalEvent event and would
cause out of bounds read in case the pointed to event was not
InternalEvent but e.g. DeviceEvent.
This regression has been introduced in
23a8b62d34.
Fixes https://gitlab.freedesktop.org/xorg/xserver/-/issues/1261
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
Fix the following race:
Possible data race during read of size 8 at 0xA112510 by thread #6
Locks held: 1, at address 0x366B40
at 0x14C8B9: GetMaster (devices.c:2691)
by 0x15CFC5: IsFloating (events.c:346)
by 0x2B9554: miPointerGetScreen (mipointer.c:527)
by 0x1A5136: xf86PostButtonEventM (xf86Xinput.c:1379)
by 0x1A52BD: xf86PostButtonEvent (xf86Xinput.c:1345)
by 0x485F45B: EvdevProcessEvent (in /usr/lib64/xorg/modules/input/evdev_drv.so)
by 0x485FDAC: EvdevReadInput (in /usr/lib64/xorg/modules/input/evdev_drv.so)
by 0x195427: xf86ReadInput (xf86Events.c:247)
by 0x2CC113: InputReady (inputthread.c:180)
by 0x2CE4EA: ospoll_wait (ospoll.c:657)
by 0x2CC077: InputThreadDoWork (inputthread.c:369)
by 0x484A336: mythread_wrapper (hg_intercepts.c:406)
This conflicts with a previous write of size 8 by thread #1
Locks held: none
at 0x14D2C6: AttachDevice (devices.c:2609)
by 0x15CF85: ReattachToOldMaster (events.c:1457)
by 0x1647DD: DeactivateKeyboardGrab (events.c:1700)
by 0x25D7F1: ProcXIUngrabDevice (xigrabdev.c:169)
by 0x2552AD: ProcIDispatch (extinit.c:398)
by 0x155291: Dispatch (dispatch.c:479)
by 0x158CBA: dix_main (main.c:276)
by 0x143A3D: main (stubmain.c:34)
Address 0xa112510 is 336 bytes inside a block of size 904 alloc'd
at 0x4846571: calloc (vg_replace_malloc.c:1328)
by 0x14A0B3: AddInputDevice (devices.c:260)
by 0x1A31A0: xf86ActivateDevice (xf86Xinput.c:365)
by 0x1A4549: xf86NewInputDevice (xf86Xinput.c:948)
by 0x1A4B44: NewInputDeviceRequest (xf86Xinput.c:1090)
by 0x1B81FE: device_added (udev.c:282)
by 0x1B8516: config_udev_init (udev.c:439)
by 0x1B7091: config_init (config.c:50)
by 0x197970: InitInput (xf86Init.c:814)
by 0x158C6B: dix_main (main.c:250)
by 0x143A3D: main (stubmain.c:34)
Block was alloc'd by thread #1
The steps to trigger the race are:
1. Main thread does cleanup at mipointer.c:360 setting the slave device's
miPointerPtr to null.
2. Input thread use MIPOINTER in mipointer.c and get the slave's
miPointerPtr = null.
3. Main thread updates dev->master at devices.c:2609.
4. MIPOINTER would now return the master's miPointerPtr but the input
thread already got the slave's miPointerPtr in step 2 and segfaults by
null ptr deref.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1260
Signed-off-by: Thomas Lindroth <thomas.lindroth@gmail.com>
This fixes a crash when a DeviceEvent struct converted to
InteralEvent was beeing copied as InternalEvent (and thus
causing out of bounds reads) in ActivateGrabNoDelivery()
in events.c: 3876 *grabinfo->sync.event = *real_event;
Possible fix for https://gitlab.freedesktop.org/xorg/xserver/-/issues/1253
Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
Adding the offset between the realloc result and the old allocation to
update pointers into the new allocation is undefined behaviour: the
old pointers are no longer valid after realloc() according to the C
standard. While this works on almost all architectures and compilers,
it causes problems on architectures that track pointer bounds (e.g.
CHERI or Arm's Morello): the DevPrivateKey pointers will still have the
bounds of the previous allocation and therefore any dereference will
result in a run-time trap.
I found this due to a crash (dereferencing an invalid capability) while
trying to run `XVnc` on a CHERI-RISC-V system. With this commit I can
successfully connect to the XVnc instance running inside a QEMU with a
VNC viewer on my host.
This also changes the check whether the allocation was moved to use
uintptr_t instead of a pointer since according to the C standard:
"The value of a pointer becomes indeterminate when the object it
points to (or just past) reaches the end of its lifetime." Casting to an
integer type avoids this undefined behaviour.
Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
In some scenarios, the Wayland compositor might have more knowledge
than the X11 server and may be able to perform pointer emulation for
touch events better. Add a command-line switch to allow compositors
to turn Xwayland pointer emulation off.
Signed-off-by: Simon Ser <contact@emersion.fr>
It is copied using memcpy() and not modified so we can add const. This
fixes a -Wincompatible-pointer-types-discards-qualifiers compiler warning
that was failing a -Werror XVnc build for me.
Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
When the command line option "-terminate" is used, it could be
interesting to give it an optional grace period to let the Xserver
running for a little longer in case a new connection occurs.
This adds an optional parameter to the "-terminate" command line option
for this purpose.
v2: Use a delay in seconds instead of milliseconds
(Martin Peres <martin.peres@mupuf.org>)
v3: Clarify man page entry, ensure terminateDelay is always >= 0,
simplify TimerFree(). (Peter Hutterer <peter.hutterer@who-t.net>)
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
With Wayland compositors now being able to start Xwayland on demand, the
next logical step is to be able to stop Xwayland when there is no more
need for it.
The Xserver itself is capable of terminating itself once all X11 clients
are gone, yet in a typical full session, there are a number of X11
clients running continuously (e.g. the Xsettings daemon, IBus, etc.).
Those always-running clients will prevent the Xserver from terminating,
because the actual number of X11 clients will never drop to 0. Worse,
the X11 window manager of a Wayland compositor also counts as an X11
client, hence also preventing Xwayland from stopping.
Some compositors such as mutter use the XRes extension to query the X11
clients connected, match their PID with the actual executable name and
compare those with a list of executables that can be ignored when
deciding to kill the Xserver.
But that's not just clumsy, it is also racy, because a new X11 client
might initiate a connection the X11 server right when the compositor is
about to kill it.
To solve this issue directly at the Xserver level, this add new entries
to the XFixes extension to let the X11 clients themselves specify the
disconnect mode they expect.
Typically, those X11 daemon clients would specify the disconnect mode
XFixesClientDisconnectFlagTerminate to let the Xserver know that they
should not be accounted for when checking the remaining clients prior
to terminate.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This fixes an problem left in f682e0563f
due to an incorrect cherry-pick.
We must use old listener->listener to deliver the touch event. Otherwise
grab won't let the event through and the abovementioned commit has no
effect.
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
Trying to change the pointer control settings on a device without
PtrFeedbackPtr would be a bug and a crash in the Xserver.
Guard against that case by returning early with a BadImplementation
error, that might kill the X11 client but the Xserver would survive.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1137
This add a new flag POINTER_RAWONLY for GetPointerEvents() which does
pretty much the opposite of POINTER_NORAW.
Basically, this tells GetPointerEvents() that we only want the
DeviceChanged events and any raw events for this motion but no actual
motion events.
This is preliminary work for Xwayland to be able to use relative motion
events for raw events. Xwayland would use absolute events for raw
events, but some X11 clients (wrongly) assume raw events to be always
relative.
To allow such clients to work with Xwayland, it needs to switch to
relative raw events (if those are available from the Wayland
compositor).
However, Xwayland cannot use relative motion events for actual pointer
location because that would cause a drift over time, the pointer being
actually controlled by the Wayland compositor.
So Xwayland needs to be able to send only relative raw events, hence
this API.
Bump the ABI_XINPUT_VERSION minor version to reflect that API addition.
v2: Actually avoid sending motion events (Peter)
v3: Keep sending raw emulated events with RAWONLY (Peter)
Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
If a XI2 client started listening to touches due to a selection and then
creates an active async grab that does not include touch events, then it
currently won't get the touch end event which will produce inconsistent
view of the pending touches.
Note that we only need to consider touch listeners and can ignore
pointer emulation. Under XI2 if a active grab replaces a passive
implicit grab and the active grab does not include the button release
event, the client won't get it either.