6426302 [tjds] capturing screen using sdtimage crashes Xserver
authorLokanath Das <Lokanath.Das@Sun.COM>
Thu, 21 Sep 2006 15:42:39 -0700
changeset 64 c03273ff2fb9
parent 63 839379b2eac2
child 65 0fe232a00381
6426302 [tjds] capturing screen using sdtimage crashes Xserver 6432709 [TX,atok] atok pallet disappear on non admin label when moving the position 6432729 TrustedExtensionsPolicy file should be updated for Japanese Input method 6459852 [tjds] gnome-panel-screenshot cores - hangs desktop
XORG_NV/sun-src/xc/programs/Xserver/tsol/TrustedExtensionsPolicy
XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolextension.c
XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolpolicy.c
XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolprotocol.c
--- a/XORG_NV/sun-src/xc/programs/Xserver/tsol/TrustedExtensionsPolicy	Thu Sep 21 15:37:20 2006 -0700
+++ b/XORG_NV/sun-src/xc/programs/Xserver/tsol/TrustedExtensionsPolicy	Thu Sep 21 15:42:39 2006 -0700
@@ -3,7 +3,7 @@
 # Use is subject to license terms.
 #
 
-# ident	"@(#)TrustedExtensionsPolicy 1.3	06/04/12 SMI"
+# ident	"@(#)TrustedExtensionsPolicy 1.4	06/08/04 SMI"
 
 # TrustedExtensionsPolicy
 # Syntax: <atom|property|selection|extension|privilege> name
@@ -177,14 +177,22 @@
 selection Dtpad
 selection _Frame_RPC
 selection _MOTIF_CLIP_LOCK
+
+#
+# I18N: Input Method for Ja locale
+#
+selection /^_IIIM_/
+selection /^IIIM_/
+selection /^_XIM_/
+selection /^XIM_/
+selection /^jp.co.justsystem.atokx2/
+
 selection /^_XIMP_/
 selection /^_HTT_/
 
-
 extension SYNC
 
 privilege win_colormap
 privilege win_config
-privilege win_dga
 privilege win_devices
 privilege win_fontpath
--- a/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolextension.c	Thu Sep 21 15:37:20 2006 -0700
+++ b/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolextension.c	Thu Sep 21 15:42:39 2006 -0700
@@ -26,7 +26,7 @@
  * of the copyright holder.
  */ 
 
-#pragma ident   "@(#)tsolextension.c 1.16     06/06/08 SMI"
+#pragma ident   "@(#)tsolextension.c 1.17     06/08/04 SMI"
 
 #include <stdio.h>
 #include <bsm/auditwrite.h>
@@ -211,6 +211,10 @@
 extern int ProcTsolListExtensions(ClientPtr client);
 extern int ProcTsolMapWindow(ClientPtr client);
 extern int ProcTsolMapSubwindows(ClientPtr client);
+extern int ProcTsolCopyArea(ClientPtr client);
+extern int ProcTsolCopyPlane(ClientPtr client);
+extern int ProcTsolPolySegment(ClientPtr client);
+extern int ProcTsolPolyRectangle(ClientPtr client);
 
 /*
  * Initialize the extension. Main entry point for this loadable
@@ -349,7 +353,10 @@
 	ProcVector[X_ListExtensions] = ProcTsolListExtensions;
 	ProcVector[X_MapWindow] = ProcTsolMapWindow;
 	ProcVector[X_MapSubwindows] = ProcTsolMapSubwindows;
-
+	ProcVector[X_CopyArea] = ProcTsolCopyArea;
+	ProcVector[X_CopyPlane] = ProcTsolCopyPlane;
+	ProcVector[X_PolySegment] = ProcTsolPolySegment;
+	ProcVector[X_PolyRectangle] = ProcTsolPolyRectangle;
 }
 
 static pointer
@@ -397,8 +404,6 @@
 	    switch (reqtype) {
 		case X_PolyPoint:
 		case X_PolyLine:
-		case X_PolySegment:
-		case X_PolyRectangle:
 		case X_PolyArc:
 		case X_FillPoly:
 		case X_PolyFillRectangle:
--- a/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolpolicy.c	Thu Sep 21 15:37:20 2006 -0700
+++ b/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolpolicy.c	Thu Sep 21 15:42:39 2006 -0700
@@ -26,7 +26,7 @@
  * of the copyright holder.
  */ 
 
-#pragma ident   "@(#)tsolpolicy.c 1.11     06/05/25 SMI"
+#pragma ident   "@(#)tsolpolicy.c 1.12     06/08/04 SMI"
 
 #include "X.h"
 #define		NEED_REPLIES
@@ -619,20 +619,12 @@
 	if (!SAMECLIENT(client, pDraw->id))
 	{
 	    /*
-	     * Trusted Path Windows require Trusted Path attrib when a 
-             * client doesn't have the PRIV_WIN_DGA privilege.
+	     * Client must have Trusted Path to access a Trusted Path Window
 	     */
-	    if ((pDraw->type == DRAWABLE_WINDOW) &&
-            XTSOLTrusted(pWin) &&
-            !HasTrustedPath(tsolinfo) &&
-            !priv_win_dga)
-		{
-		    XTSOLERR("tp", (int) misc, tsolres->sl,
-					 tsolres->uid, tsolres->pid, tsolres->pname,
-					 tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
-					 tsolinfo->pname, "read pixel", pWin->drawable.id);
-			return (err_code);
-	    }
+	    if ((pDraw->type == DRAWABLE_WINDOW) && XTSOLTrusted(pWin) &&
+		    !HasTrustedPath(tsolinfo))
+		return (err_code);
+
 		/*
 	 	 * MAC Check
 		 */
--- a/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolprotocol.c	Thu Sep 21 15:37:20 2006 -0700
+++ b/XORG_NV/sun-src/xc/programs/Xserver/tsol/tsolprotocol.c	Thu Sep 21 15:42:39 2006 -0700
@@ -26,7 +26,7 @@
  * of the copyright holder.
  */ 
 
-#pragma ident	"@(#)tsolprotocol.c 1.12	06/05/25 SMI"
+#pragma ident	"@(#)tsolprotocol.c 1.14	06/09/19 SMI"
 
 #include <sys/param.h>
 #include <fcntl.h>
@@ -2375,19 +2375,6 @@
     return(client->noClientException);
 }
 
-int
-ProcTsolGetImage(client)
-    register ClientPtr	client;
-{
-    REQUEST(xGetImageReq);
-
-    REQUEST_SIZE_MATCH(xGetImageReq);
-
-    return DoGetImage(client, stuff->format, stuff->drawable,
-		      stuff->x, stuff->y,
-		      (int)stuff->width, (int)stuff->height,
-		      stuff->planeMask, (xGetImageReply **)NULL);
-}
 
 int
 ProcTsolQueryTree(client)
@@ -2794,3 +2781,544 @@
 
     return(client->noClientException);
 }
+
+static int
+TsolDoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
+    register ClientPtr	client;
+    Drawable drawable;
+    int format;
+    int x, y, width, height;
+    Mask planemask;
+    xGetImageReply **im_return;
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+    RegionPtr pVisibleRegion = NULL;
+
+#ifdef TSOL
+    Bool        getimage_ok = TRUE; /* if false get all 0s */
+    Bool        overlap = FALSE;
+    Bool        not_root_window = FALSE;
+    WindowPtr   pHead, pWin, pRoot, pChild;
+    TsolResPtr  tsolres_win;
+    BoxRec      winbox, box;
+    BoxPtr      pwinbox;
+    DrawablePtr pDrawtmp;
+#endif /* TSOL */
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+#ifdef TSOL
+        if (DrawableIsRoot(pDraw))
+        {
+            /* Get the actual window on which get image is done */
+
+            pWin = XYToWindow( x, y);
+            if (!WindowIsRoot(pWin))
+            {
+                not_root_window = TRUE;
+                pDrawtmp = &(pWin->parent->drawable);
+                if (((WindowPtr) pDrawtmp)->realized)
+                {
+                    pDraw = pDrawtmp;
+                    /*
+                     * Adjust the coordinates only w.r.t the new drawable.
+		     * Adjusting width and height will cause incorrect
+		     * amount of data being returned to client.
+                     */
+                    x -= pDraw->x;
+                    if (x < 0)
+                        x = 0;
+                    y -= pDraw->y;
+                    if (y < 0)
+                        y = 0;
+                }
+            }
+        }
+        else
+        {
+            not_root_window = TRUE;
+        }
+
+        if (not_root_window)
+        {
+            Window   root;
+            WindowPtr tmpwin;
+
+            tmpwin = (WindowPtr)LookupWindow(pDraw->id, client);
+            while (tmpwin)
+            {
+                if (tmpwin->parent && WindowIsRoot(tmpwin->parent))
+                {
+                    pWin = tmpwin;
+                    break;
+                }
+                tmpwin = tmpwin->parent;
+            }
+            pwinbox = WindowExtents(pWin, &winbox);
+            box.x1 = pwinbox->x1;
+            box.y1 = pwinbox->y1;
+            box.x2 = pwinbox->x2;
+            box.y2 = box.y1;
+            tsolres_win =
+                (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
+            root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+            pRoot = (WindowPtr)LookupIDByType(root, RT_WINDOW);
+            pHead = pRoot->firstChild;
+        }
+
+        if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, pDraw,
+                         client, TSOL_ALL, (void *)MAJOROP))
+        {
+            /* Don't return error code. Return  contents  all zero */
+            getimage_ok = FALSE;
+        }
+#endif /* TSOL */
+
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+#ifdef TSOL
+        if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, pDraw,
+                         client, TSOL_ALL, (void *)MAJOROP))
+        {
+            /* Don't return error code. Return  contents  all zero */
+            getimage_ok = FALSE;
+        }
+#endif  /* TSOL */
+
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef TSOL
+        if (not_root_window)
+        {
+            WindowPtr  over_win = (WindowPtr)NULL;
+
+            box.y1 = y + linesDone + pDraw->y;
+            box.y2 = box.y1 + nlines;
+            over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
+            if (over_win &&
+                xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, over_win,
+                             client, TSOL_ALL, (void *)MAJOROP))
+            {
+                overlap = TRUE;
+            }
+        }
+
+        /*
+         * fill the buffer with zeros in case of security failure
+         */
+            if (!getimage_ok || overlap)
+        {
+            if (overlap)
+                overlap = FALSE;
+            memset(pBuf, 0, (int)(nlines * widthBytesLine));
+
+        }
+#endif /* TSOL */
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef TSOL
+                if (not_root_window)
+                {
+                    WindowPtr  over_win = (WindowPtr)NULL;
+
+                    box.y1 = y + linesDone + pDraw->y;
+                    box.y2 = box.y1 + nlines;
+                    over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
+                    if (over_win &&
+                        xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, over_win,
+                                     client, TSOL_ALL, (void *)MAJOROP))
+                    {
+                        overlap = TRUE;
+                    }
+                }
+                /*
+                 * fill the buffer with zeros in case of security failure
+                 */
+                if (!getimage_ok || overlap)
+                {
+                    if (overlap)
+                        overlap = FALSE;
+                    memset(pBuf, 0, (int)(nlines * widthBytesLine));
+
+                }
+#endif /* TSOL */
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcTsolGetImage(client)
+    register ClientPtr	client;
+{
+    int status;
+    int savedtrust = client->trustLevel;
+
+    client->trustLevel = XSecurityClientTrusted;
+
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    status = TsolDoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+
+    client->trustLevel = savedtrust;
+    return (status);
+}
+
+int
+ProcTsolPolySegment(client)
+    register ClientPtr client;
+{
+    int savedtrust;
+    int status;
+    GC *pGC;
+    DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+
+    savedtrust = client->trustLevel;
+    client->trustLevel = XSecurityClientTrusted;
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDraw,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message for DnD zap effect */
+        return (client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        client->errorValue = stuff->gc;
+        return (BadGC);
+    }
+
+    status = (*TsolSavedProcVector[X_PolySegment])(client);
+    client->trustLevel = savedtrust;
+
+    return (status);
+}
+
+int
+ProcTsolPolyRectangle (client)
+    register ClientPtr client;
+{
+    int savedtrust;
+    int status;
+    GC *pGC;
+    DrawablePtr pDraw;
+
+    REQUEST(xPolyRectangleReq);
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+
+    savedtrust = client->trustLevel;
+    client->trustLevel = XSecurityClientTrusted;
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDraw,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message */
+        return (client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        client->errorValue = stuff->gc;
+        return (BadGC);
+    }
+
+    status = (*TsolSavedProcVector[X_PolyRectangle])(client);
+    client->trustLevel = savedtrust;
+
+    return (status);
+}
+
+int
+ProcTsolCopyArea (client)
+    register ClientPtr client;
+{
+    int savedtrust;
+    int status;
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    savedtrust = client->trustLevel;
+    client->trustLevel = XSecurityClientTrusted;
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+        SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+                                 SecurityReadAccess);
+        if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+        {
+            client->errorValue = stuff->dstDrawable;
+            return (BadMatch);
+        }
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, pSrc,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message for DnD zap effect */
+        return(client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pDst,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message for DnD zap effect */
+        return(client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        client->errorValue = stuff->gc;
+        return (BadGC);
+    }
+
+    status = (*TsolSavedProcVector[X_CopyArea])(client);
+    client->trustLevel = savedtrust;
+
+    return (status);
+}
+
+int
+ProcTsolCopyPlane(client)
+    register ClientPtr client;
+{
+    int savedtrust;
+    int status;
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    savedtrust = client->trustLevel;
+    client->trustLevel = XSecurityClientTrusted;
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ, psrcDraw,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message for DnD zap effect */
+        return(client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY, pdstDraw,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        /* ignore the error message for DnD zap effect */
+        return(client->noClientException);
+    }
+    if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)stuff->gc,
+                     client, TSOL_ALL, (void *)MAJOROP))
+    {
+        client->errorValue = stuff->gc;
+        return (BadGC);
+    }
+
+    status = (*TsolSavedProcVector[X_CopyPlane])(client);
+    client->trustLevel = savedtrust;
+
+    return (status);
+}