Bug#636920: libxi6: Many programs crash with SIGBUS on startup
Dear Maintainer, I've prepared an NMU versioned as 2:1.4.5-1.1. The package is available at [1] and the debdiff is attached. On 04/04/12 11:22, Sebastian Ramacher wrote: > I've backported c1a5a70b51f12dedf354102217c7cd4247ed3a4b to 1.4.5. The patch > is > attached. In addition to c1a5a70b51f12dedf354102217c7cd4247ed3a4b upstream's 8436c920953f288aea2d6d5f370f8eaaaef82d97 [2] is also required. Otherwise libxi fails to work on ppc since c1a5a70b51f12dedf354102217c7cd4247ed3a4b introduced a regression: # xinput list --long ⎡ Virtual core pointer id=2[master pointer (3)] Reporting 3 classes: Class originated from: 2 Buttons supported: 10 X Error of failed request: BadAtom (invalid Atom parameter) Major opcode of failed request: 17 (X_GetAtomName) Atom id in failed request: 0x2000b Serial number of failed request: 23 Current serial number in output stream: 23 Button labels: Button Middle Button Right Button Wheel Up Button Wheel Down Button Horiz Wheel Left Button Horiz Wheel Right None None None 8436c920953f288aea2d6d5f370f8eaaaef82d97 is also included in the NMU. [1] http://mentors.debian.net/debian/pool/main/libx/libxi/libxi_1.4.5-1.1.dsc [2] http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=8436c920953f288aea2d6d5f370f8eaaaef82d97 -- Sebastian Ramacher diff -u libxi-1.4.5/debian/changelog libxi-1.4.5/debian/changelog --- libxi-1.4.5/debian/changelog +++ libxi-1.4.5/debian/changelog @@ -1,3 +1,12 @@ +libxi (2:1.4.5-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Backport fixes from upstream: +- Fix bus error on MIPS N32 (Closes: #636920) +- Fix wrong button label and mask copy on OS X. + + -- Sebastian Ramacher Sat, 07 Apr 2012 16:55:42 +0200 + libxi (2:1.4.5-1) unstable; urgency=low * New upstream release. diff -u libxi-1.4.5/debian/patches/series libxi-1.4.5/debian/patches/series --- libxi-1.4.5/debian/patches/series +++ libxi-1.4.5/debian/patches/series @@ -1 +1 @@ -# placeholder. +c1a5a70b-1.4.5.patch only in patch2: unchanged: --- libxi-1.4.5.orig/debian/patches/c1a5a70b-1.4.5.patch +++ libxi-1.4.5/debian/patches/c1a5a70b-1.4.5.patch @@ -0,0 +1,258 @@ +Description: Fix bus error on MIPS N32. + XIValuatorClassInfo might have an address of 4 bytes modulo 8, while it + contains doubles which need 8 byte alignment. This is fixed by adding extra + padding after each structure or array in sizeDeviceClassType and adding + helper functions to determine sizes and padding only in one place. + . + This is upstream's c1a5a70b51f12dedf354102217c7cd4247ed3a4b backported to + 1.4.5 and also includes 8436c920953f288aea2d6d5f370f8eaaaef82d97 to fix the + regression introduced in c1a5a70b51f12dedf354102217c7cd4247ed3a4b. +Origin: + http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=c1a5a70b, + http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=8436c920 +Last-Update: 2012-04-07 +Bug-Debian: http://bugs.debian.org/636920 + +diff --git a/src/XExtInt.c b/src/XExtInt.c +index 63afb8f..bf051f9 100644 +--- a/src/XExtInt.c b/src/XExtInt.c +@@ -1012,6 +1012,55 @@ sizeDeviceEvent(int buttons_len, int valuators_len, + return len; + } + ++/* Return the size with added padding so next element would be ++ double-aligned unless the architecture is known to allow unaligned ++ data accesses. Not doing this can cause a bus error on ++ MIPS N32. */ ++static int ++pad_to_double(int size) ++{ ++#if !defined(__i386__) && !defined(__sh__) ++if (size % sizeof(double) != 0) ++size += sizeof(double) - size % sizeof(double); ++#endif ++return size; ++} ++ ++/** ++ * Set structure and atoms to size in bytes of XIButtonClassInfo, its ++ * button state mask and labels array. ++ */ ++static void ++sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms) ++{ ++int size; ++int labels; ++ ++*structure = pad_to_double(sizeof(XIButtonClassInfo)); ++size = num_buttons + 7)/8) + 3)/4); ++ ++/* Force mask alignment with longs to avoid unaligned ++ * access when accessing the atoms. */ ++*state = pad_to_double(size * 4); ++labels = num_buttons * sizeof(Atom); ++ ++/* Force mask alignment with longs to avoid ++ * unaligned access when accessing the atoms. */ ++labels += num_buttons + 7)/8) + 3)/4) * sizeof(Atom); ++*atoms = pad_to_double(labels); ++} ++ ++/** ++ * Set structure and keycodes to size in bytes of XIKeyClassInfo and ++ * its keycodes array. ++ */ ++static void ++sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes) ++{ ++*structure = pad_to_double(sizeof(XIKeyClassInfo)); ++*keycodes = pad_to_double(num_keycodes * sizeof(int)); ++} ++ + /** + * Return the size in bytes required to store the matching class type + * num_elements is num_buttons for XIButtonClass or num_keycodes for +@@ -1023,21 +1072,21 @@ static int + sizeDeviceClassType(int type, int num_elements) + {
Bug#636920: libxi6: Many programs crash with SIGBUS on startup
tags 636920 + patch thanks I've backported c1a5a70b51f12dedf354102217c7cd4247ed3a4b to 1.4.5. The patch is attached. Regards -- Sebastian Ramacher diff --git a/src/XExtInt.c b/src/XExtInt.c index 63afb8f..afb4427 100644 --- a/src/XExtInt.c +++ b/src/XExtInt.c @@ -1012,6 +1012,55 @@ sizeDeviceEvent(int buttons_len, int valuators_len, return len; } +/* Return the size with added padding so next element would be + double-aligned unless the architecture is known to allow unaligned + data accesses. Not doing this can cause a bus error on + MIPSÂ N32. */ +static int +pad_to_double(int size) +{ +#if !defined(__i386__) && !defined(__sh__) +if (size % sizeof(double) != 0) +size += sizeof(double) - size % sizeof(double); +#endif +return size; +} + +/** + * Set structure and atoms to size in bytes of XIButtonClassInfo, its + * button state mask and labels array. + */ +static void +sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms) +{ +int size; +int labels; + +*structure = pad_to_double(sizeof(XIButtonClassInfo)); +size = num_buttons + 7)/8) + 3)/4); + +/* Force mask alignment with longs to avoid unaligned + * access when accessing the atoms. */ +*state = pad_to_double(size * 4); +labels = num_buttons * sizeof(Atom); + +/* Force mask alignment with longs to avoid + * unaligned access when accessing the atoms. */ +labels += num_buttons + 7)/8) + 3)/4) * sizeof(Atom); +*atoms = pad_to_double(labels); +} + +/** + * Set structure and keycodes to size in bytes of XIKeyClassInfo and + * its keycodes array. + */ +static void +sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes) +{ +*structure = pad_to_double(sizeof(XIKeyClassInfo)); +*keycodes = pad_to_double(num_keycodes * sizeof(int)); +} + /** * Return the size in bytes required to store the matching class type * num_elements is num_buttons for XIButtonClass or num_keycodes for @@ -1023,21 +1072,21 @@ static int sizeDeviceClassType(int type, int num_elements) { int l = 0; +int extra1 = 0; +int extra2 = 0; switch(type) { case XIButtonClass: -l = sizeof(XIButtonClassInfo); -l += num_elements * sizeof(Atom); -/* Force mask alignment with longs to avoid - * unaligned access when accessing the atoms. */ -l += num_elements + 7)/8) + 3)/4) * sizeof(Atom); +sizeXIButtonClassType(num_elements, &l, &extra1, &extra2); +l += extra1 + extra2; break; case XIKeyClass: -l = sizeof(XIKeyClassInfo); -l += num_elements * sizeof(int); +sizeXIKeyClassType(num_elements, &l, &extra1); +l += extra1; break; case XIValuatorClass: l = sizeof(XIValuatorClassInfo); +l = pad_to_double(sizeof(XIValuatorClassInfo)); break; default: printf("sizeDeviceClassType: unknown type %d\n", type); @@ -1123,20 +1172,21 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie, { case XIButtonClass: { -int size; +int struct_size; +int state_size; +int labels_size; XIButtonClassInfo *bin, *bout; bin = (XIButtonClassInfo*)any; -bout = next_block(&ptr, sizeof(XIButtonClass)); +sizeXIButtonClassType(bin->num_buttons, &struct_size, + &state_size, &labels_size); +bout = next_block(&ptr, struct_size); *bout = *bin; -/* Force mask alignment with longs to avoid unaligned - * access when accessing the atoms. */ -size = bout->state.mask_len/4 * sizeof(Atom); -bout->state.mask = next_block(&ptr, size); +bout->state.mask = next_block(&ptr, state_size); memcpy(bout->state.mask, bin->state.mask, bout->state.mask_len); -bout->labels = next_block(&ptr, bout->num_buttons * sizeof(Atom)); +bout->labels = next_block(&ptr, labels_size); memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom)); out->classes[i] = (XIAnyClassInfo*)bout; break; @@ -1144,11 +1194,15 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie, case XIKeyClass: { XIKeyClassInfo *kin, *kout; +int struct_size; +int keycodes_size; kin = (XIKeyClassInfo*)any; +sizeXIKeyClassType(kin->num_keycodes, &struct_size, + &keycodes_size); -
Bug#636920: libxi6: Many programs crash with SIGBUS on startup
tags 636920 + fixed-upstream thanks As I've been bitten by this bug now (#666452) I tested some upstream releases. 1.5.99.2 and 1.5.99.3 both had the same problem and everything works fine with 1.6.0. So c1a5a70b51f12dedf354102217c7cd4247ed3a4b [1] seems to have fixed the issue. Regards [1] http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=c1a5a70b51f12dedf354102217c7cd4247ed3a4b -- Sebastian Ramacher signature.asc Description: OpenPGP digital signature
Bug#636920: libxi6: Many programs crash with SIGBUS on startup
Package: libxi6 Version: 2:1.4.3-3 Severity: important Tags: upstream On mipsel (Loongson 2F, Yeeloong), many programs (at least all programs that use libgtk-3-0) crash with SIGBUS immediately when executed, e.g.: $ gnome-terminal Bus error Same with gnome-calculator, gcalctool, epiphany and anjuta. I have traced the problem to an unaligned access in libxi (see GDB output below) and have made a quick patch to fix the bug. (gdb) run Starting program: /usr/bin/gnome-terminal Program received signal SIGBUS, Bus error. [...] (gdb) bt #0 0x2bb62c0c in copy_classes (to=0x47be8c, from=, nclasses=3) at ../../src/XExtInt.c:1532 #1 0x2bb642dc in XIQueryDevice (dpy=0x465fc8, deviceid=, ndevices_return=) at ../../src/XIQueryDevice.c:90 #2 0x2b044314 in gdk_x11_device_manager_xi2_constructed (object=0x461aa0) at /build/buildd-gtk+3.0_3.0.11-1-mipsel-_rUgEi/gtk+3.0-3.0.11/./gdk/x11/gdkdevicemanager-xi2.c:413 #3 0x2b2bc5a8 in g_object_newv () from /usr/lib/libgobject-2.0.so.0 #4 0x2b2bce04 in g_object_new_valist () from /usr/lib/libgobject-2.0.so.0 #5 0x2b2bcf6c in g_object_new () from /usr/lib/libgobject-2.0.so.0 #6 0x2b042540 in _gdk_x11_device_manager_new (display=0x470800) at /build/buildd-gtk+3.0_3.0.11-1-mipsel-_rUgEi/gtk+3.0-3.0.11/./gdk/x11/gdkdevicemanager-x11.c:59 #7 0x2b047ba0 in _gdk_x11_display_open (display_name=) at /build/buildd-gtk+3.0_3.0.11-1-mipsel-_rUgEi/gtk+3.0-3.0.11/./gdk/x11/gdkdisplay-x11.c:1228 #8 0x2b045898 in gdk_x11_display_manager_open_display ( manager=, name=) at /build/buildd-gtk+3.0_3.0.11-1-mipsel-_rUgEi/gtk+3.0-3.0.11/./gdk/x11/gdkdisplaymanager-x11.c:55 #9 0x2ad20878 in post_parse_hook (context=, group=, data=0x459500, error=0x7fff3448) at /build/buildd-gtk+3.0_3.0.11-1-mipsel-_rUgEi/gtk+3.0-3.0.11/./gtk/gtkmain.c:904 #10 0x2b3d1690 in g_option_context_parse () from /lib/libglib-2.0.so.0 #11 0x0041bd2c in ?? () [...] (gdb) info locals cls_wire = 0x47ce08 any_lib = 0x47b104 any_wire = 0x47ce08 ptr_lib = 0x47b134 [...] -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (500, 'testing') Architecture: mipsel (mips64) Kernel: Linux 3.0.0-loongson-2f (PREEMPT) Locale: LANG=nb_NO.utf8, LC_CTYPE=nb_NO.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libxi6 depends on: ii libc6 2.13-10Embedded GNU C Library: Shared lib ii libx11-6 2:1.4.3-2 X11 client-side library ii libxext6 2:1.3.0-3 X11 miscellaneous extension librar ii multiarch-support 2.13-10Transitional package to ensure mul libxi6 recommends no packages. libxi6 suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org