From: "nobu (Nobuyoshi Nakada) via ruby-core" Date: 2023-05-15T05:08:23+00:00 Subject: [ruby-core:113488] [Ruby master Bug#19635] errno may be overwritten by rb_sprintf if it triggers GC Issue #19635 has been updated by nobu (Nobuyoshi Nakada). Thank you, I missed it. Please update the dependency in common.mk too. ---------------------------------------- Bug #19635: errno may be overwritten by rb_sprintf if it triggers GC https://bugs.ruby-lang.org/issues/19635#change-103074 * Author: wks (Kunshan Wang) * Status: Closed * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Here is an excerpt in the `trap` function in `signal.c` ``` c oldfunc = ruby_signal(sig, func); if (oldfunc == SIG_ERR) rb_sys_fail_str(rb_signo2signm(sig)); ``` `ruby_signal` tries to register a signal handling function. If it fails, it returns `SIG_ERR`, and `errno` is set to by `sigaction` to indicate the error. However, the snippet above calls `rb_signo2signm(sig)` before calling `rb_sys_fail_str`. `rb_signo2signm` allocates a Ruby heap object using `rb_sprintf`. The problem is, **if this `rb_sprintf` triggers GC**, the garbage collector may perform may complex operations, including executing `obj_free`, calling `mmap` to allocate more memory from the OS, etc. They **may overwrite the `errno`**. So if GC is triggered in the very unfortunate time, the caller of the `trap` function will receive an exception, but with the wrong reason. This may cause some tests, such as the `test_trap_uncatchable_#{sig}` test cases in `test_signal.rb`, to fail. There are similar use cases in `hash.c`, for example: ```c if (ret) rb_sys_fail_str(rb_sprintf("setenv(%s)", name)); ``` The good practice is always loading from `errno` immediately after calling functions that may set `errno`, such as `sigaction` and `setenv`. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/