diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/NXshm.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/nxagent/NXshm.c | 161 |
1 files changed, 117 insertions, 44 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c index e70415a7d..eaaa92041 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c @@ -1,10 +1,21 @@ -#ifdef NXAGENT_UPGRADE - -#include "X/NXshm.c" - -#else - -/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.36 2002/04/03 19:51:11 herrb Exp $ */ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NXAGENT, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */ /************************************************************ Copyright 1989, 1998 The Open Group @@ -35,6 +46,12 @@ in this Software without prior written authorization from The Open Group. /* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */ +#define SHM + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + #include <sys/types.h> #ifndef Lynx #include <sys/ipc.h> @@ -47,8 +64,8 @@ in this Software without prior written authorization from The Open Group. #include <sys/stat.h> #define NEED_REPLIES #define NEED_EVENTS -#include "X.h" -#include "Xproto.h" +#include <X11/X.h> +#include <X11/Xproto.h> #include "misc.h" #include "os.h" #include "dixstruct.h" @@ -60,8 +77,8 @@ in this Software without prior written authorization from The Open Group. #include "extnsionst.h" #include "servermd.h" #define _XSHM_SERVER_ -#include "shmstr.h" -#include "Xfuncproto.h" +#include <X11/extensions/shmstr.h> +#include <X11/Xfuncproto.h> #ifdef EXTMODULE #include "xf86_ansic.h" #endif @@ -71,6 +88,8 @@ in this Software without prior written authorization from The Open Group. #include "panoramiXsrv.h" #endif +#include "modinit.h" + #include "Trap.h" #include "Agent.h" #include "Drawable.h" @@ -85,6 +104,10 @@ in this Software without prior written authorization from The Open Group. #undef TEST #undef DEBUG +#ifdef TEST +#include "Literals.h" +#endif + extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); @@ -105,21 +128,15 @@ static void miShmPutImage(XSHM_PUT_IMAGE_ARGS); static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS); static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); static int ShmDetachSegment( -#if NeedFunctionPrototypes pointer /* value */, XID /* shmseg */ -#endif ); static void ShmResetProc( -#if NeedFunctionPrototypes ExtensionEntry * /* extEntry */ -#endif ); static void SShmCompletionEvent( -#if NeedFunctionPrototypes xShmCompletionEvent * /* from */, xShmCompletionEvent * /* to */ -#endif ); static Bool ShmDestroyPixmap (PixmapPtr pPixmap); @@ -208,23 +225,32 @@ static Bool CheckForShmSyscall() badSysCall = FALSE; shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); - /* Clean up */ + if (shmid != -1) { + /* Successful allocation - clean up */ shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL); } + else + { + /* Allocation failed */ + badSysCall = TRUE; + } signal(SIGSYS, oldHandler); return(!badSysCall); } + +#define MUST_CHECK_FOR_SHM_SYSCALL + #endif - + void -ShmExtensionInit() +ShmExtensionInit(INITARGS) { ExtensionEntry *extEntry; int i; -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) +#ifdef MUST_CHECK_FOR_SHM_SYSCALL if (!CheckForShmSyscall()) { ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); @@ -307,17 +333,17 @@ ExtensionEntry *extEntry; } void -ShmRegisterFuncs(pScreen, funcs) - ScreenPtr pScreen; - ShmFuncsPtr funcs; +ShmRegisterFuncs( + ScreenPtr pScreen, + ShmFuncsPtr funcs) { shmFuncs[pScreen->myNum] = funcs; } void -ShmSetPixmapFormat(pScreen, format) - ScreenPtr pScreen; - int format; +ShmSetPixmapFormat( + ScreenPtr pScreen, + int format) { shmPixFormat[pScreen->myNum] = format; } @@ -661,8 +687,7 @@ ProcPanoramiXShmPutImage(register ClientPtr client) client, stuff->gc, XRT_GC, SecurityReadAccess))) return BadGC; - isRoot = (draw->type == XRT_WINDOW) && - (stuff->drawable == WindowTable[0]->drawable.id); + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; orig_x = stuff->dstX; orig_y = stuff->dstY; @@ -722,8 +747,7 @@ ProcPanoramiXShmGetImage(ClientPtr client) format = stuff->format; planemask = stuff->planeMask; - isRoot = (draw->type == XRT_WINDOW) && - (stuff->drawable == WindowTable[0]->drawable.id); + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; if(isRoot) { if( /* check for being onscreen */ @@ -798,8 +822,8 @@ ProcPanoramiXShmGetImage(ClientPtr client) } static int -ProcPanoramiXShmCreatePixmap(client) - register ClientPtr client; +ProcPanoramiXShmCreatePixmap( + register ClientPtr client) { ScreenPtr pScreen = NULL; PixmapPtr pMap = NULL; @@ -808,6 +832,8 @@ ProcPanoramiXShmCreatePixmap(client) int i, j, result; ShmDescPtr shmdesc; REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; PanoramiXRes *newPix; REQUEST_SIZE_MATCH(xShmCreatePixmapReq); @@ -817,11 +843,18 @@ ProcPanoramiXShmCreatePixmap(client) LEGAL_NEW_RESOURCE(stuff->pid, client); VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client); VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - if (!stuff->width || !stuff->height) + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) { client->errorValue = 0; return BadValue; } + if (width > 32767 || height > 32767) + return BadAlloc; + if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; @@ -831,10 +864,18 @@ ProcPanoramiXShmCreatePixmap(client) client->errorValue = stuff->depth; return BadValue; } + CreatePmap: - VERIFY_SHMSIZE(shmdesc, stuff->offset, - PixmapBytePad(stuff->width, stuff->depth) * stuff->height, - client); + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)))) return BadAlloc; @@ -926,8 +967,17 @@ ProcShmPutImage(client) return BadValue; } - VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, - client); + /* + * There's a potential integer overflow in this check: + * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, + * client); + * the version below ought to avoid it + */ + if (stuff->totalHeight != 0 && + length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { + client->errorValue = stuff->totalWidth; + return BadValue; + } if (stuff->srcX > stuff->totalWidth) { client->errorValue = stuff->srcX; @@ -1150,6 +1200,8 @@ ProcShmCreatePixmap(client) register int i; ShmDescPtr shmdesc; REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; REQUEST_SIZE_MATCH(xShmCreatePixmapReq); client->errorValue = stuff->pid; @@ -1158,11 +1210,18 @@ ProcShmCreatePixmap(client) LEGAL_NEW_RESOURCE(stuff->pid, client); VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client); VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - if (!stuff->width || !stuff->height) + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) { client->errorValue = 0; return BadValue; } + if (width > 32767 || height > 32767) + return BadAlloc; + if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; @@ -1172,10 +1231,18 @@ ProcShmCreatePixmap(client) client->errorValue = stuff->depth; return BadValue; } + CreatePmap: - VERIFY_SHMSIZE(shmdesc, stuff->offset, - PixmapBytePad(stuff->width, stuff->depth) * stuff->height, - client); + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)( pDraw->pScreen, stuff->width, stuff->height, stuff->depth, @@ -1205,6 +1272,12 @@ ProcShmDispatch (client) #ifdef TEST fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", stuff -> data, client -> index); + + if (stuff->data <= X_ShmCreatePixmap) + { + fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n", + nxagentShmRequestLiteral[stuff->data], stuff->data); + } #endif switch (stuff->data) @@ -1364,6 +1437,7 @@ SProcShmCreatePixmap(client) REQUEST(xShmCreatePixmapReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + swapl(&stuff->pid, n); swapl(&stuff->drawable, n); swaps(&stuff->width, n); swaps(&stuff->height, n); @@ -1422,4 +1496,3 @@ SProcShmDispatch (client) } } -#endif /* #ifdef NXAGENT_UPGRADE */ |