diff options
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.patch | 221 |
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 @@ | |||
1 | From 219c54b8a3337456ce5270ded6a67bcde53553d5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Mon, 18 Dec 2023 12:26:20 +1000 | ||
4 | Subject: [PATCH] dix: fix DeviceStateNotify event calculation | ||
5 | |||
6 | The previous code only made sense if one considers buttons and keys to | ||
7 | be mutually exclusive on a device. That is not necessarily true, causing | ||
8 | a number of issues. | ||
9 | |||
10 | This function allocates and fills in the number of xEvents we need to | ||
11 | send the device state down the wire. This is split across multiple | ||
12 | 32-byte devices including one deviceStateNotify event and optional | ||
13 | deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple) | ||
14 | deviceValuator events. | ||
15 | |||
16 | The previous behavior would instead compose a sequence | ||
17 | of [state, buttonstate, state, keystate, valuator...]. This is not | ||
18 | protocol correct, and on top of that made the code extremely convoluted. | ||
19 | |||
20 | Fix this by streamlining: add both button and key into the deviceStateNotify | ||
21 | and then append the key state and button state, followed by the | ||
22 | valuators. Finally, the deviceValuator events contain up to 6 valuators | ||
23 | per event but we only ever sent through 3 at a time. Let's double that | ||
24 | troughput. | ||
25 | |||
26 | CVE-2024-0229, ZDI-CAN-22678 | ||
27 | |||
28 | This vulnerability was discovered by: | ||
29 | Jan-Niklas Sohn working with Trend Micro Zero Day Initiative | ||
30 | |||
31 | Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/219c54b8a3337456ce5270ded6a67bcde53553d5] | ||
32 | CVE: CVE-2024-0229 | ||
33 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
34 | --- | ||
35 | dix/enterleave.c | 121 ++++++++++++++++++++--------------------------- | ||
36 | 1 file changed, 52 insertions(+), 69 deletions(-) | ||
37 | |||
38 | diff --git a/dix/enterleave.c b/dix/enterleave.c | ||
39 | index 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 | -- | ||
220 | GitLab | ||
221 | |||