[Bug 34418] SuperTuxRacer 0.7/Warzone 2100 and r300g MemoryFault (64bit only)

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Tue Feb 22 08:10:20 PST 2011


https://bugs.freedesktop.org/show_bug.cgi?id=34418

--- Comment #12 from Wiktor Janas <wixorpeek at gmail.com> 2011-02-22 08:10:18 PST ---
Hooray, I've nailed it!

Look at setup_interleaved_attribs in st_draw.c. There's that little snippet
that computes minimum from array[...]->Ptr and... it's wrong! ->Ptr can be very
well NULL, so when there are two arrays, with one having offset 0 (and thus
NULL ->Ptr), and the other having non-zero offset, the non-zero value is taken
as minimum, which leads to negative velements[attr].src_offset being assigned
later. The trick is: that negative value is cast to unsigned, so it ends up
being a very large number. Later (in r300g), the src_offset is added to some
pointer. On 32bit machines, the pointer overflows and the overall result is as
if subtraction was performed, yielding correct result. On 64bit machine the
pointer gets messed up instead, resulting in segmentation fault.

Changing the minimum-computing code to
   /* Find the lowest address. */
   const GLubyte *low_addr = NULL;
   if(vpv->num_inputs) {
       low_addr = arrays[vp->index_to_input[0]]->Ptr;
       for (attr = 1; attr < vpv->num_inputs; attr++) {
          const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr;
          low_addr = MIN2(low_addr, start);
       }
   }
fixes segfaults with blender.

It is also beneficial to add
    assert(velements[attr].src_offset >= 0 &&
           velements[attr].src_offset < 2000000000);
in st_draw.c:369 (that exposes the bug on 32bit machines).

The (trivial) test code will be attached.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the dri-devel mailing list