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