ASAN leaves a pointer to the fake frame on the stack; we can use the
__asan_addr_is_in_fake_stack API to work out the extent of the fake
stack and thus mark any VALUEs contained therein.
[Bug #20001]
__has_feature is a clang-ism, and GCC has a different way to tell if
sanitizers are enabled. For this reason, I don't want to spray
__has_feature all over the codebase for other places where conditional
compilation based on sanitizers is required.
[Bug #20001]
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.
The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly
[Bug #20001]
The implementation of `native_thread_init_stack` for the various
threading models can use the address of a local variable as part of the
calculation of the machine stack extents:
* pthreads uses it as a lower-bound on the start of the stack, because
glibc (and maybe other libcs) can store its own data on the stack
before calling into user code on thread creation.
* win32 uses it as an argument to VirtualQuery, which gets the extent of
the memory mapping which contains the variable
However, the local being used for this is actually allocated _inside_
the `native_thread_init_stack` frame; that means the caller might
allocate a VALUE on the stack that actually lies outside the bounds
stored in machine.stack_{start,end}.
A local variable from one level above the topmost frame that stores
VALUEs on the stack must be drilled down into the call to
`native_thread_init_stack` to be used in the calculation. This probably
doesn't _really_ matter for the win32 case (they'll be in the same
memory mapping so VirtualQuery should return the same thing), but
definitely could matter for the pthreads case.
[Bug #20001]
Previously on builds with optimizations disabled, this could result in
an out of bounds read. When we had all of:
* built with -O0
* Leaf builtin
* Primitive.mandatory_only
* "no args builtin", called by vm_call_single_noarg_inline_builti
* The stack is escaped to the heap via binding or a proc
This is because mk_builtin_loader generated reads for all locals
regardless of whether they were used and in the case we generated a
mandatory_only iseq that would include more variables than were actually
available.
On optimized builds, the invalid accesses would be optimized away, and
this also was often unnoticed as the invalid access would just hit
another part of the stack unless it had been escaped to the heap.
The fix here is imperfect, as this could have false positives, but since
Primitive.cexpr! is only available within the cruby codebase itself
that's probably fine as a proper fix would be much more challenging (the
only false positives we found were in rjit.rb).
Fixes [Bug #20178]
Co-authored-by: Adam Hess <HParker@github.com>
When we calculate the local table size, we need to account for anonymous
"rest" parameters. Since they don't have a name, they won't be in the
"locals" table that Prism provides, but we need to reserve room for them
anyway.
Fixes: https://github.com/ruby/prism/issues/2154
Fixes: https://github.com/ruby/prism/issues/2062
This patch only fixes positional parameters, we still need to fix the
other cases spelled out in test/prism/fixtures/repeat_parameters.txt
The environ is malloc'd, so it gets reported as a memory leak. This
commit adds ruby_free_proctitle which frees it during shutdown when
RUBY_FREE_AT_EXIT is set.
STACK OF 1 INSTANCE OF 'ROOT LEAK: <calloc in ruby_init_setproctitle>':
5 dyld 0x18b7090e0 start + 2360
4 ruby 0x10000e3a8 main + 100 main.c:58
3 ruby 0x1000b4dfc ruby_options + 180 eval.c:121
2 ruby 0x1001c5f70 ruby_process_options + 200 ruby.c:3014
1 ruby 0x10035c9fc ruby_init_setproctitle + 76 setproctitle.c:105
0 libsystem_malloc.dylib 0x18b8c7b78 _malloc_zone_calloc_instrumented_or_legacy + 100
* Data#members might not be defined, instead it might be defined
on Data subclasses or a module included there. This is notably the
case on TruffleRuby which defines it there for optimization purposes.
In fact the mere presence of Data#members implies a megamorphic call
inside, so it seems best to avoid relying on its existence.
https://github.com/ruby/pp/commit/6a97d36fbb
There is another place artifice usage was making the copy of vendored
http in ruby-core be loaded instead of the one under test.
Remove unnecessary usage of artifice.
https://github.com/rubygems/rubygems/commit/d2488199b0
The fact that under the hood the upgrade is done through a
rubygems-update gem is an implementation detail that does not really
help users to know.
Plus, it reads a bit weird.
https://github.com/rubygems/rubygems/commit/0fa5c50258
If two platform specific variants have different dependencies, then
resolution may fallback to the non platform specific variant. However,
the platform specific variants that have the same dependencies as the
non specific one can still be kept.
Do a pass to complete those after resolution.