Bug 25492

Summary: make -C test/xi2 check fails on sparc and ppc
Product: xorg Reporter: Julien Cristau <jcristau>
Component: Server/Input/CoreAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: peter.hutterer
Version: 7.5 (2009.10)   
Hardware: SPARC   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
patch to fix the test none

Description Julien Cristau 2009-12-07 10:39:59 UTC
build logs at http://launchpadlibrarian.net/36535627/buildlog_ubuntu-lucid-sparc.xorg-server_2%3A1.7.2-2ubuntu1_FAILEDTOBUILD.txt.gz and http://launchpadlibrarian.net/36532905/buildlog_ubuntu-lucid-powerpc.xorg-server_2%3A1.7.2-2ubuntu1_FAILEDTOBUILD.txt.gz

i reproduced this on debian's sparc porterbox:

Reading symbols from /home/jcristau/xorg-server-1.7.2/obj-sparc-linux-gnu/test/xi2/protocol-eventconvert...done.
(gdb) run
Starting program: /home/jcristau/xorg-server-1.7.2/obj-sparc-linux-gnu/test/xi2/protocol-eventconvert 
[Thread debugging using libthread_db enabled]
/xi2/eventconvert/XIRawEvent: OK
/xi2/eventconvert/XIFocusEvent: [dix] EventToXI2: Not implemented for 10 
[dix] EventToXI2: Not implemented for 8 
OK
/xi2/eventconvert/XIDeviceEvent: OK
/xi2/eventconvert/XIDeviceChangedEvent: **
ERROR:../../../test/xi2/protocol-eventconvert.c:714:test_values_XIDeviceChangedEvent: assertion failed: (k->length == bytes_to_int32(sizeof(xXIKeyInfo)) + k->num_keycodes)

Program received signal SIGABRT, Aborted.
0xf7a580f0 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
67      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
        in ../nptl/sysdeps/unix/sysv/linux/raise.c
(gdb) bt full
#0  0xf7a580f0 in *__GI_raise (sig=6)
[...]
#4  0x0001d1dc in test_values_XIDeviceChangedEvent (in=0xffd8ec34, 
    out=0xf789e008, swap=0 '\000')
    at ../../../test/xi2/protocol-eventconvert.c:712
        k = 0xf789e500
        kc = 0x18e250
        any = 0xf789e500
        i = 5
        j = 256
        ptr = 0xf789e500 ""
        __PRETTY_FUNCTION__ = "test_values_XIDeviceChangedEvent"
#5  0x0001d55c in test_XIDeviceChangedEvent (in=0xffd8ec34)
    at ../../../test/xi2/protocol-eventconvert.c:754
        out = 0xf789e008
        swapped = 0x18de00
        rc = 0
        __PRETTY_FUNCTION__ = "test_XIDeviceChangedEvent"
#6  0x0001d89c in test_convert_XIDeviceChangedEvent ()
    at ../../../test/xi2/protocol-eventconvert.c:839
        in = {header = 255 '\377', type = ET_DeviceChanged, length = 1792, 
          time = 4294967295, deviceid = 65535, flags = 14, masterid = 65535, 
          sourceid = 65535, buttons = {num_buttons = 256, names = {10, 11, 12, 
              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 
              29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 
              45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 
              61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 
              77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 
              93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 
              107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 
              120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 
              133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 
              146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 
              159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 
              172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 
              185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 
              198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209...}}, 
          num_valuators = 4, valuators = {{min = 0, max = 0, resolution = 0, 
              mode = 0 '\000', name = 0} <repeats 36 times>}, keys = {
            min_keycode = 0, max_keycode = 65533}}
        i = 256
#7  0xf7d113c0 in ?? () from /lib/libglib-2.0.so.0
(gdb) frame 4
(gdb) p k
$1 = (xXIKeyInfo *) 0xf789e500
(gdb) p *k
$2 = {type = 0, length = 42, sourceid = 0, num_keycodes = 43}
(gdb) p *any
$3 = {type = 0, length = 42, sourceid = 0, pad = 43}
(gdb) p out
$4 = (xXIDeviceChangedEvent *) 0xf789e008
(gdb) p *out
$5 = {type = 35 '#', extension = 0 '\000', sequenceNumber = 0, length = 65846, 
  evtype = 1, deviceid = 65535, time = 4294967295, num_classes = 6, 
  sourceid = 65535, reason = 1 '\001', pad0 = 0 '\000', pad1 = 0, pad2 = 0, 
  pad3 = 0}

I don't have time to track this down further right now unfortunately.
Comment 1 Peter Hutterer 2009-12-07 17:28:10 UTC
weird. just verified this doesn't happen on my x86 box.

(gdb) p *k
$2 = {type = 0, length = 42, sourceid = 0, num_keycodes = 43}

I don't know how that could happen, it reeks of some other corruption. The matching length field is calculated in appendKeyInfo (dix/eventconvert.c) and it's a simple sizeof(xXIKeyInfo)/4 + num_keycodes. so in this case, length should be 45.

if you find time to valgrind this test, that'd be great. you can run it directly, just execute the protocol-eventconvert binary.
Comment 2 Julien Cristau 2009-12-22 06:18:00 UTC
> --- Comment #1 from Peter Hutterer <peter.hutterer@who-t.net>  2009-12-07 17:28:10 PST ---
> if you find time to valgrind this test, that'd be great. you can run it
> directly, just execute the protocol-eventconvert binary.
> 
reproduced on powerpc, which does have valgrind.  Unfortunately, no
luck, it doesn't seem to find any error.
Comment 3 Julien Cristau 2009-12-22 08:18:43 UTC
Created attachment 32246 [details] [review]
patch to fix the test
Comment 4 Julien Cristau 2009-12-22 08:19:09 UTC
I think I understand what happened.  Not sure why it doesn't trigger on all platforms though...

We run test_XIDeviceChangedEvent(&in); with in.keys.min_keycode = 0 and in.keys.max_keycode = 0xFFFD.  In appendKeyInfo(), we set info->num_keycodes to dce->keys.max_keycode - dce->keys.min_keycode + 1 (which is 0xFFFE).  And then info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes is 0, since info->length is u16.  appendKeyInfo() returns 0, and the event gets corrupted.  Changing the test to set in.keys.max_keycode to 0xFFFC makes it pass.
Comment 5 Peter Hutterer 2009-12-22 18:57:26 UTC
interesting. because appendKeyInfo returns 0, the pointer isn't advanced and the key field is simply overwritten with the next valuator. Because of that and random misc, the next couple of classes are then interpreted as valuator information and I think the reason that it fails on ppc is that some values (garbage) are byte-swapped and trigger the error, where they just happen to be correct on x86.

Anyway, patch to trigger failure on x86 is here:
http://lists.freedesktop.org/archives/xorg-devel/2009-December/004339.html

I've merged your patch, it works. Will be in my next pull request.
Comment 6 Julien Cristau 2009-12-23 02:01:55 UTC
Both patches are in master now, closing.

commit b44c9be244cee286835855483a69c69e80b095c0
Author: Julien Cristau <jcristau@debian.org>
Date:   Tue Dec 22 17:14:09 2009 +0100

    test/xi2: fix maximum max_keycode (bug#25492)
    
    The number of keycodes needs to be lower than 0xFFFD so that the length
    field of xXIKeyInfo doesn't overflow.
    
    Signed-off-by: Julien Cristau <jcristau@debian.org>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

commit 90e6d93cf9bfafd63d7849dc16ce194d6f9c9d5f
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Dec 23 12:54:14 2009 +1000

    test/xi2: fail if xi2 class type is garbage. (#25492)
    
    If the keycode range exceeds the allowable length, memory gets overwritten.
    Catch this case by making sure that only allowed class types are
    present.
    
    X.Org Bug 25492 <http://bugs.freedesktop.org/show_bug.cgi?id=25492>
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Keith Packard <keithp@keithp.com>

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.