-
-
Notifications
You must be signed in to change notification settings - Fork 419
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix use after free bug in actor heap finalisation that can lead to a …
…segfault (#4522) A long time ago, some rando named "Dipin Hora" decided to be clever and rework how objects with finalisers are stored/garbage collected in actor heaps (see: #1638). Unfortunately for us all, he wasn't nearly as clever as he thought and introduced a use after free bug that only occurs when finalisers have logic to reference other objects that might have already been freed and reused during the same garbage collection process. Luckily for us, a smarterer rando who also happens to be named "Dipin Hora" has come along to save the day. This commit adds in tests to reproduce the bug and rework the actor heap garbage collection logic to make sure this issue can no longer occur by making sure that: * finalisers can no longer re-use memory that might be freed earlier in the garbage collection process * heap chunks are only freed/destroyed after all finalisers have been run to ensure all cross object references in finalisers remain valid at the time the finalisers are run
- Loading branch information
Showing
8 changed files
with
316 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Fix use after free bug in actor heap finalisation that can lead to a segfault | ||
|
||
The [0.45.2](https://github.com/ponylang/ponyc/releases/tag/0.45.2) release introduced an improvement to handling of objects with finalisers to make them more efficient to allocate on actor heaps. However, in the process it also introduced a potential for use after free situations that could lead to segfaults when running finalisers. With this change, we've reworked the implementation of the actor heap garbage collection to avoid the potential for use after free situations entirely. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
test/full-program-tests/large-dependent-finalisers/additional.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include <stdint.h> | ||
#include <pony.h> | ||
|
||
#ifdef _MSC_VER | ||
# define EXPORT_SYMBOL __declspec(dllexport) | ||
#else | ||
# define EXPORT_SYMBOL | ||
#endif | ||
|
||
extern "C" | ||
{ | ||
|
||
static uint32_t num_objects = 3; | ||
|
||
EXPORT_SYMBOL extern void codegentest_large_dependent_finalisers_decrement_num_objects() | ||
{ | ||
num_objects--; | ||
pony_exitcode((int)num_objects); | ||
} | ||
|
||
#ifndef _MSC_VER | ||
void Main_runtime_override_defaults_oo(void* opt) | ||
{ | ||
(void)opt; | ||
return; | ||
} | ||
#endif | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
test/full-program-tests/large-dependent-finalisers/expected-exit-code.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1 |
95 changes: 95 additions & 0 deletions
95
test/full-program-tests/large-dependent-finalisers/main.pony
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use "lib:large-dependent-finalisers-additional" | ||
|
||
use @codegentest_large_dependent_finalisers_decrement_num_objects[None]() | ||
|
||
class _Final | ||
let num: USize | ||
let num2: USize = 0 | ||
let num3: USize = 0 | ||
let num4: USize = 0 | ||
let num5: USize = 0 | ||
let num6: USize = 0 | ||
let num7: USize = 0 | ||
let num8: USize = 0 | ||
let num9: USize = 0 | ||
let num10: USize = 0 | ||
let num11: USize = 0 | ||
let num12: USize = 0 | ||
let num13: USize = 0 | ||
let num14: USize = 0 | ||
let num15: USize = 0 | ||
let num16: USize = 0 | ||
let num17: USize = 0 | ||
let num18: USize = 0 | ||
let num19: USize = 0 | ||
let num20: USize = 0 | ||
let num21: USize = 0 | ||
let num22: USize = 0 | ||
let num23: USize = 0 | ||
let num24: USize = 0 | ||
let num25: USize = 0 | ||
let num26: USize = 0 | ||
let num27: USize = 0 | ||
let num28: USize = 0 | ||
let num29: USize = 0 | ||
let num30: USize = 0 | ||
let num31: USize = 0 | ||
let num32: USize = 0 | ||
let num33: USize = 0 | ||
let num34: USize = 0 | ||
let num35: USize = 0 | ||
let num36: USize = 0 | ||
let num37: USize = 0 | ||
let num38: USize = 0 | ||
let num39: USize = 0 | ||
let num40: USize = 0 | ||
let num41: USize = 0 | ||
let num42: USize = 0 | ||
let num43: USize = 0 | ||
let num44: USize = 0 | ||
let num45: USize = 0 | ||
let num46: USize = 0 | ||
let num47: USize = 0 | ||
let num48: USize = 0 | ||
let num49: USize = 0 | ||
let num50: USize = 0 | ||
let num51: USize = 0 | ||
let num52: USize = 0 | ||
let num53: USize = 0 | ||
let num54: USize = 0 | ||
let num55: USize = 0 | ||
let num56: USize = 0 | ||
let num57: USize = 0 | ||
let num58: USize = 0 | ||
let num59: USize = 0 | ||
let num60: USize = 0 | ||
let num61: USize = 0 | ||
let num62: USize = 0 | ||
let num63: USize = 0 | ||
let num64: USize = 0 | ||
let num65: USize = 0 | ||
let num66: USize = 0 | ||
let num67: USize = 0 | ||
let num68: USize = 0 | ||
let num69: USize = 0 | ||
let num70: USize = 0 | ||
var other: (_Final | None) = None | ||
|
||
new create(n: USize) => | ||
num = n | ||
|
||
fun _final() => | ||
match other | ||
| None => None | ||
| let o: this->_Final => | ||
if 1025 == (num + o.num) then | ||
@codegentest_large_dependent_finalisers_decrement_num_objects() | ||
end | ||
end | ||
|
||
actor Main | ||
new create(env: Env) => | ||
let f1 = _Final(1) | ||
let f2 = _Final(1024) | ||
f1.other = f2 | ||
f2.other = f1 |
29 changes: 29 additions & 0 deletions
29
test/full-program-tests/small-dependent-finalisers/additional.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include <stdint.h> | ||
#include <pony.h> | ||
|
||
#ifdef _MSC_VER | ||
# define EXPORT_SYMBOL __declspec(dllexport) | ||
#else | ||
# define EXPORT_SYMBOL | ||
#endif | ||
|
||
extern "C" | ||
{ | ||
|
||
static uint32_t num_objects = 1025; | ||
|
||
EXPORT_SYMBOL extern void codegentest_small_dependent_finalisers_decrement_num_objects() | ||
{ | ||
num_objects--; | ||
pony_exitcode((int)num_objects); | ||
} | ||
|
||
#ifndef _MSC_VER | ||
void Main_runtime_override_defaults_oo(void* opt) | ||
{ | ||
(void)opt; | ||
return; | ||
} | ||
#endif | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
test/full-program-tests/small-dependent-finalisers/expected-exit-code.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1 |
Oops, something went wrong.