Bug 26056

Summary: 32 bit XRender lib running with thunderbird ver2 cause crash with 64 bit Xserver
Product: xorg Reporter: Arvind Umrao <arvind.umrao>
Component: Server/GeneralAssignee: Arvind Umrao <arvind.umrao>
Status: RESOLVED DUPLICATE QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: alan.coopersmith, bob.terek, stuart.kreitman
Version: git   
Hardware: SPARC   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Arvind Umrao 2010-01-14 23:37:28 UTC
Symptoms of the problem:
1) _Xerror occur from  Xorg/render/render.c when composite glyphs are drawn
2)  Only when 64 bit of Xserver is used.
3)  Only when 32 bit libXrender render composite glyphs with 64 bit Xerver


Problem is:

This problem is coming because xorg/render/redender.c  could not able to find glyphset copied from xc/Xlib/Xrender/glyph.c with X11:Data32 interface. So Xorg delocate glyphsBase and return _Xerror.  


Reason:
In 64 bit Xserver, size of GlyphSet is 8 byte but in 32 bit libXrender size  of GlyphSet is 4 byte.

Xrender lib alway copied 32bit( 4byte) of glyphset address with interface X11:Data32 from glyph.c.  So it works with 32 bit of Xorg in x86 but not with 64 bit Xorg in SPARC 

 






xorg/render/redender.c

if (buffer + sizeof (GlyphSet) < end)
       {
               memcpy(&gs, buffer, sizeof(GlyphSet));
       glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
                                gs,
                                GlyphSetType,
                                SecurityReadAccess);
       if (!glyphSet)        {
           client->errorValue = gs; // delocate glyphsBase and return _Xerror.            

 if (glyphsBase != glyphsLocal)
           DEALLOCATE_LOCAL (glyphsBase);
           if (listsBase != listsLocal)
           DEALLOCATE_LOCAL (listsBase);
           return RenderErrBase + BadGlyphSet;
       }
Comment 1 Julien Cristau 2010-01-15 02:16:36 UTC
On Thu, Jan 14, 2010 at 23:37:29 -0800, bugzilla-daemon@freedesktop.org wrote:

> Reason:
> In 64 bit Xserver, size of GlyphSet is 8 byte but in 32 bit libXrender size  of
> GlyphSet is 4 byte.

GlyphSet is typedefed as XID, which in the server should always be
32bit.  What's going wrong there?
Comment 2 Bob Terek 2010-01-15 04:02:48 UTC
An endian problem because memcpy() is being used?

Possible fix:

  gs = *(CARD32 *) buffer;
Comment 3 Michel Dänzer 2010-01-15 07:22:09 UTC
See bug 7364 and bug 3794 for possibly related issues.
Comment 4 Arvind Umrao 2010-01-15 08:34:39 UTC
bugzilla-daemon@freedesktop.org wrote:
> http://bugs.freedesktop.org/show_bug.cgi?id=26056
>
>
>
>
>
> --- Comment #3 from Michel Dänzer <michel@daenzer.net>  2010-01-15 07:22:09 PST ---
> See bug 7364 and bug 3794 for possibly related issues.
>
>
>   
Yes both are related bug. But better solution will be as depicted 
beneath. Let me know what you finally suggest?


Xrender lib alway copy  32bit( 4byte) of glyphset address with interface 
X11:Data32 from  Xrender/Glyph.c ( see line 467,  Data32(dpy, &glyphset, 4);

Check 4 byte is hardcoded value

But xorg/render/render.c does  memcpy(&gs, buffer, sizeof(GlyphSet))  
GlyphSet is tydef to long. On 64 bit machine long is 8 byte
Because of endian problem memcpy will not copy the correct values 

-- render/render.c_org	Fri Jan 15 01:16:46 2010
+++ render/render.c	Fri Jan 15 01:28:59 2010
@@ -1271,7 +1271,7 @@
 ProcRenderCompositeGlyphs (ClientPtr client)
 {
     GlyphSetPtr     glyphSet;
-    GlyphSet	    gs;
+    CARD32	    gs;
     PicturePtr      pSrc, pDst;
     PictFormatPtr   pFormat;
     GlyphListRec    listsLocal[NLOCALDELTA];
@@ -1374,9 +1374,9 @@
 	
 	if (elt->len == 0xff)
 	{
-	    if (buffer + sizeof (GlyphSet) < end)
+	    if (buffer + sizeof (CARD32) < end)
 	    {
-                memcpy(&gs, buffer, sizeof(GlyphSet));
+                memcpy(&gs, buffer, sizeof(CARD32));
 		rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
 					     GlyphSetType, client,
 					     DixUseAccess);


-Arvind
Comment 5 Arvind Umrao 2010-01-15 08:35:32 UTC
bugzilla-daemon@freedesktop.org wrote:
> http://bugs.freedesktop.org/show_bug.cgi?id=26056
>
>
>
>
>
> --- Comment #2 from Bob Terek <robert.terek@sun.com>  2010-01-15 04:02:48 PST ---
> An endian problem because memcpy() is being used?
>
> Possible fix:
>
>   gs = *(CARD32 *) buffer;
>
>
>   
Yes it  will work


But better solution is

Xrender lib alway copy  32bit( 4byte) of glyphset address with interface 
X11:Data32 from  Xrender/Glyph.c ( see line 467,  Data32(dpy, &glyphset, 4);

Check 4 byte is hardcoded value

But xorg/render/render.c does  memcpy(&gs, buffer, sizeof(GlyphSet))  
GlyphSet is tydef to long. On 64 bit machine long is 8 byte
Because of endian problem memcpy will not copy the correct values 

-- render/render.c_org	Fri Jan 15 01:16:46 2010
+++ render/render.c	Fri Jan 15 01:28:59 2010
@@ -1271,7 +1271,7 @@
 ProcRenderCompositeGlyphs (ClientPtr client)
 {
     GlyphSetPtr     glyphSet;
-    GlyphSet	    gs;
+    CARD32	    gs;
     PicturePtr      pSrc, pDst;
     PictFormatPtr   pFormat;
     GlyphListRec    listsLocal[NLOCALDELTA];
@@ -1374,9 +1374,9 @@
 	
 	if (elt->len == 0xff)
 	{
-	    if (buffer + sizeof (GlyphSet) < end)
+	    if (buffer + sizeof (CARD32) < end)
 	    {
-                memcpy(&gs, buffer, sizeof(GlyphSet));
+                memcpy(&gs, buffer, sizeof(CARD32));
 		rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
 					     GlyphSetType, client,
 					     DixUseAccess);


-Arvind
Comment 6 Arvind Umrao 2010-01-15 08:38:25 UTC
bugzilla-daemon@freedesktop.org wrote:
> http://bugs.freedesktop.org/show_bug.cgi?id=26056
>
>
>
>
>
> --- Comment #1 from Julien Cristau <jcristau@debian.org>  2010-01-15 02:16:36 PST ---
> On Thu, Jan 14, 2010 at 23:37:29 -0800, bugzilla-daemon@freedesktop.org wrote:
>
>   
>> Reason:
>> In 64 bit Xserver, size of GlyphSet is 8 byte but in 32 bit libXrender size  of
>> GlyphSet is 4 byte.
>>     
>
> GlyphSet is typedefed as XID, which in the server should always be
> 32bit.  What's going wrong there?
>
>
>   

Xrender lib alway copy  32bit( 4byte) of glyphset address with interface 
X11:Data32 from  Xrender/Glyph.c ( see line 467,  Data32(dpy, &glyphset, 4);

Check 4 byte is hardcoded value

But xorg/render/render.c does  memcpy(&gs, buffer, sizeof(GlyphSet))  
GlyphSet is tydef to long. On 64 bit machine long is 8 byte
Because of endian problem memcpy will not copy the correct values 

Better solution is

-- render/render.c_org	Fri Jan 15 01:16:46 2010
+++ render/render.c	Fri Jan 15 01:28:59 2010
@@ -1271,7 +1271,7 @@
 ProcRenderCompositeGlyphs (ClientPtr client)
 {
     GlyphSetPtr     glyphSet;
-    GlyphSet	    gs;
+    CARD32	    gs;
     PicturePtr      pSrc, pDst;
     PictFormatPtr   pFormat;
     GlyphListRec    listsLocal[NLOCALDELTA];
@@ -1374,9 +1374,9 @@
 	
 	if (elt->len == 0xff)
 	{
-	    if (buffer + sizeof (GlyphSet) < end)
+	    if (buffer + sizeof (CARD32) < end)
 	    {
-                memcpy(&gs, buffer, sizeof(GlyphSet));
+                memcpy(&gs, buffer, sizeof(CARD32));
 		rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
 					     GlyphSetType, client,
 					     DixUseAccess);


-Arvind
Comment 7 Julien Cristau 2010-01-15 08:40:00 UTC
> --- Comment #4 from Arvind Umrao <arvind.umrao@sun.com>  2010-01-15 08:34:39 PST ---
> But xorg/render/render.c does  memcpy(&gs, buffer, sizeof(GlyphSet))  
> GlyphSet is tydef to long. On 64 bit machine long is 8 byte
> Because of endian problem memcpy will not copy the correct values 
> 
No.  In the server, GlyphSet is 32bit.  Assuming you have the fixed
renderproto.
Comment 8 Alan Coopersmith 2010-01-15 10:35:54 UTC
(In reply to comment #7)
> No.  In the server, GlyphSet is 32bit.  Assuming you have the fixed
> renderproto.

That would be this fix, in what became renderproto-0.9.3, right?
http://cgit.freedesktop.org/xorg/proto/renderproto/commit/?id=030dd885476b70c9054b6e4b50dfdbab12e73716

In which case, this bug may just be a dup of Bug #7364.

(From looking at the bug in Sun's bug database that caused Arvind to 
 file this, I can see the end-user who hit it was on Solaris 10, which
 currently has only renderproto-0.9.2, which should probably be upgraded.)
Comment 9 Julien Cristau 2010-01-15 10:41:08 UTC
(In reply to comment #8)
> (In reply to comment #7)
> > No.  In the server, GlyphSet is 32bit.  Assuming you have the fixed
> > renderproto.
> 
> That would be this fix, in what became renderproto-0.9.3, right?
> http://cgit.freedesktop.org/xorg/proto/renderproto/commit/?id=030dd885476b70c9054b6e4b50dfdbab12e73716
> 
> In which case, this bug may just be a dup of Bug #7364.
> 
Yes, I think it is.

*** This bug has been marked as a duplicate of bug 7364 ***

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.