summaryrefslogtreecommitdiff
path: root/src/3rdparty
diff options
context:
space:
mode:
authorRubidium <rubidium@openttd.org>2021-05-16 07:33:32 +0200
committerrubidium42 <rubidium42@users.noreply.github.com>2021-05-16 10:07:38 +0200
commit5c01f9ea525616b432968df845a90da1d888631f (patch)
tree8a2e38439e26b43cd01fbca231184485c7297608 /src/3rdparty
parente66e25ff71d67975e4c5ba0df569339270cfafe2 (diff)
downloadopenttd-5c01f9ea525616b432968df845a90da1d888631f.tar.xz
Fix #9267, 47a99bb: [Squirrel] Heap use after free
Due to 47a99bb the order of elements in the garbage collection chain has changed causing the class to be finalised before the instances of that class. Since the instance's array of member values depends on the size of the values in the class, the class finalisation resetting that size to 0 causes not all finalisations to run, which subsequently causes a heap use after free. So, just set the SQObjectPtrs to 'null' during the finalisation of the SQClass so the SQInstance can release all instance variables during its finalisation.
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/squirrel/squirrel/sqclass.cpp8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/3rdparty/squirrel/squirrel/sqclass.cpp b/src/3rdparty/squirrel/squirrel/sqclass.cpp
index aa1bca044..71743f464 100644
--- a/src/3rdparty/squirrel/squirrel/sqclass.cpp
+++ b/src/3rdparty/squirrel/squirrel/sqclass.cpp
@@ -34,7 +34,13 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
void SQClass::Finalize() {
_attributes = _null_;
- _defaultvalues.resize(0);
+ /* SQInstance's Finalize depends on the size of this sqvector, so instead of
+ * resizing, all SQObjectPtrs are set to "null" so it holds no references to
+ * other objects anymore. That way everything gets released properly. */
+ for (SQUnsignedInteger i = 0; i < _defaultvalues.size(); i++) {
+ _defaultvalues[i].val = _null_;
+ _defaultvalues[i].attrs = _null_;
+ }
_methods.resize(0);
_metamethods.resize(0);
__ObjRelease(_members);