From 62abddc41c4f09d3688d7f56e097820cba8d16d3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 13 Apr 2012 14:57:08 +0100 Subject: [PATCH] Prevent derreference after free when retracing glFeedbackBuffer/glSelectBuffer. --- glretrace.py | 6 ++++++ retrace.hpp | 35 ++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/glretrace.py b/glretrace.py index 97a6ecc..cd7fe80 100644 --- a/glretrace.py +++ b/glretrace.py @@ -414,6 +414,12 @@ class GlRetracer(Retracer): 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''' diff --git a/retrace.hpp b/retrace.hpp index dc11bb3..8ce15ad 100644 --- a/retrace.hpp +++ b/retrace.hpp @@ -26,7 +26,9 @@ #ifndef _RETRACE_HPP_ #define _RETRACE_HPP_ +#include #include +#include #include #include @@ -86,11 +88,11 @@ public: class ScopedAllocator { private: - void *next; + uintptr_t next; public: ScopedAllocator() : - next(NULL) { + next(0) { } inline void * @@ -99,15 +101,16 @@ public: return NULL; } - void * * buf = static_cast(malloc(sizeof(void *) + size)); + uintptr_t * buf = static_cast(malloc(sizeof(uintptr_t) + size)); if (!buf) { return NULL; } *buf = next; - next = buf; + next = reinterpret_cast(buf); + assert((next & 1) == 0); - return &buf[1]; + return static_cast(&buf[1]); } template< class T > @@ -116,11 +119,29 @@ public: return static_cast(alloc(sizeof(T) * n)); } + /** + * Prevent this pointer from being automatically freed. + */ + template< class T > + inline void + bind(T *ptr) { + if (ptr) { + reinterpret_cast(ptr)[-1] |= 1; + } + } + inline ~ScopedAllocator() { while (next) { - void *temp = *static_cast(next); - free(next); + uintptr_t temp = *reinterpret_cast(next); + + bool bind = temp & 1; + temp &= ~1; + + if (!bind) { + free(reinterpret_cast(next)); + } + next = temp; } } -- 2.45.2