Bug #20863
closed`zlib.c` calls `rb_str_set_len` and `rb_str_modify_expand`(and others) without holding the GVL.
Description
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 thez->buf
changing size while in use by therb_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