@@ -327,8 +327,9 @@ unsafe fn rebind_symbols_for_image(
327327 // file. At runtime, __LINKEDIT is mapped at (vmaddr + slide). By subtracting
328328 // the file offset of __LINKEDIT itself, we get a base we can add any file
329329 // offset to in order to get a valid runtime pointer.
330- linkedit_base =
331- ( slide as usize ) . wrapping_add ( seg. vmaddr as usize ) - seg. fileoff as usize ;
330+ linkedit_base = ( slide as usize )
331+ . wrapping_add ( seg. vmaddr as usize )
332+ . wrapping_sub ( seg. fileoff as usize ) ;
332333 linkedit_found = true ;
333334 }
334335 }
@@ -390,7 +391,10 @@ unsafe fn rebind_symbols_for_image(
390391 slide,
391392 symtab,
392393 strtab,
394+ ( * symtab_cmd) . nsyms as usize ,
395+ ( * symtab_cmd) . strsize as usize ,
393396 indirect_symtab,
397+ ( * dysymtab_cmd) . nindirectsyms as usize ,
394398 overwrites,
395399 segname == "__DATA_CONST" ,
396400 ) {
@@ -422,7 +426,10 @@ unsafe fn rebind_symbols_in_section(
422426 slide : isize ,
423427 symtab : * const Nlist64 ,
424428 strtab : * const c_char ,
429+ nsyms : usize ,
430+ strsize : usize ,
425431 indirect_symtab : * const u32 ,
432+ nindirectsyms : usize ,
426433 overwrites : & mut [ GotSymbolOverwrite ] ,
427434 is_data_const : bool ,
428435) -> bool {
@@ -432,7 +439,14 @@ unsafe fn rebind_symbols_in_section(
432439
433440 // The indirect symbol table entries for this section start at index `section.reserved1`.
434441 // Entry `indirect_sym_indices[i]` tells us which symbol table entry corresponds to slot `i`.
435- let indirect_sym_indices = indirect_symtab. add ( section. reserved1 as usize ) ;
442+ let indirect_sym_start = section. reserved1 as usize ;
443+ let Some ( indirect_sym_end) = indirect_sym_start. checked_add ( num_indirect_syms) else {
444+ return false ;
445+ } ;
446+ if indirect_sym_end > nindirectsyms {
447+ return false ;
448+ }
449+ let indirect_sym_indices = indirect_symtab. add ( indirect_sym_start) ;
436450
437451 // The actual pointer slots in memory (adjusted by ASLR slide).
438452 let symbol_ptrs = ( ( slide as usize ) . wrapping_add ( section. addr as usize ) ) as * mut * mut c_void ;
@@ -445,19 +459,27 @@ unsafe fn rebind_symbols_in_section(
445459 let symtab_index = * indirect_sym_indices. add ( i) ;
446460
447461 // Skip special entries that don't refer to real external symbols
448- if symtab_index == INDIRECT_SYMBOL_LOCAL
449- || symtab_index == INDIRECT_SYMBOL_ABS
450- || symtab_index == ( INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS )
451- {
462+ if ( symtab_index & ( INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS ) ) != 0 {
463+ continue ;
464+ }
465+
466+ if symtab_index as usize >= nsyms {
452467 continue ;
453468 }
454469
455470 // Step 2: Look up the symbol in the symbol table to get its name
456471 let nlist = & * symtab. add ( symtab_index as usize ) ;
457- let name_ptr = strtab. add ( nlist. n_strx as usize ) ;
458- let name = match CStr :: from_ptr ( name_ptr) . to_str ( ) {
459- Ok ( n) => n,
460- Err ( _) => continue ,
472+ let name_offset = nlist. n_strx as usize ;
473+ if name_offset >= strsize {
474+ continue ;
475+ }
476+ let name_bytes =
477+ std:: slice:: from_raw_parts ( strtab. add ( name_offset) as * const u8 , strsize - name_offset) ;
478+ let Ok ( name) = CStr :: from_bytes_until_nul ( name_bytes) else {
479+ continue ;
480+ } ;
481+ let Ok ( name) = name. to_str ( ) else {
482+ continue ;
461483 } ;
462484
463485 // Step 3: Strip the Mach-O leading underscore (e.g. "_recv" → "recv") so we can
0 commit comments