Load external GC using command line argument
This commit changes the external GC to be loaded with the `--gc-library` command line argument instead of the RUBY_GC_LIBRARY_PATH environment variable because @nobu pointed out that loading binaries using environment variables can pose a security risk.
This commit is contained in:
parent
bd583ca645
commit
90763e04ba
42
gc.c
42
gc.c
@ -1862,31 +1862,44 @@ static void *rb_gc_impl_objspace_alloc(void);
|
|||||||
#if USE_SHARED_GC
|
#if USE_SHARED_GC
|
||||||
# include "dln.h"
|
# include "dln.h"
|
||||||
|
|
||||||
# define RUBY_GC_LIBRARY_PATH "RUBY_GC_LIBRARY_PATH"
|
typedef struct gc_function_map {
|
||||||
|
void *(*objspace_alloc)(void);
|
||||||
|
} rb_gc_function_map_t;
|
||||||
|
|
||||||
static void
|
static rb_gc_function_map_t rb_gc_functions;
|
||||||
ruby_external_gc_init(void)
|
|
||||||
|
# define RUBY_GC_LIBRARY_ARG "--gc-library="
|
||||||
|
|
||||||
|
void
|
||||||
|
ruby_load_external_gc_from_argv(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *gc_so_path = getenv(RUBY_GC_LIBRARY_PATH);
|
char *gc_so_path = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (strncmp(argv[i], RUBY_GC_LIBRARY_ARG, sizeof(RUBY_GC_LIBRARY_ARG) - 1) == 0) {
|
||||||
|
gc_so_path = argv[i] + sizeof(RUBY_GC_LIBRARY_ARG) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *handle = NULL;
|
void *handle = NULL;
|
||||||
if (gc_so_path && dln_supported_p()) {
|
if (gc_so_path && dln_supported_p()) {
|
||||||
char error[1024];
|
char error[1024];
|
||||||
handle = dln_open(gc_so_path, error, sizeof(error));
|
handle = dln_open(gc_so_path, error, sizeof(error));
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
fprintf(stderr, "%s", error);
|
fprintf(stderr, "%s", error);
|
||||||
rb_bug("ruby_external_gc_init: Shared library %s cannot be opened", gc_so_path);
|
rb_bug("ruby_load_external_gc_from_argv: Shared library %s cannot be opened", gc_so_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# define load_external_gc_func(name) do { \
|
# define load_external_gc_func(name) do { \
|
||||||
if (handle) { \
|
if (handle) { \
|
||||||
rb_gc_functions->name = dln_symbol(handle, "rb_gc_impl_" #name); \
|
rb_gc_functions.name = dln_symbol(handle, "rb_gc_impl_" #name); \
|
||||||
if (!rb_gc_functions->name) { \
|
if (!rb_gc_functions.name) { \
|
||||||
rb_bug("ruby_external_gc_init: " #name " func not exported by library %s", gc_so_path); \
|
rb_bug("ruby_load_external_gc_from_argv: " #name " func not exported by library %s", gc_so_path); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
rb_gc_functions->name = rb_gc_impl_##name; \
|
rb_gc_functions.name = rb_gc_impl_##name; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -1895,15 +1908,12 @@ ruby_external_gc_init(void)
|
|||||||
# undef load_external_gc_func
|
# undef load_external_gc_func
|
||||||
}
|
}
|
||||||
|
|
||||||
# define rb_gc_impl_objspace_alloc rb_gc_functions->objspace_alloc
|
# define rb_gc_impl_objspace_alloc rb_gc_functions.objspace_alloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rb_objspace_t *
|
rb_objspace_t *
|
||||||
rb_objspace_alloc(void)
|
rb_objspace_alloc(void)
|
||||||
{
|
{
|
||||||
#if USE_SHARED_GC
|
|
||||||
ruby_external_gc_init();
|
|
||||||
#endif
|
|
||||||
return (rb_objspace_t *)rb_gc_impl_objspace_alloc();
|
return (rb_objspace_t *)rb_gc_impl_objspace_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13638,12 +13648,6 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
|
|||||||
void
|
void
|
||||||
Init_GC(void)
|
Init_GC(void)
|
||||||
{
|
{
|
||||||
#if USE_SHARED_GC
|
|
||||||
if (getenv(RUBY_GC_LIBRARY_PATH) != NULL && !dln_supported_p()) {
|
|
||||||
rb_warn(RUBY_GC_LIBRARY_PATH " is ignored because this executable file can't load extension libraries");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef rb_intern
|
#undef rb_intern
|
||||||
malloc_offset = gc_compute_malloc_offset();
|
malloc_offset = gc_compute_malloc_offset();
|
||||||
|
|
||||||
|
5
main.c
5
main.c
@ -32,10 +32,15 @@
|
|||||||
# undef RUBY_DEBUG_ENV
|
# undef RUBY_DEBUG_ENV
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void ruby_load_external_gc_from_argv(int argc, char **argv);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rb_main(int argc, char **argv)
|
rb_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
RUBY_INIT_STACK;
|
RUBY_INIT_STACK;
|
||||||
|
#if USE_SHARED_GC
|
||||||
|
ruby_load_external_gc_from_argv(argc, argv);
|
||||||
|
#endif
|
||||||
ruby_init();
|
ruby_init();
|
||||||
return ruby_run_node(ruby_options(argc, argv));
|
return ruby_run_node(ruby_options(argc, argv));
|
||||||
}
|
}
|
||||||
|
10
ruby.c
10
ruby.c
@ -1435,6 +1435,16 @@ proc_long_options(ruby_cmdline_options_t *opt, const char *s, long argc, char **
|
|||||||
else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
|
else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
|
||||||
set_source_encoding_once(opt, s, 0);
|
set_source_encoding_once(opt, s, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(USE_SHARED_GC) && USE_SHARED_GC
|
||||||
|
else if (is_option_with_arg("gc-library", Qfalse, Qfalse)) {
|
||||||
|
// no-op
|
||||||
|
// Handled by ruby_load_external_gc_from_argv
|
||||||
|
|
||||||
|
if (!dln_supported_p()) {
|
||||||
|
rb_warn("--gc-library is ignored because this executable file can't load extension libraries");
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (strcmp("version", s) == 0) {
|
else if (strcmp("version", s) == 0) {
|
||||||
if (envopt) goto noenvopt_long;
|
if (envopt) goto noenvopt_long;
|
||||||
|
11
vm_core.h
11
vm_core.h
@ -106,14 +106,6 @@ extern int ruby_assert_critical_section_entered;
|
|||||||
|
|
||||||
#include "ruby/thread_native.h"
|
#include "ruby/thread_native.h"
|
||||||
|
|
||||||
#if USE_SHARED_GC
|
|
||||||
typedef struct gc_function_map {
|
|
||||||
void *(*objspace_alloc)(void);
|
|
||||||
} rb_gc_function_map_t;
|
|
||||||
|
|
||||||
#define rb_gc_functions (&GET_VM()->gc_functions_map)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* implementation selector of get_insn_info algorithm
|
* implementation selector of get_insn_info algorithm
|
||||||
* 0: linear search
|
* 0: linear search
|
||||||
@ -761,9 +753,6 @@ typedef struct rb_vm_struct {
|
|||||||
int coverage_mode;
|
int coverage_mode;
|
||||||
|
|
||||||
struct rb_objspace *objspace;
|
struct rb_objspace *objspace;
|
||||||
#if USE_SHARED_GC
|
|
||||||
rb_gc_function_map_t gc_functions_map;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rb_at_exit_list *at_exit;
|
rb_at_exit_list *at_exit;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user