Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Prevent derreference after free when retracing glFeedbackBuffer/glSel…

…ectBuffer.
  • Loading branch information...
commit 62abddc41c4f09d3688d7f56e097820cba8d16d3 1 parent dd27f9f
@jrfonseca jrfonseca authored
Showing with 34 additions and 7 deletions.
  1. +6 −0 glretrace.py
  2. +28 −7 retrace.hpp
View
6 glretrace.py
@@ -414,6 +414,12 @@ def extractArg(self, function, arg, arg_type, lvalue, rvalue):
print ' samples = max_samples;'
print ' }'
+ # These parameters are referred beyond the call life-time
+ # TODO: Replace ad-hoc solution for bindable parameters with general one
+ if function.name in ('glFeedbackBuffer', 'glSelectBuffer') and arg.output:
+ print ' _allocator.bind(%s);' % arg.name
+
+
if __name__ == '__main__':
print r'''
View
35 retrace.hpp
@@ -26,7 +26,9 @@
#ifndef _RETRACE_HPP_
#define _RETRACE_HPP_
+#include <assert.h>
#include <string.h>
+#include <stdint.h>
#include <list>
#include <map>
@@ -86,11 +88,11 @@ class map
class ScopedAllocator
{
private:
- void *next;
+ uintptr_t next;
public:
ScopedAllocator() :
- next(NULL) {
+ next(0) {
}
inline void *
@@ -99,15 +101,16 @@ class ScopedAllocator
return NULL;
}
- void * * buf = static_cast<void **>(malloc(sizeof(void *) + size));
+ uintptr_t * buf = static_cast<uintptr_t *>(malloc(sizeof(uintptr_t) + size));
if (!buf) {
return NULL;
}
*buf = next;
- next = buf;
+ next = reinterpret_cast<uintptr_t>(buf);
+ assert((next & 1) == 0);
- return &buf[1];
+ return static_cast<void *>(&buf[1]);
}
template< class T >
@@ -116,11 +119,29 @@ class ScopedAllocator
return static_cast<T *>(alloc(sizeof(T) * n));
}
+ /**
+ * Prevent this pointer from being automatically freed.
+ */
+ template< class T >
+ inline void
+ bind(T *ptr) {
+ if (ptr) {
+ reinterpret_cast<uintptr_t *>(ptr)[-1] |= 1;
+ }
+ }
+
inline
~ScopedAllocator() {
while (next) {
- void *temp = *static_cast<void **>(next);
- free(next);
+ uintptr_t temp = *reinterpret_cast<uintptr_t *>(next);
+
+ bool bind = temp & 1;
+ temp &= ~1;
+
+ if (!bind) {
+ free(reinterpret_cast<void *>(next));
+ }
+
next = temp;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.