summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-09-11 10:51:00 -0400
committerPeter Zhu <peter@peterzhu.ca>2025-09-12 08:00:54 -0400
commit2687ecaf6fc3e07ce3cbe089d0537eb94518c082 (patch)
tree651cc9ad47516ff78cb88c3967d9c447279e259c
parent38ec296ce5e7e4cf0ac49b2fa43eec9e6a53e269 (diff)
Fix use of uninitialized memory in strings
Strings created from the C API with a len but no ptr have a buffer allocated and the length set, but the buffer is not zero'd. This causes use of uninitialized memory and allows reading memory that previously existed there. For example, the rb_str_tmp_new spec fails when we create a string with a large length greater than 24 bytes (since we zero the first 24 bytes of the slot).
-rw-r--r--spec/ruby/optional/capi/string_spec.rb18
-rw-r--r--string.c3
2 files changed, 16 insertions, 5 deletions
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index be9cb9015f..605c43769d 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -191,11 +191,19 @@ describe "C-API String function" do
end
it "returns a new String object filled with \\0 bytes" do
- s = @s.rb_str_tmp_new(4)
- s.encoding.should == Encoding::BINARY
- s.bytesize.should == 4
- s.size.should == 4
- s.should == "\x00\x00\x00\x00"
+ lens = [4]
+
+ ruby_version_is "3.5" do
+ lens << 100
+ end
+
+ lens.each do |len|
+ s = @s.rb_str_tmp_new(len)
+ s.encoding.should == Encoding::BINARY
+ s.bytesize.should == len
+ s.size.should == len
+ s.should == "\x00" * len
+ end
end
end
diff --git a/string.c b/string.c
index 20873a35a5..7b8a55a535 100644
--- a/string.c
+++ b/string.c
@@ -1066,6 +1066,9 @@ str_enc_new(VALUE klass, const char *ptr, long len, rb_encoding *enc)
if (ptr) {
memcpy(RSTRING_PTR(str), ptr, len);
}
+ else {
+ memset(RSTRING_PTR(str), 0, len);
+ }
STR_SET_LEN(str, len);
TERM_FILL(RSTRING_PTR(str) + len, termlen);