summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Dalessio <mike.dalessio@gmail.com>2023-04-04 23:55:43 -0400
committerPeter Zhu <peter@peterzhu.ca>2023-04-05 12:57:32 -0400
commit52e571fa72debcd764765775bd1b76ee87e36d2d (patch)
tree58e5de4f4a64709c50472e7070a0db67de795d20
parent533423ebe46ebfe3005198c12aa0d2c899c695ea (diff)
Ensure ruby_xfree won't segfault if called after vm_destruct
[Bug #19580] The real-world scenario motivating this change is libxml2's pthread code which uses `pthread_key_create` to set up a destructor that is called at thread exit to free thread-local storage. There is a small window of time -- after ruby_vm_destruct but before the process exits -- in which a pthread may exit and the destructor is called, leading to a segfault. Please note that this window of time may be relatively large if `atexit` is being used.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7663
-rw-r--r--gc.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/gc.c b/gc.c
index 6f68bbbea7..0a0572e208 100644
--- a/gc.c
+++ b/gc.c
@@ -12581,8 +12581,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size)
void
ruby_sized_xfree(void *x, size_t size)
{
- if (x) {
- objspace_xfree(&rb_objspace, x, size);
+ if (LIKELY(x)) {
+ /* It's possible for a C extension's pthread destructor function set by pthread_key_create
+ * to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in
+ * that case. */
+ if (LIKELY(GET_VM())) {
+ objspace_xfree(&rb_objspace, x, size);
+ }
+ else {
+ ruby_mimfree(x);
+ }
}
}