We also need to protect prior removal of the binstub, otherwise it can
happen that:
* Process A removes prior binstub FOO.
* Process B removes prior binstub FOO (does nothing actually because Process A already removed it).
* Process A writes binstub FOO for gem BAR from the beginning of file.
* Process B writes binstub FOO for gem BAZ from the beginning of file.
Similarly as before, if binstub FOO for gem BAR is bigger that binstub
FOO for gem BAZ, garbage bytes will be left around at the end of the
file, corrupting the binstub.
The solution is to also protect removal of the previous binstub. To do
this, we use a file lock on an explicit `.lock` file.
https://github.com/rubygems/rubygems/commit/d99a80e62d
There's an issue when multiple processes try to write the same binstub.
The problem is that our file locking mechanism is incorrect because
files are truncated _before_ they are locked. So it can happen that:
* Process A truncates binstub FOO.
* Process B truncates binstub FOO.
* Process A writes binstub FOO for gem BAR from the beginning of file.
* Process B writes binstub FOO for gem BAZ from the beginning of file.
If binstub FOO for gem BAR is bigger than binstub FOO for gem BAZ, then
some bytes will be left around at the end of the binstub, making it
corrupt.
This was not a problem in our specs until the spec testing binstubs with
the same name coming from different gems changed from using gems named
"fake" and "rack" to using gems named "fake" and "myrack". Because of
the difference in gem name length, the generated binstub for gem
"myrack" is now longer, causing the above problem if binstub for gem
myrack is written first.
The solution is to make sure when using flock to always use modes that
DON'T truncate the file when opening it. So, we use `r+` if the file
exists previously (it requires the file to exist previously), otherwise
we use `a+`.
https://github.com/rubygems/rubygems/commit/ce8bcba90f
We do not implement CET shadow-stack switching in amd64 Context.S. If
you compile Ruby with `-fcf-protection=full` and run it with
`GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK` exported, it will crash with a
control flow exception.
Configure the appropriate notes at the end of Context.S
[Bug #18061]
The dtrace python script from systemtap on Linux actually looks at the
CFLAGS environment variable when invoking gcc to make the probes.o file.
If we don't pass the CFLAGS we're using, this probes.o file can wind up
without the required annotations indicating that it supports e.g. Intel
CET.
Fix this by explicitly exporting our build flags to the environment for
this script.
[Bug #18061]
This partially reverts https://github.com/ruby/ruby/pull/10944; now that
we decided to pass CFLAGS to $(CC) when assembling .S files, we don't
need these autoconf macros that capture the state of
__ARM_FEATURE{PAC|BTI}_DEFAULT.
[Bug #20601]
We already assemble our assembly files using the $(CC) compiler driver,
rather than the actual $(AS) assembler. This means that
* The C preprocessor gets run on the assembly file
* It's valid to pass gcc-style flags to it, like e.g.
-mbranch-protection or -fcf-protection
* If you do so, the relevant preprocessor macros like __CET__ get set
* If you really wanted to pass assembler flags, you would need to do
that using -Wa,... anyway
So I think it makes sense to pass "$(XCFLAGS) $(CFLAGS) $(CPPFLAGS)" to
gcc/clang/etc when assembling, rather than passing $(ASFLAGS) (since
the flags are not actually passed to `as`, but `cc`!).
The side effect of this is that if there are mitigation flags like
-fcf-protection in $CFLAGS, then the relevant macros like __CET__ will
be defined when assembling the files.
[Bug #20601]
Previously, a TypeError was not raised if there were no thread
variables, because the conversion to symbol was done after that
check. Convert to symbol before checking for whether thread
variables are set to make the behavior consistent.
Fixes [Bug #20606]
This commit changes the external GC API to use `--with-shared-gc=DIR` at
configure time with a directory of the external GC and uses
`RUBY_GC_LIBRARY` environment variable to load the external GC at
runtime.
We only collect GC.stat_heap(nil, stat_heap_all)
once, outside of the loop, but assert_equal could
allocate objects which can cause a GC to run and
cause stat_heap_all to be out-of-sync.
When Ruby is built with ASAN and RUBY_FREE_AT_EXIT is enabled, the
following error occurs:
READ of size 8 at 0x74c666610020 thread T0
#0 0x593b6712ecc6 in RB_BUILTIN_TYPE include/ruby/internal/value_type.h:191:30
#1 0x593b6712ecc6 in rb_gc_impl_shutdown_free_objects gc_impl.c:3208:17
#2 0x593b6749a62e in ruby_vm_destruct vm.c:3133:17