[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#742433: xserver-xorg-core: Segmentation fault using bad pointer from __glXGetAnswerBuffer



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


Reply to: