Bug #22387
closedstr_shared_replace incorrectly recalculates termlen
Description
This ruby snippet crashes under ASan with a heap-buffer-overflow
s = ("\u{30AF}" * 7).encode("UTF-16LE").b
s.force_encoding("UTF-16LE")
s.encode!("UTF-8") # 21 bytes in a 22-byte malloc, capa now claims 22
s << "x" # fits, per capa, then NUL terminator written at [22]
str_shared_replace uses rb_enc_associate which recalculates termlen based on the old str even though the termlen of the new str was already used for the copy.
We can just switch that to rb_enc_raw_set to fix.
Updated by rwstauner (Randy Stauner) 25 days ago
PR for master: https://github.com/ruby/ruby/pull/19103
Updated by rwstauner (Randy Stauner) 25 days ago
bakport for 4.0: https://github.com/ruby/ruby/pull/19104
Updated by rwstauner (Randy Stauner) 25 days ago
- Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: REQUIRED to 3.3: UNKNOWN, 3.4: REQUIRED, 4.0: REQUIRED
Backport PR for 3.4: https://github.com/ruby/ruby/pull/19105
Updated by rwstauner (Randy Stauner) 25 days ago
- Backport changed from 3.3: UNKNOWN, 3.4: REQUIRED, 4.0: REQUIRED to 3.3: DONTNEED, 3.4: REQUIRED, 4.0: REQUIRED
Updated by rwstauner (Randy Stauner) 25 days ago
- Description updated (diff)
Updated by Anonymous 25 days ago
- Status changed from Open to Closed
Applied in changeset git|67cd1d3bde0fc3c1afe2fab3aaac8c10edd12e5b.
[Bug #22387] Fix termlen in str_shared_replace (#19104)
[Bug #22387] Fix termlen in str_shared_replace
The buffer is copied over based on the new string's termlen
so we can just set the new encoding raw
instead of recalculating based on the old encoding's termlen.
Updated by k0kubun (Takashi Kokubun) 14 days ago
- Backport changed from 3.3: DONTNEED, 3.4: REQUIRED, 4.0: REQUIRED to 3.3: DONTNEED, 3.4: REQUIRED, 4.0: DONE
ruby_4_0 67cd1d3bde0fc3c1afe2fab3aaac8c10edd12e5b.
Updated by nagachika (Tomoyuki Chikanaga) 11 days ago
- Backport changed from 3.3: DONTNEED, 3.4: REQUIRED, 4.0: DONE to 3.3: DONTNEED, 3.4: DONE, 4.0: DONE
Merged into ruby_3_4 at https://github.com/ruby/ruby/commit/cc3e2b96872f7a91561c48ed814b5645a8d53030.
BTW the corresponding commit hash on master branch is 323c1df196cd3ba12274757ff1739ca79b02e685.