diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-graphics/xorg-lib/libxrandr/CVE-2016-7947_CVE-2016-7948.patch | 439 | ||||
-rw-r--r-- | meta/recipes-graphics/xorg-lib/libxrandr_1.5.0.bb | 3 |
2 files changed, 442 insertions, 0 deletions
diff --git a/meta/recipes-graphics/xorg-lib/libxrandr/CVE-2016-7947_CVE-2016-7948.patch b/meta/recipes-graphics/xorg-lib/libxrandr/CVE-2016-7947_CVE-2016-7948.patch new file mode 100644 index 0000000000..a9b3dbc658 --- /dev/null +++ b/meta/recipes-graphics/xorg-lib/libxrandr/CVE-2016-7947_CVE-2016-7948.patch | |||
@@ -0,0 +1,439 @@ | |||
1 | From a0df3e1c7728205e5c7650b2e6dce684139254a6 Mon Sep 17 00:00:00 2001 | ||
2 | From: Tobias Stoeckmann <tobias@stoeckmann.org> | ||
3 | Date: Sun, 25 Sep 2016 22:21:40 +0200 | ||
4 | Subject: Avoid out of boundary accesses on illegal responses | ||
5 | |||
6 | The responses of the connected X server have to be properly checked | ||
7 | to avoid out of boundary accesses that could otherwise be triggered | ||
8 | by a malicious server. | ||
9 | |||
10 | CVE: CVE-2016-7947 | ||
11 | libXrandr: Insufficient validation of server responses result in Integer overflows | ||
12 | |||
13 | CVE: CVE-2016-7948 | ||
14 | libXrandr: Insufficient validation of server responses result in various data mishandlings | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | |||
18 | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> | ||
19 | Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> | ||
20 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
21 | |||
22 | diff --git a/src/XrrConfig.c b/src/XrrConfig.c | ||
23 | index 2f0282b..e68c45a 100644 | ||
24 | --- a/src/XrrConfig.c | ||
25 | +++ b/src/XrrConfig.c | ||
26 | @@ -29,6 +29,7 @@ | ||
27 | #include <config.h> | ||
28 | #endif | ||
29 | |||
30 | +#include <limits.h> | ||
31 | #include <stdio.h> | ||
32 | #include <X11/Xlib.h> | ||
33 | /* we need to be able to manipulate the Display structure on events */ | ||
34 | @@ -272,23 +273,30 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, | ||
35 | rep.rate = 0; | ||
36 | rep.nrateEnts = 0; | ||
37 | } | ||
38 | + if (rep.length < INT_MAX >> 2) { | ||
39 | + nbytes = (long) rep.length << 2; | ||
40 | |||
41 | - nbytes = (long) rep.length << 2; | ||
42 | + nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + | ||
43 | + ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF(CARD16) */); | ||
44 | |||
45 | - nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + | ||
46 | - ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */); | ||
47 | + /* | ||
48 | + * first we must compute how much space to allocate for | ||
49 | + * randr library's use; we'll allocate the structures in a single | ||
50 | + * allocation, on cleanlyness grounds. | ||
51 | + */ | ||
52 | |||
53 | - /* | ||
54 | - * first we must compute how much space to allocate for | ||
55 | - * randr library's use; we'll allocate the structures in a single | ||
56 | - * allocation, on cleanlyness grounds. | ||
57 | - */ | ||
58 | + rbytes = sizeof (XRRScreenConfiguration) + | ||
59 | + (rep.nSizes * sizeof (XRRScreenSize) + | ||
60 | + rep.nrateEnts * sizeof (int)); | ||
61 | |||
62 | - rbytes = sizeof (XRRScreenConfiguration) + | ||
63 | - (rep.nSizes * sizeof (XRRScreenSize) + | ||
64 | - rep.nrateEnts * sizeof (int)); | ||
65 | + scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); | ||
66 | + } else { | ||
67 | + nbytes = 0; | ||
68 | + nbytesRead = 0; | ||
69 | + rbytes = 0; | ||
70 | + scp = NULL; | ||
71 | + } | ||
72 | |||
73 | - scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); | ||
74 | if (scp == NULL) { | ||
75 | _XEatData (dpy, (unsigned long) nbytes); | ||
76 | return NULL; | ||
77 | diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c | ||
78 | index 5ae35c5..6665092 100644 | ||
79 | --- a/src/XrrCrtc.c | ||
80 | +++ b/src/XrrCrtc.c | ||
81 | @@ -24,6 +24,7 @@ | ||
82 | #include <config.h> | ||
83 | #endif | ||
84 | |||
85 | +#include <limits.h> | ||
86 | #include <stdio.h> | ||
87 | #include <X11/Xlib.h> | ||
88 | /* we need to be able to manipulate the Display structure on events */ | ||
89 | @@ -57,22 +58,33 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc) | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
93 | - nbytes = (long) rep.length << 2; | ||
94 | + if (rep.length < INT_MAX >> 2) | ||
95 | + { | ||
96 | + nbytes = (long) rep.length << 2; | ||
97 | |||
98 | - nbytesRead = (long) (rep.nOutput * 4 + | ||
99 | - rep.nPossibleOutput * 4); | ||
100 | + nbytesRead = (long) (rep.nOutput * 4 + | ||
101 | + rep.nPossibleOutput * 4); | ||
102 | |||
103 | - /* | ||
104 | - * first we must compute how much space to allocate for | ||
105 | - * randr library's use; we'll allocate the structures in a single | ||
106 | - * allocation, on cleanlyness grounds. | ||
107 | - */ | ||
108 | + /* | ||
109 | + * first we must compute how much space to allocate for | ||
110 | + * randr library's use; we'll allocate the structures in a single | ||
111 | + * allocation, on cleanlyness grounds. | ||
112 | + */ | ||
113 | |||
114 | - rbytes = (sizeof (XRRCrtcInfo) + | ||
115 | - rep.nOutput * sizeof (RROutput) + | ||
116 | - rep.nPossibleOutput * sizeof (RROutput)); | ||
117 | + rbytes = (sizeof (XRRCrtcInfo) + | ||
118 | + rep.nOutput * sizeof (RROutput) + | ||
119 | + rep.nPossibleOutput * sizeof (RROutput)); | ||
120 | + | ||
121 | + xci = (XRRCrtcInfo *) Xmalloc(rbytes); | ||
122 | + } | ||
123 | + else | ||
124 | + { | ||
125 | + nbytes = 0; | ||
126 | + nbytesRead = 0; | ||
127 | + rbytes = 0; | ||
128 | + xci = NULL; | ||
129 | + } | ||
130 | |||
131 | - xci = (XRRCrtcInfo *) Xmalloc(rbytes); | ||
132 | if (xci == NULL) { | ||
133 | _XEatDataWords (dpy, rep.length); | ||
134 | UnlockDisplay (dpy); | ||
135 | @@ -194,12 +206,21 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc crtc) | ||
136 | if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) | ||
137 | goto out; | ||
138 | |||
139 | - nbytes = (long) rep.length << 2; | ||
140 | + if (rep.length < INT_MAX >> 2) | ||
141 | + { | ||
142 | + nbytes = (long) rep.length << 2; | ||
143 | |||
144 | - /* three channels of CARD16 data */ | ||
145 | - nbytesRead = (rep.size * 2 * 3); | ||
146 | + /* three channels of CARD16 data */ | ||
147 | + nbytesRead = (rep.size * 2 * 3); | ||
148 | |||
149 | - crtc_gamma = XRRAllocGamma (rep.size); | ||
150 | + crtc_gamma = XRRAllocGamma (rep.size); | ||
151 | + } | ||
152 | + else | ||
153 | + { | ||
154 | + nbytes = 0; | ||
155 | + nbytesRead = 0; | ||
156 | + crtc_gamma = NULL; | ||
157 | + } | ||
158 | |||
159 | if (!crtc_gamma) | ||
160 | { | ||
161 | @@ -357,7 +378,7 @@ XRRGetCrtcTransform (Display *dpy, | ||
162 | xRRGetCrtcTransformReq *req; | ||
163 | int major_version, minor_version; | ||
164 | XRRCrtcTransformAttributes *attr; | ||
165 | - char *extra = NULL, *e; | ||
166 | + char *extra = NULL, *end = NULL, *e; | ||
167 | int p; | ||
168 | |||
169 | *attributes = NULL; | ||
170 | @@ -395,9 +416,17 @@ XRRGetCrtcTransform (Display *dpy, | ||
171 | else | ||
172 | { | ||
173 | int extraBytes = rep.length * 4 - CrtcTransformExtra; | ||
174 | - extra = Xmalloc (extraBytes); | ||
175 | + if (rep.length < INT_MAX / 4 && | ||
176 | + rep.length * 4 >= CrtcTransformExtra) { | ||
177 | + extra = Xmalloc (extraBytes); | ||
178 | + end = extra + extraBytes; | ||
179 | + } else | ||
180 | + extra = NULL; | ||
181 | if (!extra) { | ||
182 | - _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); | ||
183 | + if (rep.length > (CrtcTransformExtra >> 2)) | ||
184 | + _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); | ||
185 | + else | ||
186 | + _XEatDataWords (dpy, rep.length); | ||
187 | UnlockDisplay (dpy); | ||
188 | SyncHandle (); | ||
189 | return False; | ||
190 | @@ -429,22 +458,38 @@ XRRGetCrtcTransform (Display *dpy, | ||
191 | |||
192 | e = extra; | ||
193 | |||
194 | + if (e + rep.pendingNbytesFilter > end) { | ||
195 | + XFree (extra); | ||
196 | + return False; | ||
197 | + } | ||
198 | memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter); | ||
199 | attr->pendingFilter[rep.pendingNbytesFilter] = '\0'; | ||
200 | e += (rep.pendingNbytesFilter + 3) & ~3; | ||
201 | for (p = 0; p < rep.pendingNparamsFilter; p++) { | ||
202 | INT32 f; | ||
203 | + if (e + 4 > end) { | ||
204 | + XFree (extra); | ||
205 | + return False; | ||
206 | + } | ||
207 | memcpy (&f, e, 4); | ||
208 | e += 4; | ||
209 | attr->pendingParams[p] = (XFixed) f; | ||
210 | } | ||
211 | attr->pendingNparams = rep.pendingNparamsFilter; | ||
212 | |||
213 | + if (e + rep.currentNbytesFilter > end) { | ||
214 | + XFree (extra); | ||
215 | + return False; | ||
216 | + } | ||
217 | memcpy (attr->currentFilter, e, rep.currentNbytesFilter); | ||
218 | attr->currentFilter[rep.currentNbytesFilter] = '\0'; | ||
219 | e += (rep.currentNbytesFilter + 3) & ~3; | ||
220 | for (p = 0; p < rep.currentNparamsFilter; p++) { | ||
221 | INT32 f; | ||
222 | + if (e + 4 > end) { | ||
223 | + XFree (extra); | ||
224 | + return False; | ||
225 | + } | ||
226 | memcpy (&f, e, 4); | ||
227 | e += 4; | ||
228 | attr->currentParams[p] = (XFixed) f; | ||
229 | diff --git a/src/XrrMonitor.c b/src/XrrMonitor.c | ||
230 | index a9eaa7b..adc5330 100644 | ||
231 | --- a/src/XrrMonitor.c | ||
232 | +++ b/src/XrrMonitor.c | ||
233 | @@ -24,6 +24,7 @@ | ||
234 | #include <config.h> | ||
235 | #endif | ||
236 | |||
237 | +#include <limits.h> | ||
238 | #include <stdio.h> | ||
239 | #include <X11/Xlib.h> | ||
240 | /* we need to be able to manipulate the Display structure on events */ | ||
241 | @@ -65,6 +66,15 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors) | ||
242 | return NULL; | ||
243 | } | ||
244 | |||
245 | + if (rep.length > INT_MAX >> 2 || | ||
246 | + rep.nmonitors > INT_MAX / SIZEOF(xRRMonitorInfo) || | ||
247 | + rep.noutputs > INT_MAX / 4 || | ||
248 | + rep.nmonitors * SIZEOF(xRRMonitorInfo) > INT_MAX - rep.noutputs * 4) { | ||
249 | + _XEatData (dpy, rep.length); | ||
250 | + UnlockDisplay (dpy); | ||
251 | + SyncHandle (); | ||
252 | + return NULL; | ||
253 | + } | ||
254 | nbytes = (long) rep.length << 2; | ||
255 | nmon = rep.nmonitors; | ||
256 | noutput = rep.noutputs; | ||
257 | @@ -111,6 +121,14 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors) | ||
258 | mon[m].outputs = output; | ||
259 | buf += SIZEOF (xRRMonitorInfo); | ||
260 | xoutput = (CARD32 *) buf; | ||
261 | + if (xmon->noutput > rep.noutputs) { | ||
262 | + Xfree(buf); | ||
263 | + Xfree(mon); | ||
264 | + UnlockDisplay (dpy); | ||
265 | + SyncHandle (); | ||
266 | + return NULL; | ||
267 | + } | ||
268 | + rep.noutputs -= xmon->noutput; | ||
269 | for (o = 0; o < xmon->noutput; o++) | ||
270 | output[o] = xoutput[o]; | ||
271 | output += xmon->noutput; | ||
272 | diff --git a/src/XrrOutput.c b/src/XrrOutput.c | ||
273 | index 85f0b6e..30f3d40 100644 | ||
274 | --- a/src/XrrOutput.c | ||
275 | +++ b/src/XrrOutput.c | ||
276 | @@ -25,6 +25,7 @@ | ||
277 | #include <config.h> | ||
278 | #endif | ||
279 | |||
280 | +#include <limits.h> | ||
281 | #include <stdio.h> | ||
282 | #include <X11/Xlib.h> | ||
283 | /* we need to be able to manipulate the Display structure on events */ | ||
284 | @@ -60,6 +61,16 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) | ||
285 | return NULL; | ||
286 | } | ||
287 | |||
288 | + if (rep.length > INT_MAX >> 2 || rep.length < (OutputInfoExtra >> 2)) | ||
289 | + { | ||
290 | + if (rep.length > (OutputInfoExtra >> 2)) | ||
291 | + _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2)); | ||
292 | + else | ||
293 | + _XEatDataWords (dpy, rep.length); | ||
294 | + UnlockDisplay (dpy); | ||
295 | + SyncHandle (); | ||
296 | + return NULL; | ||
297 | + } | ||
298 | nbytes = ((long) (rep.length) << 2) - OutputInfoExtra; | ||
299 | |||
300 | nbytesRead = (long) (rep.nCrtcs * 4 + | ||
301 | diff --git a/src/XrrProvider.c b/src/XrrProvider.c | ||
302 | index 9e620c7..d796cd0 100644 | ||
303 | --- a/src/XrrProvider.c | ||
304 | +++ b/src/XrrProvider.c | ||
305 | @@ -25,6 +25,7 @@ | ||
306 | #include <config.h> | ||
307 | #endif | ||
308 | |||
309 | +#include <limits.h> | ||
310 | #include <stdio.h> | ||
311 | #include <X11/Xlib.h> | ||
312 | /* we need to be able to manipulate the Display structure on events */ | ||
313 | @@ -59,12 +60,20 @@ XRRGetProviderResources(Display *dpy, Window window) | ||
314 | return NULL; | ||
315 | } | ||
316 | |||
317 | - nbytes = (long) rep.length << 2; | ||
318 | + if (rep.length < INT_MAX >> 2) { | ||
319 | + nbytes = (long) rep.length << 2; | ||
320 | |||
321 | - nbytesRead = (long) (rep.nProviders * 4); | ||
322 | + nbytesRead = (long) (rep.nProviders * 4); | ||
323 | |||
324 | - rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider)); | ||
325 | - xrpr = (XRRProviderResources *) Xmalloc(rbytes); | ||
326 | + rbytes = (sizeof(XRRProviderResources) + rep.nProviders * | ||
327 | + sizeof(RRProvider)); | ||
328 | + xrpr = (XRRProviderResources *) Xmalloc(rbytes); | ||
329 | + } else { | ||
330 | + nbytes = 0; | ||
331 | + nbytesRead = 0; | ||
332 | + rbytes = 0; | ||
333 | + xrpr = NULL; | ||
334 | + } | ||
335 | |||
336 | if (xrpr == NULL) { | ||
337 | _XEatDataWords (dpy, rep.length); | ||
338 | @@ -121,6 +130,17 @@ XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provi | ||
339 | return NULL; | ||
340 | } | ||
341 | |||
342 | + if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2) | ||
343 | + { | ||
344 | + if (rep.length < ProviderInfoExtra >> 2) | ||
345 | + _XEatDataWords (dpy, rep.length); | ||
346 | + else | ||
347 | + _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2)); | ||
348 | + UnlockDisplay (dpy); | ||
349 | + SyncHandle (); | ||
350 | + return NULL; | ||
351 | + } | ||
352 | + | ||
353 | nbytes = ((long) rep.length << 2) - ProviderInfoExtra; | ||
354 | |||
355 | nbytesRead = (long)(rep.nCrtcs * 4 + | ||
356 | diff --git a/src/XrrScreen.c b/src/XrrScreen.c | ||
357 | index b8ce7e5..1f7ffe6 100644 | ||
358 | --- a/src/XrrScreen.c | ||
359 | +++ b/src/XrrScreen.c | ||
360 | @@ -24,6 +24,7 @@ | ||
361 | #include <config.h> | ||
362 | #endif | ||
363 | |||
364 | +#include <limits.h> | ||
365 | #include <stdio.h> | ||
366 | #include <X11/Xlib.h> | ||
367 | /* we need to be able to manipulate the Display structure on events */ | ||
368 | @@ -105,27 +106,36 @@ doGetScreenResources (Display *dpy, Window window, int poll) | ||
369 | xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version); | ||
370 | } | ||
371 | |||
372 | - nbytes = (long) rep.length << 2; | ||
373 | + if (rep.length < INT_MAX >> 2) { | ||
374 | + nbytes = (long) rep.length << 2; | ||
375 | |||
376 | - nbytesRead = (long) (rep.nCrtcs * 4 + | ||
377 | - rep.nOutputs * 4 + | ||
378 | - rep.nModes * SIZEOF (xRRModeInfo) + | ||
379 | - ((rep.nbytesNames + 3) & ~3)); | ||
380 | + nbytesRead = (long) (rep.nCrtcs * 4 + | ||
381 | + rep.nOutputs * 4 + | ||
382 | + rep.nModes * SIZEOF (xRRModeInfo) + | ||
383 | + ((rep.nbytesNames + 3) & ~3)); | ||
384 | |||
385 | - /* | ||
386 | - * first we must compute how much space to allocate for | ||
387 | - * randr library's use; we'll allocate the structures in a single | ||
388 | - * allocation, on cleanlyness grounds. | ||
389 | - */ | ||
390 | + /* | ||
391 | + * first we must compute how much space to allocate for | ||
392 | + * randr library's use; we'll allocate the structures in a single | ||
393 | + * allocation, on cleanlyness grounds. | ||
394 | + */ | ||
395 | + | ||
396 | + rbytes = (sizeof (XRRScreenResources) + | ||
397 | + rep.nCrtcs * sizeof (RRCrtc) + | ||
398 | + rep.nOutputs * sizeof (RROutput) + | ||
399 | + rep.nModes * sizeof (XRRModeInfo) + | ||
400 | + rep.nbytesNames + rep.nModes); /* '\0' terminate names */ | ||
401 | |||
402 | - rbytes = (sizeof (XRRScreenResources) + | ||
403 | - rep.nCrtcs * sizeof (RRCrtc) + | ||
404 | - rep.nOutputs * sizeof (RROutput) + | ||
405 | - rep.nModes * sizeof (XRRModeInfo) + | ||
406 | - rep.nbytesNames + rep.nModes); /* '\0' terminate names */ | ||
407 | + xrsr = (XRRScreenResources *) Xmalloc(rbytes); | ||
408 | + wire_names = (char *) Xmalloc (rep.nbytesNames); | ||
409 | + } else { | ||
410 | + nbytes = 0; | ||
411 | + nbytesRead = 0; | ||
412 | + rbytes = 0; | ||
413 | + xrsr = NULL; | ||
414 | + wire_names = NULL; | ||
415 | + } | ||
416 | |||
417 | - xrsr = (XRRScreenResources *) Xmalloc(rbytes); | ||
418 | - wire_names = (char *) Xmalloc (rep.nbytesNames); | ||
419 | if (xrsr == NULL || wire_names == NULL) { | ||
420 | Xfree (xrsr); | ||
421 | Xfree (wire_names); | ||
422 | @@ -174,6 +184,14 @@ doGetScreenResources (Display *dpy, Window window, int poll) | ||
423 | wire_name = wire_names; | ||
424 | for (i = 0; i < rep.nModes; i++) { | ||
425 | xrsr->modes[i].name = names; | ||
426 | + if (xrsr->modes[i].nameLength > rep.nbytesNames) { | ||
427 | + Xfree (xrsr); | ||
428 | + Xfree (wire_names); | ||
429 | + UnlockDisplay (dpy); | ||
430 | + SyncHandle (); | ||
431 | + return NULL; | ||
432 | + } | ||
433 | + rep.nbytesNames -= xrsr->modes[i].nameLength; | ||
434 | memcpy (names, wire_name, xrsr->modes[i].nameLength); | ||
435 | names[xrsr->modes[i].nameLength] = '\0'; | ||
436 | names += xrsr->modes[i].nameLength + 1; | ||
437 | -- | ||
438 | cgit v0.10.2 | ||
439 | |||
diff --git a/meta/recipes-graphics/xorg-lib/libxrandr_1.5.0.bb b/meta/recipes-graphics/xorg-lib/libxrandr_1.5.0.bb index abbbae5528..35c60b4190 100644 --- a/meta/recipes-graphics/xorg-lib/libxrandr_1.5.0.bb +++ b/meta/recipes-graphics/xorg-lib/libxrandr_1.5.0.bb | |||
@@ -19,5 +19,8 @@ XORG_PN = "libXrandr" | |||
19 | 19 | ||
20 | BBCLASSEXTEND = "native nativesdk" | 20 | BBCLASSEXTEND = "native nativesdk" |
21 | 21 | ||
22 | SRC_URI += "file://CVE-2016-7947_CVE-2016-7948.patch \ | ||
23 | " | ||
24 | |||
22 | SRC_URI[md5sum] = "309762867e41c6fd813da880d8a1bc93" | 25 | SRC_URI[md5sum] = "309762867e41c6fd813da880d8a1bc93" |
23 | SRC_URI[sha256sum] = "6f864959b7fc35db11754b270d71106ef5b5cf363426aa58589cb8ac8266de58" | 26 | SRC_URI[sha256sum] = "6f864959b7fc35db11754b270d71106ef5b5cf363426aa58589cb8ac8266de58" |