
Issue #20863 has been updated by byroot (Jean Boussier). @ko1 Do we have a proper description of what is safe and what it unsafe to do with the GVL released? Because obviously it's OK to use `ruby_xmalloc / ruby_xfree` with the GVL released, so methods which allocate aren't necessarily problematic?\ In this case I'm unclear on why `rb_str_set_len` / `rb_str_modify_expand` shouldn't be called with the GVL released, assuming the objects on which they operate aren't visible to any other thread. I think it would be helpful to have more clear guidelines on these things (unless of course I missed some existing documentation). ---------------------------------------- Bug #20863: `zlib.c` calls `rb_str_set_len` and `rb_str_modify_expand`(and others) without holding the GVL. https://bugs.ruby-lang.org/issues/20863#change-110500 * Author: ioquatix (Samuel Williams) * Status: Open * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- ## Background I was working on https://bugs.ruby-lang.org/issues/20876 and was investigating some problems with `zlib.c` and GVL, and noticed that `zstream_run_func` is executed without the GVL, but can invoke various `rb_` string functions. Those functions in turn can invoke `rb_raise` and generally look problematic. However, maybe by luck, such code path does not appear to be invoked in typical usage. However, even so, it is possible to cause `zstream_run_func` to segfault by a carefully crafted program which causes the internal buffer to be resized while the GVL is released: https://github.com/ruby/zlib/pull/88#issuecomment-2455772054 ## Proposal I would like to modify `zlib.c` to only release the GVL around the CPU intensive compression/decompression operation: https://github.com/ruby/zlib/pull/88 In addition, I identified several more improvements to prevent segfaults and other related failures: - Use `rb_str_locktemp` to prevent the `z->buf` changing size while in use by the `rb_nogvl` code. - Expand the mutex to protect `#deflate` and `#inflate` completely, not just the internal operation. In order to catch these issues earlier and find other bugs like this, I recommend we introduce additional checks: https://bugs.ruby-lang.org/issues/20877 -- https://bugs.ruby-lang.org/