aboutsummaryrefslogtreecommitdiffstats
path: root/cont.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-03 05:12:52 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-03 05:12:52 +0000
commitb4e5757122e1d9eb89aa3b7a7140d093b5831010 (patch)
tree9630e0bf769462731b288ccd064ef10812954233 /cont.c
parent29d6f77fcd00384e86ce94dc643a16fa18f13b73 (diff)
downloadruby-b4e5757122e1d9eb89aa3b7a7140d093b5831010.tar.gz
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@aosc.io> From: Lion Yang <lion@aosc.io> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63835 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'cont.c')
-rw-r--r--cont.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/cont.c b/cont.c
index 634733807a..d1356efaa8 100644
--- a/cont.c
+++ b/cont.c
@@ -142,14 +142,21 @@ enum fiber_status {
#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(rb_fiber_t *fib, size_t size)
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