Commits:
-
d755da58
by Warren Togami at 2024-02-08T17:06:09+01:00
xwayland: Ensure pointer for gestures has buttons
X11 clients tend to assume that pointers have buttons. This
assumption means they often fail to handle the X error that
is generated when querying the button mapping of a pointer
device that lacks buttons.
This failure to handle the X error leads to those client
applications to abruptly exit.
This commit assigns vestigial buttons to the gesture pointer
device for the sole purpose of backward compatibility with
legacy X11 clients.
That technique is already employed for a different pointer,
the relative pointer device, for similar reasons, so this
just makes the legacy client compatibility more complete.
See https://gitlab.gnome.org/GNOME/mutter/-/issues/2353
(cherry picked from commit 456b0e86bb25bee8ca5ab8cae18f88d0d0731bfb)
-
4c8de123
by Peter Hutterer at 2024-04-02T10:06:12+02:00
dix: fix valuator copy/paste error in the DeviceStateNotify event
Fixes 219c54b8a3337456ce5270ded6a67bcde53553d5
(cherry picked from commit 133e0d651c5d12bf01999d6289e84e224ba77adc)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1452>
-
bd16cc83
by Alan Coopersmith at 2024-04-03T08:33:35-07:00
Xi: ProcXIGetSelectedEvents needs to use unswapped length to send reply
CVE-2024-31080
Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 96798fc1967491c80a4d0c8d9e0a80586cb2152b)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1464>
-
672b26d1
by Alan Coopersmith at 2024-04-03T08:34:02-07:00
Xi: ProcXIPassiveGrabDevice needs to use unswapped length to send reply
CVE-2024-31081
Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 3e77295f888c67fc7645db5d0c00926a29ffecee)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1464>
-
01941a83
by Peter Hutterer at 2024-04-03T08:36:39-07:00
render: fix refcounting of glyphs during ProcRenderAddGlyphs
Previously, AllocateGlyph would return a new glyph with refcount=0 and a
re-used glyph would end up not changing the refcount at all. The
resulting glyph_new array would thus have multiple entries pointing to
the same non-refcounted glyphs.
AddGlyph may free a glyph, resulting in a UAF when the same glyph
pointer is then later used.
Fix this by returning a refcount of 1 for a new glyph and always
incrementing the refcount for a re-used glyph, followed by dropping that
refcount back down again when we're done with it.
CVE-2024-31083, ZDI-CAN-22880
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
(backported from commit bdca6c3d1f5057eeb31609b1280fc93237b00c77)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1464>
-
28cfd2f9
by Olivier Fourdan at 2024-04-03T17:57:56+02:00
Bump version to 23.2.5
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1465>
-
f69899a4
by Florian Weimer at 2024-04-04T13:58:32+10:00
xwayland: Use correct pointer types on i386
And other 32-bit architectures, where uint32_t and CARD32 are
not the same type. Otherwise the build will fail with GCC 14
with errors like:
../hw/xwayland/xwayland-glamor.c: In function ‘xwl_glamor_get_formats’:
../hw/xwayland/xwayland-glamor.c:291:43: error: passing argument 3 of ‘xwl_get_formats_for_device’ from incompatible pointer type [-Wincompatible-pointer-types]
291 | num_formats, formats);
| ^~~~~~~~~~~
| |
| CARD32 * {aka long unsigned int *}
../hw/xwayland/xwayland-glamor.c:238:38: note: expected ‘uint32_t *’ {aka ‘unsigned int *’} but argument is of type ‘CARD32 *’ {aka ‘long unsigned int *’}
238 | uint32_t *num_formats, uint32_t **formats)
| ~~~~~~~~~~^~~~~~~~~~~
../hw/xwayland/xwayland-glamor.c:291:56: error: passing argument 4 of ‘xwl_get_formats_for_device’ from incompatible pointer type [-Wincompatible-pointer-types]
291 | num_formats, formats);
| ^~~~~~~
| |
| CARD32 ** {aka long unsigned int **}
../hw/xwayland/xwayland-glamor.c:238:62: note: expected ‘uint32_t **’ {aka ‘unsigned int **’} but argument is of type ‘CARD32 **’ {aka ‘long unsigned int **’}
238 | uint32_t *num_formats, uint32_t **formats)
| ~~~~~~~~~~~^~~~~~~
../hw/xwayland/xwayland-glamor.c:295:28: error: passing argument 3 of ‘xwl_get_formats’ from incompatible pointer type [-Wincompatible-pointer-types]
295 | num_formats, formats);
| ^~~~~~~~~~~
| |
| CARD32 * {aka long unsigned int *}
../hw/xwayland/xwayland-glamor.c:217:26: note: expected ‘uint32_t *’ {aka ‘unsigned int *’} but argument is of type ‘CARD32 *’ {aka ‘long unsigned int *’}
217 | uint32_t *num_formats, uint32_t **formats)
| ~~~~~~~~~~^~~~~~~~~~~
../hw/xwayland/xwayland-glamor.c:295:41: error: passing argument 4 of ‘xwl_get_formats’ from incompatible pointer type [-Wincompatible-pointer-types]
295 | num_formats, formats);
| ^~~~~~~
| |
| CARD32 ** {aka long unsigned int **}
../hw/xwayland/xwayland-glamor.c:217:50: note: expected ‘uint32_t **’ {aka ‘unsigned int **’} but argument is of type ‘CARD32 **’ {aka ‘long unsigned int **’}
217 | uint32_t *num_formats, uint32_t **formats)
| ~~~~~~~~~~~^~~~~~~
(cherry picked from commit f0a187f55d76139225c11ce92ab69816d46db55c)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1470>
-
c3c2218a
by Olivier Fourdan at 2024-04-09T09:19:00+02:00
render: Avoid possible double-free in ProcRenderAddGlyphs()
ProcRenderAddGlyphs() adds the glyph to the glyphset using AddGlyph() and
then frees it using FreeGlyph() to decrease the reference count, after
AddGlyph() has increased it.
AddGlyph() however may chose to reuse an existing glyph if it's already
in the glyphSet, and free the glyph that was given, in which case the
caller function, ProcRenderAddGlyphs() will call FreeGlyph() on an
already freed glyph, as reported by ASan:
READ of size 4 thread T0
#0 in FreeGlyph xserver/render/glyph.c:252
#1 in ProcRenderAddGlyphs xserver/render/render.c:1174
#2 in Dispatch xserver/dix/dispatch.c:546
#3 in dix_main xserver/dix/main.c:271
#4 in main xserver/dix/stubmain.c:34
#5 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#6 in __libc_start_main_impl ../csu/libc-start.c:360
#7 (/usr/bin/Xwayland+0x44fe4)
Address is located 0 bytes inside of 64-byte region
freed by thread T0 here:
#0 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:52
#1 in _dixFreeObjectWithPrivates xserver/dix/privates.c:538
#2 in AddGlyph xserver/render/glyph.c:295
#3 in ProcRenderAddGlyphs xserver/render/render.c:1173
#4 in Dispatch xserver/dix/dispatch.c:546
#5 in dix_main xserver/dix/main.c:271
#6 in main xserver/dix/stubmain.c:34
#7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
previously allocated by thread T0 here:
#0 in __interceptor_malloc libsanitizer/asan/asan_malloc_linux.cpp:69
#1 in AllocateGlyph xserver/render/glyph.c:355
#2 in ProcRenderAddGlyphs xserver/render/render.c:1085
#3 in Dispatch xserver/dix/dispatch.c:546
#4 in dix_main xserver/dix/main.c:271
#5 in main xserver/dix/stubmain.c:34
#6 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-use-after-free xserver/render/glyph.c:252 in FreeGlyph
To avoid that, make sure not to free the given glyph in AddGlyph().
v2: Simplify the test using the boolean returned from AddGlyph() (Michel)
v3: Simplify even more by not freeing the glyph in AddGlyph() (Peter)
Fixes: bdca6c3d1 - render: fix refcounting of glyphs during ProcRenderAddGlyphs
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1659
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 337d8d48b618d4fc0168a7b978be4c3447650b04)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1478>
-
db9cde03
by Olivier Fourdan at 2024-04-09T11:23:44+02:00
Bump version to 23.2.6
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1480>
9 changed files:
Changes:
Xi/xipassivegrab.c
... |
... |
@@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client) |
93
|
93
|
GrabParameters param;
|
94
|
94
|
void *tmp;
|
95
|
95
|
int mask_len;
|
|
96
|
+ uint32_t length;
|
96
|
97
|
|
97
|
98
|
REQUEST(xXIPassiveGrabDeviceReq);
|
98
|
99
|
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
|
... |
... |
@@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client) |
247
|
248
|
}
|
248
|
249
|
}
|
249
|
250
|
|
|
251
|
+ /* save the value before SRepXIPassiveGrabDevice swaps it */
|
|
252
|
+ length = rep.length;
|
250
|
253
|
WriteReplyToClient(client, sizeof(rep), &rep);
|
251
|
254
|
if (rep.num_modifiers)
|
252
|
|
- WriteToClient(client, rep.length * 4, modifiers_failed);
|
|
255
|
+ WriteToClient(client, length * 4, modifiers_failed);
|
253
|
256
|
|
254
|
257
|
out:
|
255
|
258
|
free(modifiers_failed);
|
Xi/xiselectev.c
... |
... |
@@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client) |
349
|
349
|
InputClientsPtr others = NULL;
|
350
|
350
|
xXIEventMask *evmask = NULL;
|
351
|
351
|
DeviceIntPtr dev;
|
|
352
|
+ uint32_t length;
|
352
|
353
|
|
353
|
354
|
REQUEST(xXIGetSelectedEventsReq);
|
354
|
355
|
REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
|
... |
... |
@@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client) |
418
|
419
|
}
|
419
|
420
|
}
|
420
|
421
|
|
|
422
|
+ /* save the value before SRepXIGetSelectedEvents swaps it */
|
|
423
|
+ length = reply.length;
|
421
|
424
|
WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
|
422
|
425
|
|
423
|
426
|
if (reply.num_masks)
|
424
|
|
- WriteToClient(client, reply.length * 4, buffer);
|
|
427
|
+ WriteToClient(client, length * 4, buffer);
|
425
|
428
|
|
426
|
429
|
free(buffer);
|
427
|
430
|
return Success;
|
dix/enterleave.c
... |
... |
@@ -619,11 +619,11 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, |
619
|
619
|
ev->first_valuator = first;
|
620
|
620
|
switch (ev->num_valuators) {
|
621
|
621
|
case 6:
|
622
|
|
- ev->valuator2 = v->axisVal[first + 5];
|
|
622
|
+ ev->valuator5 = v->axisVal[first + 5];
|
623
|
623
|
case 5:
|
624
|
|
- ev->valuator2 = v->axisVal[first + 4];
|
|
624
|
+ ev->valuator4 = v->axisVal[first + 4];
|
625
|
625
|
case 4:
|
626
|
|
- ev->valuator2 = v->axisVal[first + 3];
|
|
626
|
+ ev->valuator3 = v->axisVal[first + 3];
|
627
|
627
|
case 3:
|
628
|
628
|
ev->valuator2 = v->axisVal[first + 2];
|
629
|
629
|
case 2:
|
hw/xwayland/xwayland-glamor.c
... |
... |
@@ -214,7 +214,7 @@ xwl_screen_get_main_dev(struct xwl_screen *xwl_screen) |
214
|
214
|
|
215
|
215
|
static Bool
|
216
|
216
|
xwl_get_formats(struct xwl_format *format_array, int format_array_len,
|
217
|
|
- uint32_t *num_formats, uint32_t **formats)
|
|
217
|
+ CARD32 *num_formats, CARD32 **formats)
|
218
|
218
|
{
|
219
|
219
|
*num_formats = 0;
|
220
|
220
|
*formats = NULL;
|
... |
... |
@@ -235,9 +235,9 @@ xwl_get_formats(struct xwl_format *format_array, int format_array_len, |
235
|
235
|
|
236
|
236
|
static Bool
|
237
|
237
|
xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, drmDevice *device,
|
238
|
|
- uint32_t *num_formats, uint32_t **formats)
|
|
238
|
+ CARD32 *num_formats, CARD32 **formats)
|
239
|
239
|
{
|
240
|
|
- uint32_t *ret = NULL;
|
|
240
|
+ CARD32 *ret = NULL;
|
241
|
241
|
uint32_t count = 0;
|
242
|
242
|
|
243
|
243
|
/* go through all matching sets of tranches for the window's device */
|
hw/xwayland/xwayland-input.c
... |
... |
@@ -313,6 +313,13 @@ xwl_pointer_proc_pointer_gestures(DeviceIntPtr device, int what) |
313
|
313
|
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
|
314
|
314
|
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
315
|
315
|
|
|
316
|
+ /*
|
|
317
|
+ * We'll never send buttons, but XGetPointerMapping might in certain
|
|
318
|
+ * situations make the client think we have no buttons.
|
|
319
|
+ */
|
|
320
|
+ if (!init_pointer_buttons(device))
|
|
321
|
+ return BadValue;
|
|
322
|
+
|
316
|
323
|
if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
|
317
|
324
|
GetMotionHistorySize(), Relative))
|
318
|
325
|
return BadValue;
|
meson.build
... |
... |
@@ -3,10 +3,10 @@ project('xwayland', 'c', |
3
|
3
|
'buildtype=debugoptimized',
|
4
|
4
|
'c_std=gnu99',
|
5
|
5
|
],
|
6
|
|
- version: '23.2.4',
|
|
6
|
+ version: '23.2.6',
|
7
|
7
|
meson_version: '>= 0.52.0',
|
8
|
8
|
)
|
9
|
|
-release_date = '2024-01-16'
|
|
9
|
+release_date = '2024-04-09'
|
10
|
10
|
|
11
|
11
|
add_project_arguments('-DHAVE_DIX_CONFIG_H', language: ['c', 'objc'])
|
12
|
12
|
cc = meson.get_compiler('c')
|
render/glyph.c
... |
... |
@@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph) |
245
|
245
|
}
|
246
|
246
|
}
|
247
|
247
|
|
248
|
|
-static void
|
|
248
|
+void
|
249
|
249
|
FreeGlyph(GlyphPtr glyph, int format)
|
250
|
250
|
{
|
251
|
251
|
CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
|
|
252
|
+ BUG_RETURN(glyph->refcnt == 0);
|
252
|
253
|
if (--glyph->refcnt == 0) {
|
253
|
254
|
GlyphRefPtr gr;
|
254
|
255
|
int i;
|
... |
... |
@@ -290,8 +291,6 @@ AddGlyph(GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) |
290
|
291
|
gr = FindGlyphRef(&globalGlyphs[glyphSet->fdepth], signature,
|
291
|
292
|
TRUE, glyph->sha1);
|
292
|
293
|
if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) {
|
293
|
|
- FreeGlyphPicture(glyph);
|
294
|
|
- dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH);
|
295
|
294
|
glyph = gr->glyph;
|
296
|
295
|
}
|
297
|
296
|
else if (gr->glyph != glyph) {
|
... |
... |
@@ -354,7 +353,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth) |
354
|
353
|
glyph = (GlyphPtr) malloc(size);
|
355
|
354
|
if (!glyph)
|
356
|
355
|
return 0;
|
357
|
|
- glyph->refcnt = 0;
|
|
356
|
+ glyph->refcnt = 1;
|
358
|
357
|
glyph->size = size + sizeof(xGlyphInfo);
|
359
|
358
|
glyph->info = *gi;
|
360
|
359
|
dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);
|
render/glyphstr.h
... |
... |
@@ -102,6 +102,9 @@ HashGlyph(xGlyphInfo * gi, |
102
|
102
|
extern void
|
103
|
103
|
AddGlyph(GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
|
104
|
104
|
|
|
105
|
+extern void
|
|
106
|
+FreeGlyph(GlyphPtr glyph, int format);
|
|
107
|
+
|
105
|
108
|
extern Bool
|
106
|
109
|
DeleteGlyph(GlyphSetPtr glyphSet, Glyph id);
|
107
|
110
|
|
render/render.c
... |
... |
@@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client) |
1076
|
1076
|
|
1077
|
1077
|
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
|
1078
|
1078
|
glyph_new->found = TRUE;
|
|
1079
|
+ ++glyph_new->glyph->refcnt;
|
1079
|
1080
|
}
|
1080
|
1081
|
else {
|
1081
|
1082
|
GlyphPtr glyph;
|
... |
... |
@@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client) |
1168
|
1169
|
err = BadAlloc;
|
1169
|
1170
|
goto bail;
|
1170
|
1171
|
}
|
1171
|
|
- for (i = 0; i < nglyphs; i++)
|
|
1172
|
+ for (i = 0; i < nglyphs; i++) {
|
1172
|
1173
|
AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
|
|
1174
|
+ FreeGlyph(glyphs[i].glyph, glyphSet->fdepth);
|
|
1175
|
+ }
|
1173
|
1176
|
|
1174
|
1177
|
if (glyphsBase != glyphsLocal)
|
1175
|
1178
|
free(glyphsBase);
|
... |
... |
@@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client) |
1179
|
1182
|
FreePicture((void *) pSrc, 0);
|
1180
|
1183
|
if (pSrcPix)
|
1181
|
1184
|
FreeScratchPixmapHeader(pSrcPix);
|
1182
|
|
- for (i = 0; i < nglyphs; i++)
|
1183
|
|
- if (glyphs[i].glyph && !glyphs[i].found)
|
1184
|
|
- free(glyphs[i].glyph);
|
|
1185
|
+ for (i = 0; i < nglyphs; i++) {
|
|
1186
|
+ if (glyphs[i].glyph) {
|
|
1187
|
+ --glyphs[i].glyph->refcnt;
|
|
1188
|
+ if (!glyphs[i].found)
|
|
1189
|
+ free(glyphs[i].glyph);
|
|
1190
|
+ }
|
|
1191
|
+ }
|
1185
|
1192
|
if (glyphsBase != glyphsLocal)
|
1186
|
1193
|
free(glyphsBase);
|
1187
|
1194
|
return err;
|
|