summaryrefslogtreecommitdiffstats
path: root/meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch')
-rw-r--r--meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch221
1 files changed, 221 insertions, 0 deletions
diff --git a/meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch b/meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch
new file mode 100644
index 0000000000..65df74376b
--- /dev/null
+++ b/meta/recipes-graphics/xorg-xserver/xserver-xorg/CVE-2024-0229-2.patch
@@ -0,0 +1,221 @@
1From 219c54b8a3337456ce5270ded6a67bcde53553d5 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Mon, 18 Dec 2023 12:26:20 +1000
4Subject: [PATCH] dix: fix DeviceStateNotify event calculation
5
6The previous code only made sense if one considers buttons and keys to
7be mutually exclusive on a device. That is not necessarily true, causing
8a number of issues.
9
10This function allocates and fills in the number of xEvents we need to
11send the device state down the wire. This is split across multiple
1232-byte devices including one deviceStateNotify event and optional
13deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple)
14deviceValuator events.
15
16The previous behavior would instead compose a sequence
17of [state, buttonstate, state, keystate, valuator...]. This is not
18protocol correct, and on top of that made the code extremely convoluted.
19
20Fix this by streamlining: add both button and key into the deviceStateNotify
21and then append the key state and button state, followed by the
22valuators. Finally, the deviceValuator events contain up to 6 valuators
23per event but we only ever sent through 3 at a time. Let's double that
24troughput.
25
26CVE-2024-0229, ZDI-CAN-22678
27
28This vulnerability was discovered by:
29Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
30
31Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/219c54b8a3337456ce5270ded6a67bcde53553d5]
32CVE: CVE-2024-0229
33Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
34---
35 dix/enterleave.c | 121 ++++++++++++++++++++---------------------------
36 1 file changed, 52 insertions(+), 69 deletions(-)
37
38diff --git a/dix/enterleave.c b/dix/enterleave.c
39index 17964b00a4..7b7ba1098b 100644
40--- a/dix/enterleave.c
41+++ b/dix/enterleave.c
42@@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
43
44 ev->type = DeviceValuator;
45 ev->deviceid = dev->id;
46- ev->num_valuators = nval < 3 ? nval : 3;
47+ ev->num_valuators = nval < 6 ? nval : 6;
48 ev->first_valuator = first;
49 switch (ev->num_valuators) {
50+ case 6:
51+ ev->valuator2 = v->axisVal[first + 5];
52+ case 5:
53+ ev->valuator2 = v->axisVal[first + 4];
54+ case 4:
55+ ev->valuator2 = v->axisVal[first + 3];
56 case 3:
57 ev->valuator2 = v->axisVal[first + 2];
58 case 2:
59@@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
60 ev->valuator0 = v->axisVal[first];
61 break;
62 }
63- first += ev->num_valuators;
64 }
65
66 static void
67@@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
68 ev->num_buttons = b->numButtons;
69 memcpy((char *) ev->buttons, (char *) b->down, 4);
70 }
71- else if (k) {
72+ if (k) {
73 ev->classes_reported |= (1 << KeyClass);
74 ev->num_keys = k->xkbInfo->desc->max_key_code -
75 k->xkbInfo->desc->min_key_code;
76@@ -670,15 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
77 }
78 }
79
80-
81+/**
82+ * The device state notify event is split across multiple 32-byte events.
83+ * The first one contains the first 32 button state bits, the first 32
84+ * key state bits, and the first 3 valuator values.
85+ *
86+ * If a device has more than that, the server sends out:
87+ * - one deviceButtonStateNotify for buttons 32 and above
88+ * - one deviceKeyStateNotify for keys 32 and above
89+ * - one deviceValuator event per 6 valuators above valuator 4
90+ *
91+ * All events but the last one have the deviceid binary ORed with MORE_EVENTS,
92+ */
93 static void
94 DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
95 {
96+ /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
97+ * and one deviceValuator for each 6 valuators */
98+ deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
99 int evcount = 1;
100- deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
101- deviceStateNotify *ev;
102- deviceKeyStateNotify *kev;
103- deviceButtonStateNotify *bev;
104+ deviceStateNotify *ev = sev;
105
106 KeyClassPtr k;
107 ButtonClassPtr b;
108@@ -691,82 +707,49 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
109
110 if ((b = dev->button) != NULL) {
111 nbuttons = b->numButtons;
112- if (nbuttons > 32)
113+ if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
114 evcount++;
115 }
116 if ((k = dev->key) != NULL) {
117 nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
118- if (nkeys > 32)
119+ if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
120 evcount++;
121- if (nbuttons > 0) {
122- evcount++;
123- }
124 }
125 if ((v = dev->valuator) != NULL) {
126 nval = v->numAxes;
127-
128- if (nval > 3)
129- evcount++;
130- if (nval > 6) {
131- if (!(k && b))
132- evcount++;
133- if (nval > 9)
134- evcount += ((nval - 7) / 3);
135- }
136+ /* first three are encoded in deviceStateNotify, then
137+ * it's 6 per deviceValuator event */
138+ evcount += ((nval - 3) + 6)/6;
139 }
140
141- ev = sev;
142- FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
143-
144- if (b != NULL) {
145- FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
146- first += 3;
147- nval -= 3;
148- if (nbuttons > 32) {
149- (ev - 1)->deviceid |= MORE_EVENTS;
150- bev = (deviceButtonStateNotify *) ev++;
151- bev->type = DeviceButtonStateNotify;
152- bev->deviceid = dev->id;
153- memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
154- DOWN_LENGTH - 4);
155- }
156- if (nval > 0) {
157- (ev - 1)->deviceid |= MORE_EVENTS;
158- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
159- first += 3;
160- nval -= 3;
161- }
162+ BUG_RETURN(evcount <= ARRAY_SIZE(sev));
163+
164+ FixDeviceStateNotify(dev, ev, k, b, v, first);
165+
166+ if (b != NULL && nbuttons > 32) {
167+ deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
168+ (ev - 1)->deviceid |= MORE_EVENTS;
169+ bev->type = DeviceButtonStateNotify;
170+ bev->deviceid = dev->id;
171+ memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
172+ DOWN_LENGTH - 4);
173 }
174
175- if (k != NULL) {
176- FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
177- first += 3;
178- nval -= 3;
179- if (nkeys > 32) {
180- (ev - 1)->deviceid |= MORE_EVENTS;
181- kev = (deviceKeyStateNotify *) ev++;
182- kev->type = DeviceKeyStateNotify;
183- kev->deviceid = dev->id;
184- memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
185- }
186- if (nval > 0) {
187- (ev - 1)->deviceid |= MORE_EVENTS;
188- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
189- first += 3;
190- nval -= 3;
191- }
192+ if (k != NULL && nkeys > 32) {
193+ deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
194+ (ev - 1)->deviceid |= MORE_EVENTS;
195+ kev->type = DeviceKeyStateNotify;
196+ kev->deviceid = dev->id;
197+ memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
198 }
199
200+ first = 3;
201+ nval -= 3;
202 while (nval > 0) {
203- FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
204- first += 3;
205- nval -= 3;
206- if (nval > 0) {
207- (ev - 1)->deviceid |= MORE_EVENTS;
208- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
209- first += 3;
210- nval -= 3;
211- }
212+ ev->deviceid |= MORE_EVENTS;
213+ FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
214+ first += 6;
215+ nval -= 6;
216 }
217
218 DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
219--
220GitLab
221