Re: Alignment error in libXi

2011-03-29 Thread Peter Hutterer
On Sun, Mar 27, 2011 at 10:42:14PM +0200, Matthieu Herrb wrote:
 On Thu, Mar 24, 2011 at 11:51:32PM -0700, Jeremy Huddleston wrote:
  Don't feel too bad.  I missed it too and bugged Peter about it
  before I pushed the release ;)  
 
 
 Unfortunatly, as Peter forsaid it, there are other issues. I'm
 currently fighting with the code for XISelectEvents(). 
 
 It uses Data32() to send a xXIEventMask structure. This is very wrong
 and fails miserablily on sparc64, for at least 2 reasons: 
 
 1. Data32() suffers from the infamous 'use unsigned long for 32 bits
data' API mis-design, so on 64 bits machines one can't pass a
pointer to a 32 bit only data to Data32(): it has one chance over 2
to be mis-aligned, and will read 4 extra random bytes on the stack.
 2. since xXIEventMask contains two uint_16 values, which are not
properly swapped, this will not work across client/server with
different endianness.

swapping is handled by the server anyway, so the library shouldn't need to
worry about it.

can't we just replace the Data32() call with Data() here?
Aside from the API issues, the only difference is that Data32 pads out,
right? Given that xXIEventMask is always 4 bytes we don't need the padding.

Cheers,
  Peter

 This can all be seen whil trying Gtk+3's gtk3-demo on an
 OpenBSD/sparc64 machine, but probably on other 64 bits big endian
 machines too.
 
 For now I have the ugly patch below. Any better suggestion ?
 
 And there are other issues...
 
 --- src/XISelEv.c 4 Sep 2010 10:17:03 -   1.2
 +++ src/XISelEv.c 27 Mar 2011 15:09:31 -
 @@ -32,6 +32,7 @@ in this Software without prior written a
  
  
  #include stdint.h
 +#include X11/Xarch.h
  #include X11/Xlibint.h
  #include X11/extensions/XI2proto.h
  #include X11/extensions/XInput2.h
 @@ -46,6 +47,7 @@ XISelectEvents(Display* dpy, Window win,
  XIEventMask  *current;
  xXISelectEventsReq  *req;
  xXIEventMask mask;
 +unsigned long long_mask;
  int i;
  int len = 0;
  int r = Success;
 @@ -83,7 +85,12 @@ XISelectEvents(Display* dpy, Window win,
   * and they need to be padded with 0 */
  buff = calloc(1, mask.mask_len * 4);
  memcpy(buff, current-mask, current-mask_len);
 -Data32(dpy, mask, sizeof(xXIEventMask));
 +#if X_BYTE_ORDER == X_BIG_ENDIAN
 + long_mask = mask.deviceid  16 | mask.mask_len;
 +#else
 + long_mask = mask.mask_len  16 | mask.deviceid;
 +#endif
 + Data32(dpy, long_mask, sizeof(xXIEventMask));
  Data(dpy, buff, mask.mask_len * 4);
  free(buff);
  }
 
 -- 
 Matthieu Herrb
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-27 Thread Matthieu Herrb
On Thu, Mar 24, 2011 at 11:51:32PM -0700, Jeremy Huddleston wrote:
 Don't feel too bad.  I missed it too and bugged Peter about it
 before I pushed the release ;)  


Unfortunatly, as Peter forsaid it, there are other issues. I'm
currently fighting with the code for XISelectEvents(). 

It uses Data32() to send a xXIEventMask structure. This is very wrong
and fails miserablily on sparc64, for at least 2 reasons: 

1. Data32() suffers from the infamous 'use unsigned long for 32 bits
   data' API mis-design, so on 64 bits machines one can't pass a
   pointer to a 32 bit only data to Data32(): it has one chance over 2
   to be mis-aligned, and will read 4 extra random bytes on the stack.
2. since xXIEventMask contains two uint_16 values, which are not
   properly swapped, this will not work across client/server with
   different endianness.

This can all be seen whil trying Gtk+3's gtk3-demo on an
OpenBSD/sparc64 machine, but probably on other 64 bits big endian
machines too.

For now I have the ugly patch below. Any better suggestion ?

And there are other issues...

--- src/XISelEv.c   4 Sep 2010 10:17:03 -   1.2
+++ src/XISelEv.c   27 Mar 2011 15:09:31 -
@@ -32,6 +32,7 @@ in this Software without prior written a
 
 
 #include stdint.h
+#include X11/Xarch.h
 #include X11/Xlibint.h
 #include X11/extensions/XI2proto.h
 #include X11/extensions/XInput2.h
@@ -46,6 +47,7 @@ XISelectEvents(Display* dpy, Window win,
 XIEventMask  *current;
 xXISelectEventsReq  *req;
 xXIEventMask mask;
+unsigned long long_mask;
 int i;
 int len = 0;
 int r = Success;
@@ -83,7 +85,12 @@ XISelectEvents(Display* dpy, Window win,
  * and they need to be padded with 0 */
 buff = calloc(1, mask.mask_len * 4);
 memcpy(buff, current-mask, current-mask_len);
-Data32(dpy, mask, sizeof(xXIEventMask));
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+   long_mask = mask.deviceid  16 | mask.mask_len;
+#else
+   long_mask = mask.mask_len  16 | mask.deviceid;
+#endif
+   Data32(dpy, long_mask, sizeof(xXIEventMask));
 Data(dpy, buff, mask.mask_len * 4);
 free(buff);
 }

-- 
Matthieu Herrb
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-26 Thread Julien Cristau
On Fri, Mar 25, 2011 at 06:31:38 +, Matt Turner wrote:

 Oh, I didn't realize it had already been fixed.
 
 Odd that it was fixed, reviewed, and tested without another comment in
 this thread. Guess I just missed the patch.
 
The followup with patch was only on -devel.

Cheers,
Julien
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-25 Thread Matt Turner
On Sun, Mar 13, 2011 at 10:11 PM, Christian Weisgerber
na...@mips.inka.de wrote:
 GTK+3 blows up on LP64 archs with strict alignment.  This comes
 down to an unaligned access error in libXi, specifically in
 the XIButtonClass case in copy_classes() in XExtInt.c.

    cls_lib-num_buttons = cls_wire-num_buttons;
    cls_lib-state.mask_len = cls_wire-num_buttons + 7)/8) + 3)/4) * 4;
    cls_lib-state.mask = next_block(ptr_lib, cls_lib-state.mask_len);
    memcpy(cls_lib-state.mask, cls_wire[1],
           cls_lib-state.mask_len);

    cls_lib-labels = next_block(ptr_lib, cls_lib-num_buttons * 
 sizeof(Atom));
    atoms =(uint32_t*)((char*)cls_wire[1] + cls_lib-state.mask_len);
    for (j = 0; j  cls_lib-num_buttons; j++)
        cls_lib-labels[j] = *atoms++;

 It's the   cls_lib-labels[j] = *atoms++   assignment that blows up.

 For state.mask, n*4 bytes are allocated from the ptr_lib area.
 labels is allocated immediately following that, but labels is an
 array of Atoms, which are longs, i.e, an 8-byte type on LP64 archs.
 labels can end up on an address that is misaligned for Atom
 assignments, like it did here:

 #0  0x0001616ea910 in copy_classes (to=0x165db5600, from=0x161bae020,
    nclasses=3) at /usr/xenocara/lib/libXi/src/XExtInt.c:1490
 1490                            cls_lib-labels[j] = *atoms++;
 (gdb) bt
 #0  0x0001616ea910 in copy_classes (to=0x165db5600, from=0x161bae020,
    nclasses=3) at /usr/xenocara/lib/libXi/src/XExtInt.c:1490
 #1  0x0001616ecd80 in XIQueryDevice (dpy=0x16b964db0, deviceid=0,
    ndevices_return=0x1fffe44f0)
    at /usr/xenocara/lib/libXi/src/XIQueryDevice.c:90
 #2  0x00016c30b6b0 in gdk_x11_device_manager_xi2_constructed (
    object=0x16f8886a0) at gdkdevicemanager-xi2.c:413
 #3  0x00016bf08488 in g_object_newv ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
 #4  0x00016bf08a48 in g_object_new_valist ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
 #5  0x00016bf07dec in g_object_new ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
 #6  0x00016c308c10 in _gdk_x11_device_manager_new (display=0x164582000)
    at gdkdevicemanager-x11.c:59
 #7  0x00016c310a0c in _gdk_x11_display_open (display_name=0x0)
    at gdkdisplay-x11.c:1228
 #8  0x00016c30dff4 in gdk_x11_display_manager_open_display (
    manager=0x1659b, name=0x0) at gdkdisplaymanager-x11.c:55
 #9  0x00016c2d4130 in gdk_display_manager_open_display (
    manager=0x1659b, name=0x0) at gdkdisplaymanager.c:362
 #10 0x00016c2d29e4 in gdk_display_open (display_name=0x0)
    at gdkdisplay.c:1720
 #11 0x00016c2c44b4 in gdk_display_open_default_libgtk_only () at gdk.c:341
 #12 0x000168a9981c in gtk_init_check (argc=0x1fffe49a8, argv=0x1fffe49b0)
    at gtkmain.c:1132
 #13 0x000168a99878 in gtk_init (argc=0x1fffe49a8, argv=0x1fffe49b0)
    at gtkmain.c:1184
 #14 0x000120031094 in main (argc=1, argv=0x1fffe4a70) at main.c:948
 (gdb) i loc
 cls_lib = (XIButtonClassInfo *) 0x165db5018
 cls_wire = (xXIButtonInfo *) 0x161bae020
 atoms = (uint32_t *) 0x161bae02c
 j = 0
 any_lib = (XIAnyClassInfo *) 0x165db5018
 any_wire = (xXIAnyInfo *) 0x161bae020
 ptr_lib = (void *) 0x165db5094
 ptr_wire = 0x161bae020 \001
 i = 0
 len = 0
 (gdb) p cls_lib-labels
 $1 = (Atom *) 0x165db5044
 (gdb) p sizeof(Atom)
 $2 = 8
 (gdb)

 --
 Christian naddy Weisgerber                          na...@mips.inka.de

Good analysis.

Is this one of those cases where someone, long ago, thought using
longs was inherently good? Can we just change labels to be an array of
ints, or is that too easy?

There's even a comment in the code you quoted:

/* Force mask alignment with longs to avoid unaligned
 * access when accessing the atoms. */

So much for that.

Matt
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-25 Thread Jeremy Huddleston

On Mar 24, 2011, at 11:06 PM, Matt Turner wrote:
 
 Is this one of those cases where someone, long ago, thought using
 longs was inherently good? Can we just change labels to be an array of
 ints, or is that too easy?

You can just get the latest libXi release with the fix.


___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-25 Thread Matt Turner
On Fri, Mar 25, 2011 at 6:19 AM, Jeremy Huddleston jerem...@apple.com wrote:

 On Mar 24, 2011, at 11:06 PM, Matt Turner wrote:

 Is this one of those cases where someone, long ago, thought using
 longs was inherently good? Can we just change labels to be an array of
 ints, or is that too easy?

 You can just get the latest libXi release with the fix.

Oh, I didn't realize it had already been fixed.

Odd that it was fixed, reviewed, and tested without another comment in
this thread. Guess I just missed the patch.

Matt
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Re: Alignment error in libXi

2011-03-25 Thread Jeremy Huddleston
Don't feel too bad.  I missed it too and bugged Peter about it before I pushed 
the release ;)

On Mar 24, 2011, at 11:31 PM, Matt Turner wrote:

 On Fri, Mar 25, 2011 at 6:19 AM, Jeremy Huddleston jerem...@apple.com wrote:
 
 On Mar 24, 2011, at 11:06 PM, Matt Turner wrote:
 
 Is this one of those cases where someone, long ago, thought using
 longs was inherently good? Can we just change labels to be an array of
 ints, or is that too easy?
 
 You can just get the latest libXi release with the fix.
 
 Oh, I didn't realize it had already been fixed.
 
 Odd that it was fixed, reviewed, and tested without another comment in
 this thread. Guess I just missed the patch.
 
 Matt
 ___
 xorg-de...@lists.x.org: X.Org development
 Archives: http://lists.x.org/archives/xorg-devel
 Info: http://lists.x.org/mailman/listinfo/xorg-devel
 

___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com


Alignment error in libXi

2011-03-13 Thread Christian Weisgerber
GTK+3 blows up on LP64 archs with strict alignment.  This comes
down to an unaligned access error in libXi, specifically in
the XIButtonClass case in copy_classes() in XExtInt.c.

cls_lib-num_buttons = cls_wire-num_buttons;
cls_lib-state.mask_len = cls_wire-num_buttons + 7)/8) + 3)/4) * 4;
cls_lib-state.mask = next_block(ptr_lib, cls_lib-state.mask_len);
memcpy(cls_lib-state.mask, cls_wire[1],
   cls_lib-state.mask_len);

cls_lib-labels = next_block(ptr_lib, cls_lib-num_buttons * sizeof(Atom));
atoms =(uint32_t*)((char*)cls_wire[1] + cls_lib-state.mask_len);
for (j = 0; j  cls_lib-num_buttons; j++)
cls_lib-labels[j] = *atoms++;

It's the   cls_lib-labels[j] = *atoms++   assignment that blows up.

For state.mask, n*4 bytes are allocated from the ptr_lib area.
labels is allocated immediately following that, but labels is an
array of Atoms, which are longs, i.e, an 8-byte type on LP64 archs.
labels can end up on an address that is misaligned for Atom
assignments, like it did here:

#0  0x0001616ea910 in copy_classes (to=0x165db5600, from=0x161bae020, 
nclasses=3) at /usr/xenocara/lib/libXi/src/XExtInt.c:1490
1490cls_lib-labels[j] = *atoms++;
(gdb) bt
#0  0x0001616ea910 in copy_classes (to=0x165db5600, from=0x161bae020, 
nclasses=3) at /usr/xenocara/lib/libXi/src/XExtInt.c:1490
#1  0x0001616ecd80 in XIQueryDevice (dpy=0x16b964db0, deviceid=0, 
ndevices_return=0x1fffe44f0)
at /usr/xenocara/lib/libXi/src/XIQueryDevice.c:90
#2  0x00016c30b6b0 in gdk_x11_device_manager_xi2_constructed (
object=0x16f8886a0) at gdkdevicemanager-xi2.c:413
#3  0x00016bf08488 in g_object_newv ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
#4  0x00016bf08a48 in g_object_new_valist ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
#5  0x00016bf07dec in g_object_new ()
   from /usr/local/lib/libgobject-2.0.so.2800.0
#6  0x00016c308c10 in _gdk_x11_device_manager_new (display=0x164582000)
at gdkdevicemanager-x11.c:59
#7  0x00016c310a0c in _gdk_x11_display_open (display_name=0x0)
at gdkdisplay-x11.c:1228
#8  0x00016c30dff4 in gdk_x11_display_manager_open_display (
manager=0x1659b, name=0x0) at gdkdisplaymanager-x11.c:55
#9  0x00016c2d4130 in gdk_display_manager_open_display (
manager=0x1659b, name=0x0) at gdkdisplaymanager.c:362
#10 0x00016c2d29e4 in gdk_display_open (display_name=0x0)
at gdkdisplay.c:1720
#11 0x00016c2c44b4 in gdk_display_open_default_libgtk_only () at gdk.c:341
#12 0x000168a9981c in gtk_init_check (argc=0x1fffe49a8, argv=0x1fffe49b0)
at gtkmain.c:1132
#13 0x000168a99878 in gtk_init (argc=0x1fffe49a8, argv=0x1fffe49b0)
at gtkmain.c:1184
#14 0x000120031094 in main (argc=1, argv=0x1fffe4a70) at main.c:948
(gdb) i loc
cls_lib = (XIButtonClassInfo *) 0x165db5018
cls_wire = (xXIButtonInfo *) 0x161bae020
atoms = (uint32_t *) 0x161bae02c
j = 0
any_lib = (XIAnyClassInfo *) 0x165db5018
any_wire = (xXIAnyInfo *) 0x161bae020
ptr_lib = (void *) 0x165db5094
ptr_wire = 0x161bae020 \001
i = 0
len = 0
(gdb) p cls_lib-labels   
$1 = (Atom *) 0x165db5044
(gdb) p sizeof(Atom)
$2 = 8
(gdb) 

-- 
Christian naddy Weisgerber  na...@mips.inka.de
___
xorg@lists.freedesktop.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: arch...@mail-archive.com