ruby/ext
Alan Wu c06ddfee87
str_duplicate: Don't share with a frozen shared string
This is a follow up for 3f9562015e.
Before this commit, it was possible to create a shared string which
shares with another shared string by passing a frozen shared string
to `str_duplicate`.

Such string looks like:

```
 --------                    -----------------
 | root | ------ owns -----> | root's buffer |
 --------                    -----------------
     ^                             ^   ^
 -----------                       |   |
 | shared1 | ------ references -----   |
 -----------                           |
     ^                                 |
 -----------                           |
 | shared2 | ------ references ---------
 -----------
```

This is bad news because `rb_fstring(shared2)` can make `shared1`
independent, which severs the reference from `shared1` to `root`:

```c
/* from fstr_update_callback() */
str = str_new_frozen(rb_cString, shared2);  /* can return shared1 */
if (STR_SHARED_P(str)) { /* shared1 is also a shared string */
    str_make_independent(str);  /* no frozen check */
}
```

If `shared1` was the only reference to `root`, then `root` can be
reclaimed by the GC, leaving `shared2` in a corrupted state:

```
 -----------                         --------------------
 | shared1 | -------- owns --------> | shared1's buffer |
 -----------                         --------------------
      ^
      |
 -----------                         -------------------------
 | shared2 | ------ references ----> | root's buffer (freed) |
 -----------                         -------------------------
```

Here is a reproduction script for the situation this commit fixes.

```ruby
a = ('a' * 24).strip.freeze.strip
-a
p a
4.times { GC.start }
p a
```

 - string.c (str_duplicate): always share with the root string when
   the original is a shared string.
 - test_rb_str_dup.rb: specifically test `rb_str_dup` to make
   sure it does not try to share with a shared string.

[Bug #15792]

Closes: https://github.com/ruby/ruby/pull/2159
2019-05-09 10:04:19 +09:00
..
-test- str_duplicate: Don't share with a frozen shared string 2019-05-09 10:04:19 +09:00
bigdecimal Import bigdecimal 1.4.2 2018-12-26 08:17:30 +00:00
cgi/escape Use $(hdrdir) for include/ruby.h, as well as r67033 2019-02-11 13:43:14 +00:00
continuation Update dependencies 2016-07-06 05:48:13 +00:00
coverage Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
date date: support for Reiwa, new Japanese era 2019-04-09 01:27:36 +00:00
dbm Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
digest Prefer relative directory from srcdir to top_srcdir 2019-02-14 05:42:14 +00:00
etc Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
fcntl Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
fiber Update dependencies 2016-07-06 05:48:13 +00:00
fiddle Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
gdbm Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
io Use $(hdrdir) for include/ruby.h, as well as r67033 2019-02-11 13:43:14 +00:00
json Add `GC.compact` again. 2019-04-20 01:19:47 +00:00
nkf Revert "* expand tabs." 2018-12-15 14:45:36 +00:00
objspace * expand tabs. 2019-04-23 12:34:10 +09:00
openssl ext/openssl/ossl_bn.c (ossl_bn_initialize): get rid of SEGV 2019-04-10 12:57:39 +00:00
pathname Try statx syscall 2019-02-20 06:54:23 +00:00
psych syntax error can move, so do not cache 2019-04-23 15:26:21 -07:00
pty Fix PTY.open on OpenBSD [Bug #15607] 2019-03-06 09:48:39 +00:00
racc/cparse Update dependencies 2016-07-06 05:48:13 +00:00
rbconfig/sizeof configure.ac 2017-09-29 13:21:17 +00:00
readline Update the canonical repository url. 2019-05-07 23:16:26 +09:00
ripper Introduce pattern matching [EXPERIMENTAL] 2019-04-17 06:48:03 +00:00
rubyvm Disable tailcall optimization [Bug #15303] 2018-12-12 05:46:13 +00:00
sdbm Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
socket Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
stringio Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
strscan Removed needless date attribute from gemspec of default gems. 2018-08-07 12:02:10 +00:00
syslog no ID cache in Init functions 2018-02-16 08:39:48 +00:00
win32 Win32API.rb: use uplevel option to warn 2018-04-02 12:39:01 +00:00
win32ole Fix call-seq of OpenSSL.fips_mode and WIN32OLE_METHOD#name [ci skip] 2018-11-01 07:25:50 +00:00
zlib Removed moving toplevel header since r12501 2019-02-08 02:46:22 +00:00
.document ext/.document: follow-up r59734 2017-09-03 13:31:34 +00:00
Setup Removed deprecated extensions of mathn. 2017-04-20 08:21:24 +00:00
Setup.atheos * ext/tk: Tk is removed from stdlib. [Feature #8539] 2016-08-09 06:44:45 +00:00
Setup.nt * ext/tk: Tk is removed from stdlib. [Feature #8539] 2016-08-09 06:44:45 +00:00
extmk.rb Let sub-directory exts depend on their parent ext 2018-12-01 09:29:14 +00:00