@@ -301,19 +301,29 @@ static void ruby_runtime_stack_callback(
301301 // Handle Ruby frames
302302 const rb_iseq_t * iseq = cfp -> iseq ;
303303
304- if (!iseq || !iseq -> body ) {
304+ // Use comprehensive iseq validation
305+ if (!is_valid_iseq (iseq )) {
305306 continue ;
306307 }
307308
308309 VALUE name = rb_iseq_base_label (iseq );
309- const char * function_name = (name != Qnil ) ? safe_string_ptr (name ) : "<unknown>" ;
310+ const char * function_name = "<unknown>" ;
311+ if (name != Qnil && is_reasonable_string_size (name )) {
312+ function_name = safe_string_ptr (name );
313+ }
310314
311315 VALUE filename = rb_iseq_path (iseq );
312- const char * file_name = (filename != Qnil ) ? safe_string_ptr (filename ) : "<unknown>" ;
316+ const char * file_name = "<unknown>" ;
317+ if (filename != Qnil && is_reasonable_string_size (filename )) {
318+ file_name = safe_string_ptr (filename );
319+ }
313320
314321 int line_no = 0 ;
315322 if (iseq && cfp -> pc ) {
316- if (iseq -> body && iseq -> body -> iseq_encoded && iseq -> body -> iseq_size > 0 ) {
323+ // Additional safety checks for line number calculation
324+ if (iseq -> body &&
325+ is_pointer_readable (iseq -> body -> iseq_encoded , iseq -> body -> iseq_size * sizeof (* iseq -> body -> iseq_encoded )) &&
326+ iseq -> body -> iseq_size > 0 ) {
317327 ptrdiff_t pc_offset = cfp -> pc - iseq -> body -> iseq_encoded ;
318328 if (pc_offset >= 0 && pc_offset < iseq -> body -> iseq_size ) {
319329 // Use the Ruby VM line calculation like ddtrace_rb_profile_frames
@@ -339,12 +349,18 @@ static void ruby_runtime_stack_callback(
339349 const char * function_name = "<C method>" ;
340350 const char * file_name = "<C extension>" ;
341351
342- // Try to get method entry information
352+ // Try to get method entry information with comprehensive safety checks
343353 const rb_callable_method_entry_t * me = rb_vm_frame_method_entry (cfp );
344- if (me && me -> def && me -> def -> original_id ) {
345- const char * method_name = rb_id2name (me -> def -> original_id );
346- if (method_name && is_pointer_readable (method_name , strlen (method_name ))) {
347- function_name = method_name ;
354+ if (me && is_pointer_readable (me , sizeof (rb_callable_method_entry_t ))) {
355+ if (me -> def && is_pointer_readable (me -> def , sizeof (* me -> def )) && me -> def -> original_id ) {
356+ const char * method_name = rb_id2name (me -> def -> original_id );
357+ if (method_name && is_pointer_readable (method_name , strlen (method_name ))) {
358+ // Additional length check for method name
359+ size_t method_name_len = strlen (method_name );
360+ if (method_name_len > 0 && method_name_len < 256 ) { // Reasonable method name length
361+ function_name = method_name ;
362+ }
363+ }
348364 }
349365 }
350366
@@ -377,11 +393,8 @@ static VALUE _native_register_runtime_stack_callback(DDTRACE_UNUSED VALUE _self,
377393 switch (result ) {
378394 case DDOG_CRASHT_CALLBACK_RESULT_OK :
379395 return Qtrue ;
380- case DDOG_CRASHT_CALLBACK_RESULT_NULL_CALLBACK :
381- rb_raise (rb_eRuntimeError , "Failed to register runtime callback: null callback provided" );
382- break ;
383- case DDOG_CRASHT_CALLBACK_RESULT_UNKNOWN_ERROR :
384- rb_raise (rb_eRuntimeError , "Failed to register runtime callback: unknown error" );
396+ case DDOG_CRASHT_CALLBACK_RESULT_ERROR :
397+ rb_raise (rb_eRuntimeError , "Failed to register runtime callback" );
385398 break ;
386399 }
387400
0 commit comments