Bug Summary

File:Xext/shm.c
Location:line 858, column 5
Description:Potential leak of memory pointed to by 'drawables'

Annotated Source Code

1/************************************************************
2
3Copyright 1989, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25********************************************************/
26
27/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
28
29#define SHM
30
31#ifdef HAVE_DIX_CONFIG_H1
32#include <dix-config.h>
33#endif
34
35#include <sys/types.h>
36#include <sys/ipc.h>
37#include <sys/shm.h>
38#include <unistd.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <X11/X.h>
42#include <X11/Xproto.h>
43#include "misc.h"
44#include "os.h"
45#include "dixstruct.h"
46#include "resource.h"
47#include "scrnintstr.h"
48#include "windowstr.h"
49#include "pixmapstr.h"
50#include "gcstruct.h"
51#include "extnsionst.h"
52#include "servermd.h"
53#include "shmint.h"
54#include "xace.h"
55#include <X11/extensions/shmproto.h>
56#include <X11/Xfuncproto.h>
57#include <sys/mman.h>
58#include "protocol-versions.h"
59#include "busfault.h"
60
61/* Needed for Solaris cross-zone shared memory extension */
62#ifdef HAVE_SHMCTL64
63#include <sys/ipc_impl.h>
64#define SHMSTAT(id, buf)shmctl(id, 2, buf) shmctl64(id, IPC_STAT64, buf)
65#define SHMSTAT_TYPEstruct __shmid_ds_new struct shmid_ds64
66#define SHMPERM_TYPEstruct ipc_perm struct ipc_perm64
67#define SHM_PERM(buf)buf.shm_perm buf.shmx_perm
68#define SHM_SEGSZ(buf)buf.shm_segsz buf.shmx_segsz
69#define SHMPERM_UID(p)p->uid p->ipcx_uid
70#define SHMPERM_CUID(p)p->cuid p->ipcx_cuid
71#define SHMPERM_GID(p)p->gid p->ipcx_gid
72#define SHMPERM_CGID(p)p->cgid p->ipcx_cgid
73#define SHMPERM_MODE(p)p->mode p->ipcx_mode
74#define SHMPERM_ZONEID(p) p->ipcx_zoneid
75#else
76#define SHMSTAT(id, buf)shmctl(id, 2, buf) shmctl(id, IPC_STAT2, buf)
77#define SHMSTAT_TYPEstruct __shmid_ds_new struct shmid_ds__shmid_ds_new
78#define SHMPERM_TYPEstruct ipc_perm struct ipc_perm
79#define SHM_PERM(buf)buf.shm_perm buf.shm_perm
80#define SHM_SEGSZ(buf)buf.shm_segsz buf.shm_segsz
81#define SHMPERM_UID(p)p->uid p->uid
82#define SHMPERM_CUID(p)p->cuid p->cuid
83#define SHMPERM_GID(p)p->gid p->gid
84#define SHMPERM_CGID(p)p->cgid p->cgid
85#define SHMPERM_MODE(p)p->mode p->mode
86#endif
87
88#ifdef PANORAMIX1
89#include "panoramiX.h"
90#include "panoramiXsrv.h"
91#endif
92
93#include "extinit.h"
94
95typedef struct _ShmScrPrivateRec {
96 CloseScreenProcPtr CloseScreen;
97 ShmFuncsPtr shmFuncs;
98 DestroyPixmapProcPtr destroyPixmap;
99} ShmScrPrivateRec;
100
101static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGSScreenPtr , int , int , int , char *);
102static int ShmDetachSegment(void *value, XID shmseg);
103static void ShmResetProc(ExtensionEntry *extEntry);
104static void SShmCompletionEvent(xShmCompletionEvent *from,
105 xShmCompletionEvent *to);
106
107static Bool ShmDestroyPixmap(PixmapPtr pPixmap);
108
109static unsigned char ShmReqCode;
110int ShmCompletionCode;
111int BadShmSegCode;
112RESTYPE ShmSegType;
113static ShmDescPtr Shmsegs;
114static Bool sharedPixmaps;
115static DevPrivateKeyRec shmScrPrivateKeyRec;
116
117#define shmScrPrivateKey(&shmScrPrivateKeyRec) (&shmScrPrivateKeyRec)
118static DevPrivateKeyRec shmPixmapPrivateKeyRec;
119
120#define shmPixmapPrivateKey(&shmPixmapPrivateKeyRec) (&shmPixmapPrivateKeyRec)
121static ShmFuncs miFuncs = { NULL((void*)0), NULL((void*)0) };
122static ShmFuncs fbFuncs = { fbShmCreatePixmap, NULL((void*)0) };
123
124#define ShmGetScreenPriv(s)((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates
, (&shmScrPrivateKeyRec)))
((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec)))
125
126#define VERIFY_SHMSEG(shmseg,shmdesc,client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc
), shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0)
return tmprc; }
\
127{ \
128 int tmprc; \
129 tmprc = dixLookupResourceByType((void **)&(shmdesc), shmseg, ShmSegType, \
130 client, DixReadAccess(1<<0)); \
131 if (tmprc != Success0) \
132 return tmprc; \
133}
134
135#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), shmseg, ShmSegType, client, (1<<0)); if (tmprc
!= 0) return tmprc; }; if ((offset & 3) || (offset > shmdesc
->size)) { client->errorValue = offset; return 2; } if (
needwrite && !shmdesc->writable) return 10; }
\
136{ \
137 VERIFY_SHMSEG(shmseg, shmdesc, client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc
), shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0)
return tmprc; }
; \
138 if ((offset & 3) || (offset > shmdesc->size)) \
139 { \
140 client->errorValue = offset; \
141 return BadValue2; \
142 } \
143 if (needwrite && !shmdesc->writable) \
144 return BadAccess10; \
145}
146
147#define VERIFY_SHMSIZE(shmdesc,offset,len,client){ if ((offset + len) > shmdesc->size) { return 10; } } \
148{ \
149 if ((offset + len) > shmdesc->size) \
150 { \
151 return BadAccess10; \
152 } \
153}
154
155#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
156#include <sys/signal.h>
157
158static Bool badSysCall = FALSE0;
159
160static void
161SigSysHandler(int signo)
162{
163 badSysCall = TRUE1;
164}
165
166static Bool
167CheckForShmSyscall(void)
168{
169 void (*oldHandler) (int);
170 int shmid = -1;
171
172 /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
173 oldHandler = signal(SIGSYS12, SigSysHandler);
174
175 badSysCall = FALSE0;
176 shmid = shmget(IPC_PRIVATE((key_t)0), 4096, IPC_CREAT001000);
177
178 if (shmid != -1) {
179 /* Successful allocation - clean up */
180 shmctl(shmid, IPC_RMID0, NULL((void*)0));
181 }
182 else {
183 /* Allocation failed */
184 badSysCall = TRUE1;
185 }
186 signal(SIGSYS12, oldHandler);
187 return !badSysCall;
188}
189
190#define MUST_CHECK_FOR_SHM_SYSCALL
191
192#endif
193
194static Bool
195ShmCloseScreen(ScreenPtr pScreen)
196{
197 ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates
, (&shmScrPrivateKeyRec)))
;
198
199 pScreen->CloseScreen = screen_priv->CloseScreen;
200 dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec), NULL((void*)0));
201 free(screen_priv);
202 return (*pScreen->CloseScreen) (pScreen);
203}
204
205static ShmScrPrivateRec *
206ShmInitScreenPriv(ScreenPtr pScreen)
207{
208 ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates
, (&shmScrPrivateKeyRec)))
;
209
210 if (!screen_priv) {
211 screen_priv = calloc(1, sizeof(ShmScrPrivateRec));
212 screen_priv->CloseScreen = pScreen->CloseScreen;
213 dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec), screen_priv);
214 pScreen->CloseScreen = ShmCloseScreen;
215 }
216 return screen_priv;
217}
218
219static Bool
220ShmRegisterPrivates(void)
221{
222 if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0))
223 return FALSE0;
224 if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
225 return FALSE0;
226 return TRUE1;
227}
228
229 /*ARGSUSED*/ static void
230ShmResetProc(ExtensionEntry * extEntry)
231{
232 int i;
233
234 for (i = 0; i < screenInfo.numScreens; i++)
235 ShmRegisterFuncs(screenInfo.screens[i], NULL((void*)0));
236}
237
238void
239ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
240{
241 if (!ShmRegisterPrivates())
242 return;
243 ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
244}
245
246static Bool
247ShmDestroyPixmap(PixmapPtr pPixmap)
248{
249 ScreenPtr pScreen = pPixmap->drawable.pScreen;
250 ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates
, (&shmScrPrivateKeyRec)))
;
251 void *shmdesc = NULL((void*)0);
252 Bool ret;
253
254 if (pPixmap->refcnt == 1)
255 shmdesc = dixLookupPrivate(&pPixmap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec));
256
257 pScreen->DestroyPixmap = screen_priv->destroyPixmap;
258 ret = (*pScreen->DestroyPixmap) (pPixmap);
259 screen_priv->destroyPixmap = pScreen->DestroyPixmap;
260 pScreen->DestroyPixmap = ShmDestroyPixmap;
261
262 if (shmdesc)
263 ShmDetachSegment(shmdesc, 0);
264
265 return ret;
266}
267
268void
269ShmRegisterFbFuncs(ScreenPtr pScreen)
270{
271 ShmRegisterFuncs(pScreen, &fbFuncs);
272}
273
274static int
275ProcShmQueryVersion(ClientPtr client)
276{
277 xShmQueryVersionReply rep = {
278 .type = X_Reply1,
279 .sharedPixmaps = sharedPixmaps,
280 .sequenceNumber = client->sequence,
281 .length = 0,
282 .majorVersion = SERVER_SHM_MAJOR_VERSION1,
283 .minorVersion = SERVER_SHM_MINOR_VERSION1,
284 .uid = geteuid(),
285 .gid = getegid(),
286 .pixmapFormat = sharedPixmaps ? ZPixmap2 : 0
287 };
288
289 REQUEST_SIZE_MATCH(xShmQueryVersionReq)if ((sizeof(xShmQueryVersionReq) >> 2) != client->req_len
) return(16)
;
290
291 if (client->swapped) {
292 swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber
) & 1) && ((uintptr_t)(&rep.sequenceNumber) &
1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber
)); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); }
while (0)
;
293 swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.length) & 3) && ((uintptr_t
)(&rep.length) & 3) == 0) *(&rep.length) = lswapl
(*(&rep.length)); else swap_uint32((uint32_t *)(&rep.
length)); } while (0)
;
294 swaps(&rep.majorVersion)do { if (sizeof(*(&rep.majorVersion)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.majorVersion) &
1) && ((uintptr_t)(&rep.majorVersion) & 1) ==
0) *(&rep.majorVersion) = lswaps(*(&rep.majorVersion
)); else swap_uint16((uint16_t *)(&rep.majorVersion)); } while
(0)
;
295 swaps(&rep.minorVersion)do { if (sizeof(*(&rep.minorVersion)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&rep.minorVersion) &
1) && ((uintptr_t)(&rep.minorVersion) & 1) ==
0) *(&rep.minorVersion) = lswaps(*(&rep.minorVersion
)); else swap_uint16((uint16_t *)(&rep.minorVersion)); } while
(0)
;
296 swaps(&rep.uid)do { if (sizeof(*(&rep.uid)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.uid) & 1) && ((uintptr_t)(&
rep.uid) & 1) == 0) *(&rep.uid) = lswaps(*(&rep.uid
)); else swap_uint16((uint16_t *)(&rep.uid)); } while (0)
;
297 swaps(&rep.gid)do { if (sizeof(*(&rep.gid)) != 2) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&rep.gid) & 1) && ((uintptr_t)(&
rep.gid) & 1) == 0) *(&rep.gid) = lswaps(*(&rep.gid
)); else swap_uint16((uint16_t *)(&rep.gid)); } while (0)
;
298 }
299 WriteToClient(client, sizeof(xShmQueryVersionReply), &rep);
300 return Success0;
301}
302
303/*
304 * Simulate the access() system call for a shared memory segement,
305 * using the credentials from the client if available
306 */
307static int
308shm_access(ClientPtr client, SHMPERM_TYPEstruct ipc_perm * perm, int readonly)
309{
310 int uid, gid;
311 mode_t mask;
312 int uidset = 0, gidset = 0;
313 LocalClientCredRec *lcc;
314
315 if (GetLocalClientCreds(client, &lcc) != -1) {
316
317 if (lcc->fieldsSet & LCC_UID_SET(1 << 0)) {
318 uid = lcc->euid;
319 uidset = 1;
320 }
321 if (lcc->fieldsSet & LCC_GID_SET(1 << 1)) {
322 gid = lcc->egid;
323 gidset = 1;
324 }
325
326#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
327 if (((lcc->fieldsSet & LCC_ZID_SET(1 << 3)) == 0) || (lcc->zoneid == -1)
328 || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
329 uidset = 0;
330 gidset = 0;
331 }
332#endif
333 FreeLocalClientCreds(lcc);
334
335 if (uidset) {
336 /* User id 0 always gets access */
337 if (uid == 0) {
338 return 0;
339 }
340 /* Check the owner */
341 if (SHMPERM_UID(perm)perm->uid == uid || SHMPERM_CUID(perm)perm->cuid == uid) {
342 mask = S_IRUSR0000400;
343 if (!readonly) {
344 mask |= S_IWUSR0000200;
345 }
346 return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1;
347 }
348 }
349
350 if (gidset) {
351 /* Check the group */
352 if (SHMPERM_GID(perm)perm->gid == gid || SHMPERM_CGID(perm)perm->cgid == gid) {
353 mask = S_IRGRP0000040;
354 if (!readonly) {
355 mask |= S_IWGRP0000020;
356 }
357 return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1;
358 }
359 }
360 }
361 /* Otherwise, check everyone else */
362 mask = S_IROTH0000004;
363 if (!readonly) {
364 mask |= S_IWOTH0000002;
365 }
366 return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1;
367}
368
369static int
370ProcShmAttach(ClientPtr client)
371{
372 SHMSTAT_TYPEstruct __shmid_ds_new buf;
373 ShmDescPtr shmdesc;
374
375 REQUEST(xShmAttachReq)xShmAttachReq *stuff = (xShmAttachReq *)client->requestBuffer;
376
377 REQUEST_SIZE_MATCH(xShmAttachReq)if ((sizeof(xShmAttachReq) >> 2) != client->req_len)
return(16)
;
378 LEGAL_NEW_RESOURCE(stuff->shmseg, client)if (!LegalNewID(stuff->shmseg,client)) { client->errorValue
= stuff->shmseg; return 14; }
;
379 if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) {
380 client->errorValue = stuff->readOnly;
381 return BadValue2;
382 }
383 for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next) {
384 if (!SHMDESC_IS_FD(shmdesc)(0) && shmdesc->shmid == stuff->shmid)
385 break;
386 }
387 if (shmdesc) {
388 if (!stuff->readOnly && !shmdesc->writable)
389 return BadAccess10;
390 shmdesc->refcnt++;
391 }
392 else {
393 shmdesc = malloc(sizeof(ShmDescRec));
394 if (!shmdesc)
395 return BadAlloc11;
396#ifdef SHM_FD_PASSING
397 shmdesc->is_fd = FALSE0;
398#endif
399 shmdesc->addr = shmat(stuff->shmid, 0,
400 stuff->readOnly ? SHM_RDONLY010000 : 0);
401 if ((shmdesc->addr == ((char *) -1)) || SHMSTAT(stuff->shmid, &buf)shmctl(stuff->shmid, 2, &buf)) {
402 free(shmdesc);
403 return BadAccess10;
404 }
405
406 /* The attach was performed with root privs. We must
407 * do manual checking of access rights for the credentials
408 * of the client */
409
410 if (shm_access(client, &(SHM_PERM(buf)buf.shm_perm), stuff->readOnly) == -1) {
411 shmdt(shmdesc->addr);
412 free(shmdesc);
413 return BadAccess10;
414 }
415
416 shmdesc->shmid = stuff->shmid;
417 shmdesc->refcnt = 1;
418 shmdesc->writable = !stuff->readOnly;
419 shmdesc->size = SHM_SEGSZ(buf)buf.shm_segsz;
420 shmdesc->next = Shmsegs;
421 Shmsegs = shmdesc;
422 }
423 if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc))
424 return BadAlloc11;
425 return Success0;
426}
427
428 /*ARGSUSED*/ static int
429ShmDetachSegment(void *value, /* must conform to DeleteType */
430 XID unused)
431{
432 ShmDescPtr shmdesc = (ShmDescPtr) value;
433 ShmDescPtr *prev;
434
435 if (--shmdesc->refcnt)
436 return TRUE1;
437#if SHM_FD_PASSING
438 if (shmdesc->is_fd) {
439 if (shmdesc->busfault)
440 busfault_unregister(shmdesc->busfault);
441 munmap(shmdesc->addr, shmdesc->size);
442 } else
443#endif
444 shmdt(shmdesc->addr);
445 for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next);
446 *prev = shmdesc->next;
447 free(shmdesc);
448 return Success0;
449}
450
451static int
452ProcShmDetach(ClientPtr client)
453{
454 ShmDescPtr shmdesc;
455
456 REQUEST(xShmDetachReq)xShmDetachReq *stuff = (xShmDetachReq *)client->requestBuffer;
457
458 REQUEST_SIZE_MATCH(xShmDetachReq)if ((sizeof(xShmDetachReq) >> 2) != client->req_len)
return(16)
;
459 VERIFY_SHMSEG(stuff->shmseg, shmdesc, client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc
), stuff->shmseg, ShmSegType, client, (1<<0)); if (tmprc
!= 0) return tmprc; }
;
460 FreeResource(stuff->shmseg, RT_NONE((RESTYPE)0));
461 return Success0;
462}
463
464/*
465 * If the given request doesn't exactly match PutImage's constraints,
466 * wrap the image in a scratch pixmap header and let CopyArea sort it out.
467 */
468static void
469doShmPutImage(DrawablePtr dst, GCPtr pGC,
470 int depth, unsigned int format,
471 int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
472 char *data)
473{
474 PixmapPtr pPixmap;
475
476 if (format == ZPixmap2 || (format == XYPixmap1 && depth == 1)) {
477 pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
478 BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel),
479 PixmapBytePad(w, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(w) * PixmapWidthPaddingInfo
[depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel
) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int
)((w) + PixmapWidthPaddingInfo[depth].padRoundUp) >> PixmapWidthPaddingInfo
[depth].padPixelsLog2)) << PixmapWidthPaddingInfo[depth
].padBytesLog2)
, data);
480 if (!pPixmap)
481 return;
482 pGC->ops->CopyArea((DrawablePtr) pPixmap, dst, pGC, sx, sy, sw, sh, dx,
483 dy);
484 FreeScratchPixmapHeader(pPixmap);
485 }
486 else {
487 GCPtr putGC = GetScratchGC(depth, dst->pScreen);
488
489 if (!putGC)
490 return;
491
492 pPixmap = (*dst->pScreen->CreatePixmap) (dst->pScreen, sw, sh, depth,
493 CREATE_PIXMAP_USAGE_SCRATCH1);
494 if (!pPixmap) {
495 FreeScratchGC(putGC);
496 return;
497 }
498 ValidateGC(&pPixmap->drawable, putGC);
499 (*putGC->ops->PutImage) (&pPixmap->drawable, putGC, depth, -sx, -sy, w,
500 h, 0,
501 (format == XYPixmap1) ? XYPixmap1 : ZPixmap2,
502 data);
503 FreeScratchGC(putGC);
504 if (format == XYBitmap0)
505 (void) (*pGC->ops->CopyPlane) (&pPixmap->drawable, dst, pGC, 0, 0,
506 sw, sh, dx, dy, 1L);
507 else
508 (void) (*pGC->ops->CopyArea) (&pPixmap->drawable, dst, pGC, 0, 0,
509 sw, sh, dx, dy);
510 (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
511 }
512}
513
514static int
515ProcShmPutImage(ClientPtr client)
516{
517 GCPtr pGC;
518 DrawablePtr pDraw;
519 long length;
520 ShmDescPtr shmdesc;
521
522 REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer;
523
524 REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len
) return(16)
;
525 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess){ int tmprc = dixLookupDrawable(&(pDraw), stuff->drawable
, client, (-1), (1<<1)); if (tmprc != 0) return tmprc; tmprc
= dixLookupGC(&(pGC), stuff->gc, client, (1<<24
)); if (tmprc != 0) return tmprc; if ((pGC->depth != pDraw
->depth) || (pGC->pScreen != pDraw->pScreen)) return
8; } if (pGC->serialNumber != pDraw->serialNumber) ValidateGC
(pDraw, pGC);
;
526 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), stuff->shmseg, ShmSegType, client, (1<<0)
); if (tmprc != 0) return tmprc; }; if ((stuff->offset &
3) || (stuff->offset > shmdesc->size)) { client->
errorValue = stuff->offset; return 2; } if (0 && !
shmdesc->writable) return 10; }
;
527 if ((stuff->sendEvent != xTrue1) && (stuff->sendEvent != xFalse0))
528 return BadValue2;
529 if (stuff->format == XYBitmap0) {
530 if (stuff->depth != 1)
531 return BadMatch8;
532 length = PixmapBytePad(stuff->totalWidth, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->totalWidth
) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo
[1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2
) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[1]
.padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2
)) << PixmapWidthPaddingInfo[1].padBytesLog2)
;
533 }
534 else if (stuff->format == XYPixmap1) {
535 if (pDraw->depth != stuff->depth)
536 return BadMatch8;
537 length = PixmapBytePad(stuff->totalWidth, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->totalWidth
) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo
[1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2
) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[1]
.padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2
)) << PixmapWidthPaddingInfo[1].padBytesLog2)
;
538 length *= stuff->depth;
539 }
540 else if (stuff->format == ZPixmap2) {
541 if (pDraw->depth != stuff->depth)
542 return BadMatch8;
543 length = PixmapBytePad(stuff->totalWidth, stuff->depth)((PixmapWidthPaddingInfo[stuff->depth].notPower2 ? (((int)
(stuff->totalWidth) * PixmapWidthPaddingInfo[stuff->depth
].bytesPerPixel + PixmapWidthPaddingInfo[stuff->depth].bytesPerPixel
) >> PixmapWidthPaddingInfo[stuff->depth].padBytesLog2
) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[stuff
->depth].padRoundUp) >> PixmapWidthPaddingInfo[stuff
->depth].padPixelsLog2)) << PixmapWidthPaddingInfo[stuff
->depth].padBytesLog2)
;
544 }
545 else {
546 client->errorValue = stuff->format;
547 return BadValue2;
548 }
549
550 /*
551 * There's a potential integer overflow in this check:
552 * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
553 * client);
554 * the version below ought to avoid it
555 */
556 if (stuff->totalHeight != 0 &&
557 length > (shmdesc->size - stuff->offset) / stuff->totalHeight) {
558 client->errorValue = stuff->totalWidth;
559 return BadValue2;
560 }
561 if (stuff->srcX > stuff->totalWidth) {
562 client->errorValue = stuff->srcX;
563 return BadValue2;
564 }
565 if (stuff->srcY > stuff->totalHeight) {
566 client->errorValue = stuff->srcY;
567 return BadValue2;
568 }
569 if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) {
570 client->errorValue = stuff->srcWidth;
571 return BadValue2;
572 }
573 if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) {
574 client->errorValue = stuff->srcHeight;
575 return BadValue2;
576 }
577
578 if ((((stuff->format == ZPixmap2) && (stuff->srcX == 0)) ||
579 ((stuff->format != ZPixmap2) &&
580 (stuff->srcX < screenInfo.bitmapScanlinePad) &&
581 ((stuff->format == XYBitmap0) ||
582 ((stuff->srcY == 0) &&
583 (stuff->srcHeight == stuff->totalHeight))))) &&
584 ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
585 (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
586 stuff->dstX, stuff->dstY,
587 stuff->totalWidth, stuff->srcHeight,
588 stuff->srcX, stuff->format,
589 shmdesc->addr + stuff->offset +
590 (stuff->srcY * length));
591 else
592 doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
593 stuff->totalWidth, stuff->totalHeight,
594 stuff->srcX, stuff->srcY,
595 stuff->srcWidth, stuff->srcHeight,
596 stuff->dstX, stuff->dstY, shmdesc->addr + stuff->offset);
597
598 if (stuff->sendEvent) {
599 xShmCompletionEvent ev = {
600 .type = ShmCompletionCode,
601 .drawable = stuff->drawable,
602 .minorEvent = X_ShmPutImage3,
603 .majorEvent = ShmReqCode,
604 .shmseg = stuff->shmseg,
605 .offset = stuff->offset
606 };
607 WriteEventsToClient(client, 1, (xEvent *) &ev);
608 }
609
610 return Success0;
611}
612
613static int
614ProcShmGetImage(ClientPtr client)
615{
616 DrawablePtr pDraw;
617 long lenPer = 0, length;
618 Mask plane = 0;
619 xShmGetImageReply xgi;
620 ShmDescPtr shmdesc;
621 VisualID visual = None0L;
622 int rc;
623
624 REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer;
625
626 REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len
) return(16)
;
627 if ((stuff->format != XYPixmap1) && (stuff->format != ZPixmap2)) {
628 client->errorValue = stuff->format;
629 return BadValue2;
630 }
631 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess(1<<0));
632 if (rc != Success0)
633 return rc;
634 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), stuff->shmseg, ShmSegType, client, (1<<0)
); if (tmprc != 0) return tmprc; }; if ((stuff->offset &
3) || (stuff->offset > shmdesc->size)) { client->
errorValue = stuff->offset; return 2; } if (1 && !
shmdesc->writable) return 10; }
;
635 if (pDraw->type == DRAWABLE_WINDOW0) {
636 if ( /* check for being viewable */
637 !((WindowPtr) pDraw)->realized ||
638 /* check for being on screen */
639 pDraw->x + stuff->x < 0 ||
640 pDraw->x + stuff->x + (int) stuff->width > pDraw->pScreen->width
641 || pDraw->y + stuff->y < 0 ||
642 pDraw->y + stuff->y + (int) stuff->height >
643 pDraw->pScreen->height ||
644 /* check for being inside of border */
645 stuff->x < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) ||
646 stuff->x + (int) stuff->width >
647 wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->width ||
648 stuff->y < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) ||
649 stuff->y + (int) stuff->height >
650 wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->height)
651 return BadMatch8;
652 visual = wVisual(((WindowPtr) pDraw))((((WindowPtr) pDraw))->optional ? (((WindowPtr) pDraw))->
optional->visual : FindWindowWithOptional(((WindowPtr) pDraw
))->optional->visual)
;
653 }
654 else {
655 if (stuff->x < 0 ||
656 stuff->x + (int) stuff->width > pDraw->width ||
657 stuff->y < 0 || stuff->y + (int) stuff->height > pDraw->height)
658 return BadMatch8;
659 visual = None0L;
660 }
661 xgi = (xShmGetImageReply) {
662 .type = X_Reply1,
663 .sequenceNumber = client->sequence,
664 .length = 0,
665 .visual = visual,
666 .depth = pDraw->depth
667 };
668 if (stuff->format == ZPixmap2) {
669 length = PixmapBytePad(stuff->width, pDraw->depth)((PixmapWidthPaddingInfo[pDraw->depth].notPower2 ? (((int)
(stuff->width) * PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel
+ PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel) >>
PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2) : ((int
)((stuff->width) + PixmapWidthPaddingInfo[pDraw->depth]
.padRoundUp) >> PixmapWidthPaddingInfo[pDraw->depth]
.padPixelsLog2)) << PixmapWidthPaddingInfo[pDraw->depth
].padBytesLog2)
* stuff->height;
670 }
671 else {
672 lenPer = PixmapBytePad(stuff->width, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->width
) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo
[1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2
) : ((int)((stuff->width) + PixmapWidthPaddingInfo[1].padRoundUp
) >> PixmapWidthPaddingInfo[1].padPixelsLog2)) <<
PixmapWidthPaddingInfo[1].padBytesLog2)
* stuff->height;
673 plane = ((Mask) 1) << (pDraw->depth - 1);
674 /* only planes asked for */
675 length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
676 }
677
678 VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client){ if ((stuff->offset + length) > shmdesc->size) { return
10; } }
;
679 xgi.size = length;
680
681 if (length == 0) {
682 /* nothing to do */
683 }
684 else if (stuff->format == ZPixmap2) {
685 (*pDraw->pScreen->GetImage) (pDraw, stuff->x, stuff->y,
686 stuff->width, stuff->height,
687 stuff->format, stuff->planeMask,
688 shmdesc->addr + stuff->offset);
689 }
690 else {
691
692 length = stuff->offset;
693 for (; plane; plane >>= 1) {
694 if (stuff->planeMask & plane) {
695 (*pDraw->pScreen->GetImage) (pDraw,
696 stuff->x, stuff->y,
697 stuff->width, stuff->height,
698 stuff->format, plane,
699 shmdesc->addr + length);
700 length += lenPer;
701 }
702 }
703 }
704
705 if (client->swapped) {
706 swaps(&xgi.sequenceNumber)do { if (sizeof(*(&xgi.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&xgi.sequenceNumber
) & 1) && ((uintptr_t)(&xgi.sequenceNumber) &
1) == 0) *(&xgi.sequenceNumber) = lswaps(*(&xgi.sequenceNumber
)); else swap_uint16((uint16_t *)(&xgi.sequenceNumber)); }
while (0)
;
707 swapl(&xgi.length)do { if (sizeof(*(&xgi.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.length) & 3) && ((uintptr_t
)(&xgi.length) & 3) == 0) *(&xgi.length) = lswapl
(*(&xgi.length)); else swap_uint32((uint32_t *)(&xgi.
length)); } while (0)
;
708 swapl(&xgi.visual)do { if (sizeof(*(&xgi.visual)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.visual) & 3) && ((uintptr_t
)(&xgi.visual) & 3) == 0) *(&xgi.visual) = lswapl
(*(&xgi.visual)); else swap_uint32((uint32_t *)(&xgi.
visual)); } while (0)
;
709 swapl(&xgi.size)do { if (sizeof(*(&xgi.size)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.size) & 3) && ((uintptr_t)(
&xgi.size) & 3) == 0) *(&xgi.size) = lswapl(*(&
xgi.size)); else swap_uint32((uint32_t *)(&xgi.size)); } while
(0)
;
710 }
711 WriteToClient(client, sizeof(xShmGetImageReply), &xgi);
712
713 return Success0;
714}
715
716#ifdef PANORAMIX1
717static int
718ProcPanoramiXShmPutImage(ClientPtr client)
719{
720 int j, result, orig_x, orig_y;
721 PanoramiXRes *draw, *gc;
722 Bool sendEvent, isRoot;
723
724 REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer;
725 REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len
) return(16)
;
726
727 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
728 XRC_DRAWABLE, client, DixWriteAccess(1<<1));
729 if (result != Success0)
730 return (result == BadValue2) ? BadDrawable9 : result;
731
732 result = dixLookupResourceByType((void **) &gc, stuff->gc,
733 XRT_GC, client, DixReadAccess(1<<0));
734 if (result != Success0)
735 return result;
736
737 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
738
739 orig_x = stuff->dstX;
740 orig_y = stuff->dstY;
741 sendEvent = stuff->sendEvent;
742 stuff->sendEvent = 0;
743 FOR_NSCREENS(j)for(j = 0; j < PanoramiXNumScreens; j++) {
744 if (!j)
745 stuff->sendEvent = sendEvent;
746 stuff->drawable = draw->info[j].id;
747 stuff->gc = gc->info[j].id;
748 if (isRoot) {
749 stuff->dstX = orig_x - screenInfo.screens[j]->x;
750 stuff->dstY = orig_y - screenInfo.screens[j]->y;
751 }
752 result = ProcShmPutImage(client);
753 if (result != Success0)
754 break;
755 }
756 return result;
757}
758
759static int
760ProcPanoramiXShmGetImage(ClientPtr client)
761{
762 PanoramiXRes *draw;
763 DrawablePtr *drawables;
764 DrawablePtr pDraw;
765 xShmGetImageReply xgi;
766 ShmDescPtr shmdesc;
767 int i, x, y, w, h, format, rc;
768 Mask plane = 0, planemask;
769 long lenPer = 0, length, widthBytesLine;
770 Bool isRoot;
771
772 REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer;
773
774 REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len
) return(16)
;
775
776 if ((stuff->format != XYPixmap1) && (stuff->format != ZPixmap2)) {
1
Taking false branch
777 client->errorValue = stuff->format;
778 return BadValue2;
779 }
780
781 rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
782 XRC_DRAWABLE, client, DixWriteAccess(1<<1));
783 if (rc != Success0)
2
Assuming 'rc' is equal to 0
3
Taking false branch
784 return (rc == BadValue2) ? BadDrawable9 : rc;
785
786 if (draw->type == XRT_PIXMAP)
4
Taking false branch
787 return ProcShmGetImage(client);
788
789 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess(1<<0));
790 if (rc != Success0)
5
Assuming 'rc' is equal to 0
6
Taking false branch
791 return rc;
792
793 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), stuff->shmseg, ShmSegType, client, (1<<0)
); if (tmprc != 0) return tmprc; }; if ((stuff->offset &
3) || (stuff->offset > shmdesc->size)) { client->
errorValue = stuff->offset; return 2; } if (1 && !
shmdesc->writable) return 10; }
;
794
795 x = stuff->x;
796 y = stuff->y;
797 w = stuff->width;
798 h = stuff->height;
799 format = stuff->format;
800 planemask = stuff->planeMask;
801
802 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
803
804 if (isRoot) {
7
Taking false branch
805 if ( /* check for being onscreen */
806 x < 0 || x + w > PanoramiXPixWidth ||
807 y < 0 || y + h > PanoramiXPixHeight)
808 return BadMatch8;
809 }
810 else {
811 if ( /* check for being onscreen */
8
Taking false branch
812 screenInfo.screens[0]->x + pDraw->x + x < 0 ||
813 screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth
814 || screenInfo.screens[0]->y + pDraw->y + y < 0 ||
815 screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight
816 ||
817 /* check for being inside of border */
818 x < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) ||
819 x + w > wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->width ||
820 y < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) ||
821 y + h > wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->height)
822 return BadMatch8;
823 }
824
825 drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
9
Memory is allocated
826 if (!drawables)
10
Assuming 'drawables' is non-null
11
Taking false branch
827 return BadAlloc11;
828
829 drawables[0] = pDraw;
830 FOR_NSCREENS_FORWARD_SKIP(i)for(i = 1; i < PanoramiXNumScreens; i++) {
831 rc = dixLookupDrawable(drawables + i, draw->info[i].id, client, 0,
832 DixReadAccess(1<<0));
833 if (rc != Success0) {
834 free(drawables);
835 return rc;
836 }
837 }
838
839 xgi = (xShmGetImageReply) {
840 .type = X_Reply1,
841 .sequenceNumber = client->sequence,
842 .length = 0,
843 .visual = wVisual(((WindowPtr) pDraw))((((WindowPtr) pDraw))->optional ? (((WindowPtr) pDraw))->
optional->visual : FindWindowWithOptional(((WindowPtr) pDraw
))->optional->visual)
,
844 .depth = pDraw->depth
845 };
846
847 if (format == ZPixmap2) {
12
Taking true branch
848 widthBytesLine = PixmapBytePad(w, pDraw->depth)((PixmapWidthPaddingInfo[pDraw->depth].notPower2 ? (((int)
(w) * PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel +
PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel) >>
PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2) : ((int
)((w) + PixmapWidthPaddingInfo[pDraw->depth].padRoundUp) >>
PixmapWidthPaddingInfo[pDraw->depth].padPixelsLog2)) <<
PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2)
;
849 length = widthBytesLine * h;
850 }
851 else {
852 widthBytesLine = PixmapBytePad(w, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(w) * PixmapWidthPaddingInfo
[1].bytesPerPixel + PixmapWidthPaddingInfo[1].bytesPerPixel) >>
PixmapWidthPaddingInfo[1].padBytesLog2) : ((int)((w) + PixmapWidthPaddingInfo
[1].padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2
)) << PixmapWidthPaddingInfo[1].padBytesLog2)
;
853 lenPer = widthBytesLine * h;
854 plane = ((Mask) 1) << (pDraw->depth - 1);
855 length = lenPer * Ones(planemask & (plane | (plane - 1)));
856 }
857
858 VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client){ if ((stuff->offset + length) > shmdesc->size) { return
10; } }
;
13
Within the expansion of the macro 'VERIFY_SHMSIZE':
a
Potential leak of memory pointed to by 'drawables'
859 xgi.size = length;
860
861 if (length == 0) { /* nothing to do */
862 }
863 else if (format == ZPixmap2) {
864 XineramaGetImageData(drawables, x, y, w, h, format, planemask,
865 shmdesc->addr + stuff->offset,
866 widthBytesLine, isRoot);
867 }
868 else {
869
870 length = stuff->offset;
871 for (; plane; plane >>= 1) {
872 if (planemask & plane) {
873 XineramaGetImageData(drawables, x, y, w, h,
874 format, plane, shmdesc->addr + length,
875 widthBytesLine, isRoot);
876 length += lenPer;
877 }
878 }
879 }
880 free(drawables);
881
882 if (client->swapped) {
883 swaps(&xgi.sequenceNumber)do { if (sizeof(*(&xgi.sequenceNumber)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&xgi.sequenceNumber
) & 1) && ((uintptr_t)(&xgi.sequenceNumber) &
1) == 0) *(&xgi.sequenceNumber) = lswaps(*(&xgi.sequenceNumber
)); else swap_uint16((uint16_t *)(&xgi.sequenceNumber)); }
while (0)
;
884 swapl(&xgi.length)do { if (sizeof(*(&xgi.length)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.length) & 3) && ((uintptr_t
)(&xgi.length) & 3) == 0) *(&xgi.length) = lswapl
(*(&xgi.length)); else swap_uint32((uint32_t *)(&xgi.
length)); } while (0)
;
885 swapl(&xgi.visual)do { if (sizeof(*(&xgi.visual)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.visual) & 3) && ((uintptr_t
)(&xgi.visual) & 3) == 0) *(&xgi.visual) = lswapl
(*(&xgi.visual)); else swap_uint32((uint32_t *)(&xgi.
visual)); } while (0)
;
886 swapl(&xgi.size)do { if (sizeof(*(&xgi.size)) != 4) wrong_size(); if (__builtin_constant_p
((uintptr_t)(&xgi.size) & 3) && ((uintptr_t)(
&xgi.size) & 3) == 0) *(&xgi.size) = lswapl(*(&
xgi.size)); else swap_uint32((uint32_t *)(&xgi.size)); } while
(0)
;
887 }
888 WriteToClient(client, sizeof(xShmGetImageReply), &xgi);
889
890 return Success0;
891}
892
893static int
894ProcPanoramiXShmCreatePixmap(ClientPtr client)
895{
896 ScreenPtr pScreen = NULL((void*)0);
897 PixmapPtr pMap = NULL((void*)0);
898 DrawablePtr pDraw;
899 DepthPtr pDepth;
900 int i, j, result, rc;
901 ShmDescPtr shmdesc;
902
903 REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client->
requestBuffer
;
904 unsigned int width, height, depth;
905 unsigned long size;
906 PanoramiXRes *newPix;
907
908 REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len
) return(16)
;
909 client->errorValue = stuff->pid;
910 if (!sharedPixmaps)
911 return BadImplementation17;
912 LEGAL_NEW_RESOURCE(stuff->pid, client)if (!LegalNewID(stuff->pid,client)) { client->errorValue
= stuff->pid; return 14; }
;
913 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY(-1),
914 DixGetAttrAccess(1<<4));
915 if (rc != Success0)
916 return rc;
917
918 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), stuff->shmseg, ShmSegType, client, (1<<0)
); if (tmprc != 0) return tmprc; }; if ((stuff->offset &
3) || (stuff->offset > shmdesc->size)) { client->
errorValue = stuff->offset; return 2; } if (1 && !
shmdesc->writable) return 10; }
;
919
920 width = stuff->width;
921 height = stuff->height;
922 depth = stuff->depth;
923 if (!width || !height || !depth) {
924 client->errorValue = 0;
925 return BadValue2;
926 }
927 if (width > 32767 || height > 32767)
928 return BadAlloc11;
929
930 if (stuff->depth != 1) {
931 pDepth = pDraw->pScreen->allowedDepths;
932 for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
933 if (pDepth->depth == stuff->depth)
934 goto CreatePmap;
935 client->errorValue = stuff->depth;
936 return BadValue2;
937 }
938
939 CreatePmap:
940 size = PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo
[depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel
) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int
)((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >>
PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo
[depth].padBytesLog2)
* height;
941 if (sizeof(size) == 4 && BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel) > 8) {
942 if (size < width * height)
943 return BadAlloc11;
944 }
945 /* thankfully, offset is unsigned */
946 if (stuff->offset + size < size)
947 return BadAlloc11;
948
949 VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client){ if ((stuff->offset + size) > shmdesc->size) { return
10; } }
;
950
951 if (!(newPix = malloc(sizeof(PanoramiXRes))))
952 return BadAlloc11;
953
954 newPix->type = XRT_PIXMAP;
955 newPix->u.pix.shared = TRUE1;
956 panoramix_setup_ids(newPix, client, stuff->pid);
957
958 result = Success0;
959
960 FOR_NSCREENS(j)for(j = 0; j < PanoramiXNumScreens; j++) {
961 ShmScrPrivateRec *screen_priv;
962
963 pScreen = screenInfo.screens[j];
964
965 screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates
, (&shmScrPrivateKeyRec)))
;
966 pMap = (*screen_priv->shmFuncs->CreatePixmap) (pScreen,
967 stuff->width,
968 stuff->height,
969 stuff->depth,
970 shmdesc->addr +
971 stuff->offset);
972
973 if (pMap) {
974 result = XaceHook(XACE_RESOURCE_ACCESS2, client, stuff->pid,
975 RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), pMap, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3));
976 if (result != Success0) {
977 pDraw->pScreen->DestroyPixmap(pMap);
978 return result;
979 }
980 dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec), shmdesc);
981 shmdesc->refcnt++;
982 pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber
= 1): globalSerialNumber)
;
983 pMap->drawable.id = newPix->info[j].id;
984 if (!AddResourceDarwin_X_AddResource(newPix->info[j].id, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), (void *) pMap)) {
985 result = BadAlloc11;
986 break;
987 }
988 }
989 else {
990 result = BadAlloc11;
991 break;
992 }
993 }
994
995 if (result == BadAlloc11) {
996 while (j--)
997 FreeResource(newPix->info[j].id, RT_NONE((RESTYPE)0));
998 free(newPix);
999 }
1000 else
1001 AddResourceDarwin_X_AddResource(stuff->pid, XRT_PIXMAP, newPix);
1002
1003 return result;
1004}
1005#endif
1006
1007static PixmapPtr
1008fbShmCreatePixmap(ScreenPtr pScreen,
1009 int width, int height, int depth, char *addr)
1010{
1011 PixmapPtr pPixmap;
1012
1013 pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
1014 if (!pPixmap)
1015 return NullPixmap((PixmapPtr)0);
1016
1017 if (!(*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth,
1018 BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel),
1019 PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo
[depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel
) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int
)((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >>
PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo
[depth].padBytesLog2)
,
1020 (void *) addr)) {
1021 (*pScreen->DestroyPixmap) (pPixmap);
1022 return NullPixmap((PixmapPtr)0);
1023 }
1024 return pPixmap;
1025}
1026
1027static int
1028ProcShmCreatePixmap(ClientPtr client)
1029{
1030 PixmapPtr pMap;
1031 DrawablePtr pDraw;
1032 DepthPtr pDepth;
1033 int i, rc;
1034 ShmDescPtr shmdesc;
1035 ShmScrPrivateRec *screen_priv;
1036
1037 REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client->
requestBuffer
;
1038 unsigned int width, height, depth;
1039 unsigned long size;
1040
1041 REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len
) return(16)
;
1042 client->errorValue = stuff->pid;
1043 if (!sharedPixmaps)
1044 return BadImplementation17;
1045 LEGAL_NEW_RESOURCE(stuff->pid, client)if (!LegalNewID(stuff->pid,client)) { client->errorValue
= stuff->pid; return 14; }
;
1046 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY(-1),
1047 DixGetAttrAccess(1<<4));
1048 if (rc != Success0)
1049 return rc;
1050
1051 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)&
(shmdesc), stuff->shmseg, ShmSegType, client, (1<<0)
); if (tmprc != 0) return tmprc; }; if ((stuff->offset &
3) || (stuff->offset > shmdesc->size)) { client->
errorValue = stuff->offset; return 2; } if (1 && !
shmdesc->writable) return 10; }
;
1052
1053 width = stuff->width;
1054 height = stuff->height;
1055 depth = stuff->depth;
1056 if (!width || !height || !depth) {
1057 client->errorValue = 0;
1058 return BadValue2;
1059 }
1060 if (width > 32767 || height > 32767)
1061 return BadAlloc11;
1062
1063 if (stuff->depth != 1) {
1064 pDepth = pDraw->pScreen->allowedDepths;
1065 for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
1066 if (pDepth->depth == stuff->depth)
1067 goto CreatePmap;
1068 client->errorValue = stuff->depth;
1069 return BadValue2;
1070 }
1071
1072 CreatePmap:
1073 size = PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo
[depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel
) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int
)((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >>
PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo
[depth].padBytesLog2)
* height;
1074 if (sizeof(size) == 4 && BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel) > 8) {
1075 if (size < width * height)
1076 return BadAlloc11;
1077 }
1078 /* thankfully, offset is unsigned */
1079 if (stuff->offset + size < size)
1080 return BadAlloc11;
1081
1082 VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client){ if ((stuff->offset + size) > shmdesc->size) { return
10; } }
;
1083 screen_priv = ShmGetScreenPriv(pDraw->pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pDraw->pScreen
)->devPrivates, (&shmScrPrivateKeyRec)))
;
1084 pMap = (*screen_priv->shmFuncs->CreatePixmap) (pDraw->pScreen, stuff->width,
1085 stuff->height, stuff->depth,
1086 shmdesc->addr +
1087 stuff->offset);
1088 if (pMap) {
1089 rc = XaceHook(XACE_RESOURCE_ACCESS2, client, stuff->pid, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)),
1090 pMap, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3));
1091 if (rc != Success0) {
1092 pDraw->pScreen->DestroyPixmap(pMap);
1093 return rc;
1094 }
1095 dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec), shmdesc);
1096 shmdesc->refcnt++;
1097 pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber
= 1): globalSerialNumber)
;
1098 pMap->drawable.id = stuff->pid;
1099 if (AddResourceDarwin_X_AddResource(stuff->pid, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), (void *) pMap)) {
1100 return Success0;
1101 }
1102 }
1103 return BadAlloc11;
1104}
1105
1106#ifdef SHM_FD_PASSING
1107
1108static void
1109ShmBusfaultNotify(void *context)
1110{
1111 ShmDescPtr shmdesc = context;
1112
1113 ErrorF("shared memory 0x%x truncated by client\n",
1114 (unsigned int) shmdesc->resource);
1115 busfault_unregister(shmdesc->busfault);
1116 shmdesc->busfault = NULL((void*)0);
1117 FreeResource (shmdesc->resource, RT_NONE((RESTYPE)0));
1118}
1119
1120static int
1121ProcShmAttachFd(ClientPtr client)
1122{
1123 int fd;
1124 ShmDescPtr shmdesc;
1125 REQUEST(xShmAttachFdReq)xShmAttachFdReq *stuff = (xShmAttachFdReq *)client->requestBuffer;
1126 struct stat statb;
1127
1128 SetReqFds(client, 1);
1129 REQUEST_SIZE_MATCH(xShmAttachFdReq)if ((sizeof(xShmAttachFdReq) >> 2) != client->req_len
) return(16)
;
1130 LEGAL_NEW_RESOURCE(stuff->shmseg, client)if (!LegalNewID(stuff->shmseg,client)) { client->errorValue
= stuff->shmseg; return 14; }
;
1131 if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) {
1132 client->errorValue = stuff->readOnly;
1133 return BadValue2;
1134 }
1135 fd = ReadFdFromClient(client);
1136 if (fd < 0)
1137 return BadMatch8;
1138
1139 if (fstat(fd, &statb) < 0 || statb.st_size == 0) {
1140 close(fd);
1141 return BadMatch8;
1142 }
1143
1144 shmdesc = malloc(sizeof(ShmDescRec));
1145 if (!shmdesc) {
1146 close(fd);
1147 return BadAlloc11;
1148 }
1149 shmdesc->is_fd = TRUE1;
1150 shmdesc->addr = mmap(NULL((void*)0), statb.st_size,
1151 stuff->readOnly ? PROT_READ0x01 : PROT_READ0x01|PROT_WRITE0x02,
1152 MAP_SHARED0x0001,
1153 fd, 0);
1154
1155 close(fd);
1156 if (shmdesc->addr == ((char *) -1)) {
1157 free(shmdesc);
1158 return BadAccess10;
1159 }
1160
1161 shmdesc->refcnt = 1;
1162 shmdesc->writable = !stuff->readOnly;
1163 shmdesc->size = statb.st_size;
1164 shmdesc->resource = stuff->shmseg;
1165
1166 shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc);
1167 if (!shmdesc->busfault) {
1168 munmap(shmdesc->addr, shmdesc->size);
1169 free(shmdesc);
1170 return BadAlloc11;
1171 }
1172
1173 shmdesc->next = Shmsegs;
1174 Shmsegs = shmdesc;
1175
1176 if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc))
1177 return BadAlloc11;
1178 return Success0;
1179}
1180
1181static int
1182shm_tmpfile(void)
1183{
1184#ifdef SHMDIR"/var/tmp"
1185 int fd;
1186 int flags;
1187 char template[] = SHMDIR"/var/tmp" "/shmfd-XXXXXX";
1188#ifdef O_TMPFILE
1189 fd = open(SHMDIR"/var/tmp", O_TMPFILE|O_RDWR0x0002|O_CLOEXEC0x1000000|O_EXCL0x0800, 0666);
1190 if (fd >= 0) {
1191 ErrorF ("Using O_TMPFILE\n");
1192 return fd;
1193 }
1194 ErrorF ("Not using O_TMPFILE\n");
1195#endif
1196 fd = mkstemp(template);
1197 if (fd < 0)
1198 return -1;
1199 unlink(template);
1200 if (fcntl(fd, F_GETFD1, &flags) >= 0) {
1201 flags |= FD_CLOEXEC1;
1202 (void) fcntl(fd, F_SETFD2, &flags);
1203 }
1204 return fd;
1205#else
1206 return -1;
1207#endif
1208}
1209
1210static int
1211ProcShmCreateSegment(ClientPtr client)
1212{
1213 int fd;
1214 ShmDescPtr shmdesc;
1215 REQUEST(xShmCreateSegmentReq)xShmCreateSegmentReq *stuff = (xShmCreateSegmentReq *)client->
requestBuffer
;
1216 xShmCreateSegmentReply rep = {
1217 .type = X_Reply1,
1218 .nfd = 1,
1219 .sequenceNumber = client->sequence,
1220 .length = 0,
1221 };
1222
1223 REQUEST_SIZE_MATCH(xShmCreateSegmentReq)if ((sizeof(xShmCreateSegmentReq) >> 2) != client->req_len
) return(16)
;
1224 if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) {
1225 client->errorValue = stuff->readOnly;
1226 return BadValue2;
1227 }
1228 fd = shm_tmpfile();
1229 if (fd < 0)
1230 return BadAlloc11;
1231 if (ftruncate(fd, stuff->size) < 0) {
1232 close(fd);
1233 return BadAlloc11;
1234 }
1235 shmdesc = malloc(sizeof(ShmDescRec));
1236 if (!shmdesc) {
1237 close(fd);
1238 return BadAlloc11;
1239 }
1240 shmdesc->is_fd = TRUE1;
1241 shmdesc->addr = mmap(NULL((void*)0), stuff->size,
1242 stuff->readOnly ? PROT_READ0x01 : PROT_READ0x01|PROT_WRITE0x02,
1243 MAP_SHARED0x0001,
1244 fd, 0);
1245
1246 if (shmdesc->addr == ((char *) -1)) {
1247 close(fd);
1248 free(shmdesc);
1249 return BadAccess10;
1250 }
1251
1252 shmdesc->refcnt = 1;
1253 shmdesc->writable = !stuff->readOnly;
1254 shmdesc->size = stuff->size;
1255
1256 shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc);
1257 if (!shmdesc->busfault) {
1258 close(fd);
1259 munmap(shmdesc->addr, shmdesc->size);
1260 free(shmdesc);
1261 return BadAlloc11;
1262 }
1263
1264 shmdesc->next = Shmsegs;
1265 Shmsegs = shmdesc;
1266
1267 if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc)) {
1268 close(fd);
1269 return BadAlloc11;
1270 }
1271
1272 if (WriteFdToClient(client, fd, TRUE1) < 0) {
1273 FreeResource(stuff->shmseg, RT_NONE((RESTYPE)0));
1274 close(fd);
1275 return BadAlloc11;
1276 }
1277 WriteToClient(client, sizeof (xShmCreateSegmentReply), &rep);
1278 return Success0;
1279}
1280#endif /* SHM_FD_PASSING */
1281
1282static int
1283ProcShmDispatch(ClientPtr client)
1284{
1285 REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer;
1286 switch (stuff->data) {
1287 case X_ShmQueryVersion0:
1288 return ProcShmQueryVersion(client);
1289 case X_ShmAttach1:
1290 return ProcShmAttach(client);
1291 case X_ShmDetach2:
1292 return ProcShmDetach(client);
1293 case X_ShmPutImage3:
1294#ifdef PANORAMIX1
1295 if (!noPanoramiXExtension)
1296 return ProcPanoramiXShmPutImage(client);
1297#endif
1298 return ProcShmPutImage(client);
1299 case X_ShmGetImage4:
1300#ifdef PANORAMIX1
1301 if (!noPanoramiXExtension)
1302 return ProcPanoramiXShmGetImage(client);
1303#endif
1304 return ProcShmGetImage(client);
1305 case X_ShmCreatePixmap5:
1306#ifdef PANORAMIX1
1307 if (!noPanoramiXExtension)
1308 return ProcPanoramiXShmCreatePixmap(client);
1309#endif
1310 return ProcShmCreatePixmap(client);
1311#ifdef SHM_FD_PASSING
1312 case X_ShmAttachFd6:
1313 return ProcShmAttachFd(client);
1314 case X_ShmCreateSegment7:
1315 return ProcShmCreateSegment(client);
1316#endif
1317 default:
1318 return BadRequest1;
1319 }
1320}
1321
1322static void
1323SShmCompletionEvent(xShmCompletionEvent * from, xShmCompletionEvent * to)
1324{
1325 to->type = from->type;
1326 cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to
->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber
) = lswaps((from->sequenceNumber)); } while (0)
;
1327 cpswapl(from->drawable, to->drawable)do { if (sizeof((from->drawable)) != 4 || sizeof((to->drawable
)) != 4) wrong_size(); (to->drawable) = lswapl((from->drawable
)); } while (0)
;
1328 cpswaps(from->minorEvent, to->minorEvent)do { if (sizeof((from->minorEvent)) != 2 || sizeof((to->
minorEvent)) != 2) wrong_size(); (to->minorEvent) = lswaps
((from->minorEvent)); } while (0)
;
1329 to->majorEvent = from->majorEvent;
1330 cpswapl(from->shmseg, to->shmseg)do { if (sizeof((from->shmseg)) != 4 || sizeof((to->shmseg
)) != 4) wrong_size(); (to->shmseg) = lswapl((from->shmseg
)); } while (0)
;
1331 cpswapl(from->offset, to->offset)do { if (sizeof((from->offset)) != 4 || sizeof((to->offset
)) != 4) wrong_size(); (to->offset) = lswapl((from->offset
)); } while (0)
;
1332}
1333
1334static int
1335SProcShmQueryVersion(ClientPtr client)
1336{
1337 REQUEST(xShmQueryVersionReq)xShmQueryVersionReq *stuff = (xShmQueryVersionReq *)client->
requestBuffer
;
1338
1339 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1340 return ProcShmQueryVersion(client);
1341}
1342
1343static int
1344SProcShmAttach(ClientPtr client)
1345{
1346 REQUEST(xShmAttachReq)xShmAttachReq *stuff = (xShmAttachReq *)client->requestBuffer;
1347 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1348 REQUEST_SIZE_MATCH(xShmAttachReq)if ((sizeof(xShmAttachReq) >> 2) != client->req_len)
return(16)
;
1349 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1350 swapl(&stuff->shmid)do { if (sizeof(*(&stuff->shmid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->shmid) &
3) && ((uintptr_t)(&stuff->shmid) & 3) ==
0) *(&stuff->shmid) = lswapl(*(&stuff->shmid))
; else swap_uint32((uint32_t *)(&stuff->shmid)); } while
(0)
;
1351 return ProcShmAttach(client);
1352}
1353
1354static int
1355SProcShmDetach(ClientPtr client)
1356{
1357 REQUEST(xShmDetachReq)xShmDetachReq *stuff = (xShmDetachReq *)client->requestBuffer;
1358 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1359 REQUEST_SIZE_MATCH(xShmDetachReq)if ((sizeof(xShmDetachReq) >> 2) != client->req_len)
return(16)
;
1360 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1361 return ProcShmDetach(client);
1362}
1363
1364static int
1365SProcShmPutImage(ClientPtr client)
1366{
1367 REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer;
1368 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1369 REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len
) return(16)
;
1370 swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->drawable
) & 3) && ((uintptr_t)(&stuff->drawable) &
3) == 0) *(&stuff->drawable) = lswapl(*(&stuff->
drawable)); else swap_uint32((uint32_t *)(&stuff->drawable
)); } while (0)
;
1371 swapl(&stuff->gc)do { if (sizeof(*(&stuff->gc)) != 4) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->gc) & 3) &&
((uintptr_t)(&stuff->gc) & 3) == 0) *(&stuff->
gc) = lswapl(*(&stuff->gc)); else swap_uint32((uint32_t
*)(&stuff->gc)); } while (0)
;
1372 swaps(&stuff->totalWidth)do { if (sizeof(*(&stuff->totalWidth)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->totalWidth
) & 1) && ((uintptr_t)(&stuff->totalWidth)
& 1) == 0) *(&stuff->totalWidth) = lswaps(*(&
stuff->totalWidth)); else swap_uint16((uint16_t *)(&stuff
->totalWidth)); } while (0)
;
1373 swaps(&stuff->totalHeight)do { if (sizeof(*(&stuff->totalHeight)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->totalHeight
) & 1) && ((uintptr_t)(&stuff->totalHeight
) & 1) == 0) *(&stuff->totalHeight) = lswaps(*(&
stuff->totalHeight)); else swap_uint16((uint16_t *)(&stuff
->totalHeight)); } while (0)
;
1374 swaps(&stuff->srcX)do { if (sizeof(*(&stuff->srcX)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->srcX) &
1) && ((uintptr_t)(&stuff->srcX) & 1) == 0
) *(&stuff->srcX) = lswaps(*(&stuff->srcX)); else
swap_uint16((uint16_t *)(&stuff->srcX)); } while (0)
;
1375 swaps(&stuff->srcY)do { if (sizeof(*(&stuff->srcY)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->srcY) &
1) && ((uintptr_t)(&stuff->srcY) & 1) == 0
) *(&stuff->srcY) = lswaps(*(&stuff->srcY)); else
swap_uint16((uint16_t *)(&stuff->srcY)); } while (0)
;
1376 swaps(&stuff->srcWidth)do { if (sizeof(*(&stuff->srcWidth)) != 2) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->srcWidth
) & 1) && ((uintptr_t)(&stuff->srcWidth) &
1) == 0) *(&stuff->srcWidth) = lswaps(*(&stuff->
srcWidth)); else swap_uint16((uint16_t *)(&stuff->srcWidth
)); } while (0)
;
1377 swaps(&stuff->srcHeight)do { if (sizeof(*(&stuff->srcHeight)) != 2) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->srcHeight
) & 1) && ((uintptr_t)(&stuff->srcHeight) &
1) == 0) *(&stuff->srcHeight) = lswaps(*(&stuff->
srcHeight)); else swap_uint16((uint16_t *)(&stuff->srcHeight
)); } while (0)
;
1378 swaps(&stuff->dstX)do { if (sizeof(*(&stuff->dstX)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->dstX) &
1) && ((uintptr_t)(&stuff->dstX) & 1) == 0
) *(&stuff->dstX) = lswaps(*(&stuff->dstX)); else
swap_uint16((uint16_t *)(&stuff->dstX)); } while (0)
;
1379 swaps(&stuff->dstY)do { if (sizeof(*(&stuff->dstY)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->dstY) &
1) && ((uintptr_t)(&stuff->dstY) & 1) == 0
) *(&stuff->dstY) = lswaps(*(&stuff->dstY)); else
swap_uint16((uint16_t *)(&stuff->dstY)); } while (0)
;
1380 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1381 swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->offset) &
3) && ((uintptr_t)(&stuff->offset) & 3) ==
0) *(&stuff->offset) = lswapl(*(&stuff->offset
)); else swap_uint32((uint32_t *)(&stuff->offset)); } while
(0)
;
1382 return ProcShmPutImage(client);
1383}
1384
1385static int
1386SProcShmGetImage(ClientPtr client)
1387{
1388 REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer;
1389 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1390 REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len
) return(16)
;
1391 swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->drawable
) & 3) && ((uintptr_t)(&stuff->drawable) &
3) == 0) *(&stuff->drawable) = lswapl(*(&stuff->
drawable)); else swap_uint32((uint32_t *)(&stuff->drawable
)); } while (0)
;
1392 swaps(&stuff->x)do { if (sizeof(*(&stuff->x)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->x) & 1) &&
((uintptr_t)(&stuff->x) & 1) == 0) *(&stuff->
x) = lswaps(*(&stuff->x)); else swap_uint16((uint16_t *
)(&stuff->x)); } while (0)
;
1393 swaps(&stuff->y)do { if (sizeof(*(&stuff->y)) != 2) wrong_size(); if (
__builtin_constant_p((uintptr_t)(&stuff->y) & 1) &&
((uintptr_t)(&stuff->y) & 1) == 0) *(&stuff->
y) = lswaps(*(&stuff->y)); else swap_uint16((uint16_t *
)(&stuff->y)); } while (0)
;
1394 swaps(&stuff->width)do { if (sizeof(*(&stuff->width)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->width) &
1) && ((uintptr_t)(&stuff->width) & 1) ==
0) *(&stuff->width) = lswaps(*(&stuff->width))
; else swap_uint16((uint16_t *)(&stuff->width)); } while
(0)
;
1395 swaps(&stuff->height)do { if (sizeof(*(&stuff->height)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->height) &
1) && ((uintptr_t)(&stuff->height) & 1) ==
0) *(&stuff->height) = lswaps(*(&stuff->height
)); else swap_uint16((uint16_t *)(&stuff->height)); } while
(0)
;
1396 swapl(&stuff->planeMask)do { if (sizeof(*(&stuff->planeMask)) != 4) wrong_size
(); if (__builtin_constant_p((uintptr_t)(&stuff->planeMask
) & 3) && ((uintptr_t)(&stuff->planeMask) &
3) == 0) *(&stuff->planeMask) = lswapl(*(&stuff->
planeMask)); else swap_uint32((uint32_t *)(&stuff->planeMask
)); } while (0)
;
1397 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1398 swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->offset) &
3) && ((uintptr_t)(&stuff->offset) & 3) ==
0) *(&stuff->offset) = lswapl(*(&stuff->offset
)); else swap_uint32((uint32_t *)(&stuff->offset)); } while
(0)
;
1399 return ProcShmGetImage(client);
1400}
1401
1402static int
1403SProcShmCreatePixmap(ClientPtr client)
1404{
1405 REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client->
requestBuffer
;
1406 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1407 REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len
) return(16)
;
1408 swapl(&stuff->pid)do { if (sizeof(*(&stuff->pid)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->pid) & 3
) && ((uintptr_t)(&stuff->pid) & 3) == 0) *
(&stuff->pid) = lswapl(*(&stuff->pid)); else swap_uint32
((uint32_t *)(&stuff->pid)); } while (0)
;
1409 swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size(
); if (__builtin_constant_p((uintptr_t)(&stuff->drawable
) & 3) && ((uintptr_t)(&stuff->drawable) &
3) == 0) *(&stuff->drawable) = lswapl(*(&stuff->
drawable)); else swap_uint32((uint32_t *)(&stuff->drawable
)); } while (0)
;
1410 swaps(&stuff->width)do { if (sizeof(*(&stuff->width)) != 2) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->width) &
1) && ((uintptr_t)(&stuff->width) & 1) ==
0) *(&stuff->width) = lswaps(*(&stuff->width))
; else swap_uint16((uint16_t *)(&stuff->width)); } while
(0)
;
1411 swaps(&stuff->height)do { if (sizeof(*(&stuff->height)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->height) &
1) && ((uintptr_t)(&stuff->height) & 1) ==
0) *(&stuff->height) = lswaps(*(&stuff->height
)); else swap_uint16((uint16_t *)(&stuff->height)); } while
(0)
;
1412 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1413 swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->offset) &
3) && ((uintptr_t)(&stuff->offset) & 3) ==
0) *(&stuff->offset) = lswapl(*(&stuff->offset
)); else swap_uint32((uint32_t *)(&stuff->offset)); } while
(0)
;
1414 return ProcShmCreatePixmap(client);
1415}
1416
1417#ifdef SHM_FD_PASSING
1418static int
1419SProcShmAttachFd(ClientPtr client)
1420{
1421 REQUEST(xShmAttachFdReq)xShmAttachFdReq *stuff = (xShmAttachFdReq *)client->requestBuffer;
1422 SetReqFds(client, 1);
1423 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1424 REQUEST_SIZE_MATCH(xShmAttachFdReq)if ((sizeof(xShmAttachFdReq) >> 2) != client->req_len
) return(16)
;
1425 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1426 return ProcShmAttachFd(client);
1427}
1428
1429static int
1430SProcShmCreateSegment(ClientPtr client)
1431{
1432 REQUEST(xShmCreateSegmentReq)xShmCreateSegmentReq *stuff = (xShmCreateSegmentReq *)client->
requestBuffer
;
1433 swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->length) &
1) && ((uintptr_t)(&stuff->length) & 1) ==
0) *(&stuff->length) = lswaps(*(&stuff->length
)); else swap_uint16((uint16_t *)(&stuff->length)); } while
(0)
;
1434 REQUEST_SIZE_MATCH(xShmCreateSegmentReq)if ((sizeof(xShmCreateSegmentReq) >> 2) != client->req_len
) return(16)
;
1435 swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size();
if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) &
3) && ((uintptr_t)(&stuff->shmseg) & 3) ==
0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg
)); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while
(0)
;
1436 swapl(&stuff->size)do { if (sizeof(*(&stuff->size)) != 4) wrong_size(); if
(__builtin_constant_p((uintptr_t)(&stuff->size) &
3) && ((uintptr_t)(&stuff->size) & 3) == 0
) *(&stuff->size) = lswapl(*(&stuff->size)); else
swap_uint32((uint32_t *)(&stuff->size)); } while (0)
;
1437 return ProcShmCreateSegment(client);
1438}
1439#endif /* SHM_FD_PASSING */
1440
1441static int
1442SProcShmDispatch(ClientPtr client)
1443{
1444 REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer;
1445 switch (stuff->data) {
1446 case X_ShmQueryVersion0:
1447 return SProcShmQueryVersion(client);
1448 case X_ShmAttach1:
1449 return SProcShmAttach(client);
1450 case X_ShmDetach2:
1451 return SProcShmDetach(client);
1452 case X_ShmPutImage3:
1453 return SProcShmPutImage(client);
1454 case X_ShmGetImage4:
1455 return SProcShmGetImage(client);
1456 case X_ShmCreatePixmap5:
1457 return SProcShmCreatePixmap(client);
1458#ifdef SHM_FD_PASSING
1459 case X_ShmAttachFd6:
1460 return SProcShmAttachFd(client);
1461 case X_ShmCreateSegment7:
1462 return SProcShmCreateSegment(client);
1463#endif
1464 default:
1465 return BadRequest1;
1466 }
1467}
1468
1469void
1470ShmExtensionInit(void)
1471{
1472 ExtensionEntry *extEntry;
1473 int i;
1474
1475#ifdef MUST_CHECK_FOR_SHM_SYSCALL
1476 if (!CheckForShmSyscall()) {
1477 ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
1478 return;
1479 }
1480#endif
1481
1482 if (!ShmRegisterPrivates())
1483 return;
1484
1485 sharedPixmaps = xFalse0;
1486 {
1487 sharedPixmaps = xTrue1;
1488 for (i = 0; i < screenInfo.numScreens; i++) {
1489 ShmScrPrivateRec *screen_priv =
1490 ShmInitScreenPriv(screenInfo.screens[i]);
1491 if (!screen_priv->shmFuncs)
1492 screen_priv->shmFuncs = &miFuncs;
1493 if (!screen_priv->shmFuncs->CreatePixmap)
1494 sharedPixmaps = xFalse0;
1495 }
1496 if (sharedPixmaps)
1497 for (i = 0; i < screenInfo.numScreens; i++) {
1498 ShmScrPrivateRec *screen_priv =
1499 ShmGetScreenPriv(screenInfo.screens[i])((ShmScrPrivateRec *)dixLookupPrivate(&(screenInfo.screens
[i])->devPrivates, (&shmScrPrivateKeyRec)))
;
1500 screen_priv->destroyPixmap =
1501 screenInfo.screens[i]->DestroyPixmap;
1502 screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
1503 }
1504 }
1505 ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
1506 if (ShmSegType &&
1507 (extEntry = AddExtension(SHMNAME"MIT-SHM", ShmNumberEvents(0 + 1), ShmNumberErrors(0 + 1),
1508 ProcShmDispatch, SProcShmDispatch,
1509 ShmResetProc, StandardMinorOpcode))) {
1510 ShmReqCode = (unsigned char) extEntry->base;
1511 ShmCompletionCode = extEntry->eventBase;
1512 BadShmSegCode = extEntry->errorBase;
1513 SetResourceTypeErrorValue(ShmSegType, BadShmSegCode);
1514 EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
1515 }
1516}