diff options
author | Tian Gao <gaogaotiantian@hotmail.com> | 2024-07-18 19:47:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-18 19:47:22 (GMT) |
commit | 1ab17782832bb1b6baa915627aead3e3516a0894 (patch) | |
tree | 920f54b5c39d3ef65992dce91e4a57c4f7354581 /Lib | |
parent | 7431c3799efbd06ed03ee70b64420f45e83b3667 (diff) | |
download | cpython-1ab17782832bb1b6baa915627aead3e3516a0894.zip cpython-1ab17782832bb1b6baa915627aead3e3516a0894.tar.gz cpython-1ab17782832bb1b6baa915627aead3e3516a0894.tar.bz2 |
gh-120289: Disallow disable() and clear() in external timer to prevent use-after-free (#120297)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_cprofile.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 27e8a76..b2595ec 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -30,6 +30,43 @@ class CProfileTest(ProfileTest): self.assertEqual(cm.unraisable.exc_type, TypeError) + def test_evil_external_timer(self): + # gh-120289 + # Disabling profiler in external timer should not crash + import _lsprof + class EvilTimer(): + def __init__(self, disable_count): + self.count = 0 + self.disable_count = disable_count + + def __call__(self): + self.count += 1 + if self.count == self.disable_count: + profiler_with_evil_timer.disable() + return self.count + + # this will trigger external timer to disable profiler at + # call event - in initContext in _lsprof.c + with support.catch_unraisable_exception() as cm: + profiler_with_evil_timer = _lsprof.Profiler(EvilTimer(1)) + profiler_with_evil_timer.enable() + # Make a call to trigger timer + (lambda: None)() + profiler_with_evil_timer.disable() + profiler_with_evil_timer.clear() + self.assertEqual(cm.unraisable.exc_type, RuntimeError) + + # this will trigger external timer to disable profiler at + # return event - in Stop in _lsprof.c + with support.catch_unraisable_exception() as cm: + profiler_with_evil_timer = _lsprof.Profiler(EvilTimer(2)) + profiler_with_evil_timer.enable() + # Make a call to trigger timer + (lambda: None)() + profiler_with_evil_timer.disable() + profiler_with_evil_timer.clear() + self.assertEqual(cm.unraisable.exc_type, RuntimeError) + def test_profile_enable_disable(self): prof = self.profilerclass() # Make sure we clean ourselves up if the test fails for some reason. |