From: john@... Date: 2019-07-30T16:04:22+00:00 Subject: [ruby-core:94057] [Ruby master Bug#14834] rb_profile_frames SEGV when PC adjusted on IFUNC Issue #14834 has been updated by jhawthorn (John Hawthorn). Status changed from Closed to Open I believe since r64737 this is an issue again. On Ruby 2.6.3 I get an almost identical stacktrace as before ``` Thread 1 "ruby" received signal SIGSEGV, Segmentation fault. 0x00005555555cac9e in succ_index_lookup (x=, sd=0x10c483485c750000) at iseq.c:3357 3357 return imm_block_rank_get(sd->imm_part[i], j); (gdb) bt #0 0x00005555555cac9e in succ_index_lookup (x=, sd=0x10c483485c750000) at iseq.c:3357 #1 get_insn_info_succinct_bitvector (iseq=, pos=) at iseq.c:1593 #2 get_insn_info (pos=, iseq=) at iseq.c:1601 #3 rb_iseq_line_no (iseq=, pos=) at iseq.c:1669 #4 0x000055555571cf83 in calc_lineno (pc=, iseq=) at vm_backtrace.c:47 #5 rb_profile_frames (start=start@entry=0, limit=limit@entry=2048, buff=buff@entry=0x7fffffff86f0, lines=lines@entry=0x7fffffff66f0) at vm_backtrace.c:1308 #6 0x00007ffff5532e83 in newobj (tpval=, ptr=0x555555feb610) at ../../../../ext/allocation_sampler/allocation_sampler.c:227 #7 0x000055555571dc49 in tp_call_trace (tpval=, trace_arg=) at vm_trace.c:1194 #8 0x000055555571e206 in exec_hooks_body (ec=ec@entry=0x5555558c13b8, trace_arg=0x7fffffffc7d0, trace_arg@entry=0x7fffffffc790, list=) at vm_trace.c:304 #9 0x0000555555720ebc in exec_hooks_unprotected (trace_arg=0x7fffffffc790, list=0x5555558c0e08, ec=) at vm_trace.c:333 #10 rb_exec_event_hooks (trace_arg=trace_arg@entry=0x7fffffffc7d0, hooks=, pop_p=pop_p@entry=0) at vm_trace.c:378 #11 0x000055555558f72f in rb_exec_event_hook_orig (pop_p=0, data=, klass=0, called_id=0, id=0, self=, flag=, hooks=, ec=0x5555558c13b8) at vm_core.h:1870 #12 gc_event_hook_body (ec=0x5555558c13b8, event=, data=, objspace=) at gc.c:1805 #13 0x0000555555599cf8 in newobj_slowpath (wb_protected=1, objspace=0x5555558c1140, v3=0, v2=, v1=0, flags=8199, klass=) at vm_core.h:1735 #14 newobj_slowpath_wb_protected (klass=, flags=8199, v1=0, v2=, v3=0, objspace=0x5555558c1140) at gc.c:1929 ``` ---------------------------------------- Bug #14834: rb_profile_frames SEGV when PC adjusted on IFUNC https://bugs.ruby-lang.org/issues/14834#change-80285 * Author: kivikakk (Ashe Connor) * Status: Open * Priority: Normal * Assignee: shyouhei (Shyouhei Urabe) * Target version: * ruby -v: ruby 2.6.0dev (2018-06-08 trunk 63606) [x86_64-linux] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- Since r62052, we increment `ec->cfp->pc` by one pointer width (e.g. 8 bytes) in `gc_event_hook_body` around the `EXEC_EVENT_HOOK` call. This becomes a problem when the hook is on an IFUNC: in this case, `pc == 0x0`, meaning we increment it to a non-zero value during that call. `rb_profile_frames` uses the following check to determine if frame info should be recorded: ~~~ c if (cfp->iseq && cfp->pc) { ~~~ The example here is [`stackprof`](https://github.com/tmm1/stackprof/blob/58d65ffa801ed27f013d573148783694526c7426/ext/stackprof/stackprof.c#L486), which calls `rb_profile_frames` in a gc event hook. This will segfault currently, as the above check will pass. `calc_lineno` then attempts to calculate the line number: ~~~ c size_t pos = (size_t)(pc - iseq->body->iseq_encoded); ~~~ This fails for a variety of reasons: `iseq_encoded` isn't valid because `iseq` isn't an `rb_iseq_t` underneath, producing an essentially random value, and `pc` is 0x8, so we underflow and eventually cause an overrun in `succ_index_lookup` with a huge `pos` argument. We instead only adjust PC if it appears to be a valid pointer in the first place. ---Files-------------------------------- pc-treatment.diff (777 Bytes) -- https://bugs.ruby-lang.org/ Unsubscribe: