ruby-changes:51624
From: nobu <ko1@a...>
Date: Tue, 3 Jul 2018 14:12:57 +0900 (JST)
Subject: [ruby-changes:51624] nobu:r63835 (trunk): cont.c: handle errors for getcontext()
nobu 2018-07-03 14:12:52 +0900 (Tue, 03 Jul 2018) New Revision: 63835 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63835 Log: cont.c: handle errors for getcontext() It may raise an error in a certain security configuration. It is very likely to trigger a segmentation fault if `getcontext()` failed silently and we just let it keep going. Related to https://bugs.ruby-lang.org/issues/14883 [Fix GH-1903] Based on the patch from Lion Yang <lion@a...> From: Lion Yang <lion@a...> Modified files: trunk/cont.c Index: cont.c =================================================================== --- cont.c (revision 63834) +++ cont.c (revision 63835) @@ -142,14 +142,21 @@ enum fiber_status { https://github.com/ruby/ruby/blob/trunk/cont.c#L142 #define FIBER_RUNNABLE_P(fib) (FIBER_CREATED_P(fib) || FIBER_SUSPENDED_P(fib)) #if FIBER_USE_NATIVE && !defined(_WIN32) -static inline void +static inline int fiber_context_create(ucontext_t *context, void (*func)(), void *arg, void *ptr, size_t size) { - getcontext(context); + if (getcontext(context) < 0) return -1; + /* + * getcontext() may fail by some reasons: + * 1. SELinux policy banned one of "rt_sigprocmask", + * "sigprocmask" or "swapcontext"; + * 2. libseccomp (aka. syscall filter) banned one of them. + */ context->uc_link = NULL; context->uc_stack.ss_sp = ptr; context->uc_stack.ss_size = size; makecontext(context, func, 0); + return 0; } #endif @@ -856,7 +863,9 @@ fiber_initialize_machine_stack_context(r https://github.com/ruby/ruby/blob/trunk/cont.c#L863 ptr = fiber_machine_stack_alloc(size); fib->ss_sp = ptr; fib->ss_size = size; - fiber_context_create(&fib->context, fiber_entry, NULL, fib->ss_sp, fib->ss_size); + if (fiber_context_create(&fib->context, fiber_entry, NULL, fib->ss_sp, fib->ss_size)) { + rb_raise(rb_eFiberError, "can't get context for creating fiber: %s", ERRNOMSG); + } sec->machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size)); sec->machine.stack_maxsize = size - RB_PAGE_SIZE; #endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/