Control: tag -1 moreinfo
On Mon, Mar 24, 2014 at 04:31:16AM +1100, Steven McDonald wrote:
> Package: xserver-xorg-core
> Version: 2:1.15.0-2
> Severity: normal
> Tags: upstream patch
>
> Hi there!
>
> While trying to play the game FTL, installed using Debian's steam:i386
> package, I experienced consistently reproducible X segfaults at game
> startup time.
>
> Doing a bit of digging with gdb, I got the following backtrace from the
> active thread at the time of the segfault:
>
> ---------------------- 8< ----------------------
> #0 _mesa_GenTextures (n=256, textures=<optimized out>) at ../../../../src/mesa/main/texobj.c:1031
> #1 0x00007f825ccce606 in __glXDisp_GenTextures (cl=0x7f826383bce0, pc=<optimized out>) at ../../glx/indirect_dispatch.c:2596
> #2 0x00007f825cce21a0 in __glXDispatch (client=<optimized out>) at ../../glx/glxext.c:606
> #3 0x00007f826260584e in Dispatch () at ../../dix/dispatch.c:433
> #4 0x00007f826260964a in dix_main (argc=8, argv=0x7fff41a21a28, envp=<optimized out>) at ../../dix/main.c:294
> #5 0x00007f825fe4ab45 in __libc_start_main (main=0x7f82625f4c00 <main>, argc=8, argv=0x7fff41a21a28, init=<optimized out>, fini=<optimized out>,
> rtld_fini=<optimized out>, stack_end=0x7fff41a21a18) at libc-start.c:287
> #6 0x00007f82625f4c2e in _start ()
> ---------------------- >8 ----------------------
>
> After a little more digging, I found that the fault is in xorg-server
> and not mesa, due to __glXDisp_GenTextures passing a garbage pointer as
> the second argument to _mesa_GenTextures. This pointer comes from
> __glXGetAnswerBuffer within xorg-server.
>
> I found that line 94 of glx/indirect_util.c in particular is
> responsible for turning the pointer into a garbage value:
>
> temp_buf = (temp_buf + mask) & ~mask;
>
> I don't have a very deep understanding of how this line is evaluated,
> but as best I can determine, (temp_buf + mask) is an "intptr_t" (which
> should be a 64-bit value on my 64-bit system), and mask is a
> "const unsigned" (which is a 32-bit integer). NOTing mask and ANDing
> the result with a 64-bit pointer seems to produce a pointer limited to
> the range of a 32-bit integer, which causes a segfault when access is
> attempted.
>
> I did notice that the same behaviour does not manifest with mask as a
> *signed* 32-bit value, but I can't explain that with my level of C
> knowledge.
>
> In any case, I am attaching a patch which fixes the problem by changing
> the declaration of mask from "const unsigned" to "const uintptr_t".
> I've tested and confirmed that I can run the game with this patch
> applied.
>
> Please let me know if you need any further information. :)
>
> - Steven
>
Hi,
is this still an issue with a newer xserver-xorg-core version (e.g.
the version from jessie or stretch/sid)?
Thanks,
Andreas
> Make sure we're using a pointer-sized integer when doing pointer
> arithmetic.
> --- a/glx/indirect_util.c
> +++ b/glx/indirect_util.c
> @@ -73,7 +73,7 @@
> void *local_buffer, size_t local_size, unsigned alignment)
> {
> void *buffer = local_buffer;
> - const unsigned mask = alignment - 1;
> + const uintptr_t mask = alignment - 1;
>
> if (local_size < required_size) {
> const size_t worst_case_size = required_size + alignment;
Attachment:
signature.asc
Description: Digital signature