diff options
author | Rubidium <rubidium@openttd.org> | 2021-05-16 07:33:32 +0200 |
---|---|---|
committer | rubidium42 <rubidium42@users.noreply.github.com> | 2021-05-16 10:07:38 +0200 |
commit | 5c01f9ea525616b432968df845a90da1d888631f (patch) | |
tree | 8a2e38439e26b43cd01fbca231184485c7297608 /src/3rdparty | |
parent | e66e25ff71d67975e4c5ba0df569339270cfafe2 (diff) | |
download | openttd-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.cpp | 8 |
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); |