CTSRD-CHERI / cheribsd

FreeBSD adapted for CHERI-RISC-V and Arm Morello.
http://cheribsd.org
Other
170 stars 60 forks source link

ld-cheri-elf.so.1 seems to be confused by some executables #611

Open nwf opened 4 years ago

nwf commented 4 years ago

Working on snmalloc CHERIfication, I was rewarded with (well, after I also turned on rtld debugging)

Setting DT_MIPS_RLD_MAP_REL for (null): 0x4106fc60 <- 0x410705d0
RTLD:
        mapbase=v:1 s:0 p:G-rwRWL-+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
        relocbase=v:1 s:0 p:G-rwRWL-+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
        text_rodata=v:1 s:0 p:Gxr-R---+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
__cap_relocs for (null) have already been processed!
BIND_NOW PLT relocation processing for (null)
(null): done relocating 0 PLT entries.
Using imprecise bounds for captable: v:1 s:0 p:GxrwRWL-+00078100 b:000000004106b580 l:00000000000046e0 o:0000000000000010 t:-1 - size was 18144 but real size should be 18128
(null): text/rodata start = 0, text/rodata end = 0x4ada8, captable = v:1 s:0 p:GxrwRWL-+00078100 b:000000004106b580 l:00000000000046e0 o:0000000000000010 t:-1 (relative to start 0x6b590), current text/rodata cap = v:1 s:0 p:Gxr-R---+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
Using imprecise bounds for text/rodata/captable: v:1 s:0 p:Gxr-R---+00078100 b:0000000041000000 l:000000000006fe00 o:0000000000000000 t:-1 - size was 458240 but real size should be 457824
(null): tightened bounds of text/rodata cap: v:1 s:0 p:Gxr-R---+00078100 b:0000000041000000 l:000000000006fe00 o:0000000000000000 t:-1
/libexec/ld-cheri-elf.so.1 is initialized, base address = v:1 s:0 p:GxrwRWL-+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
RTLD dynamic = v:1 s:0 p:G-r-R---+00068100 b:0000000041000760 l:0000000000000190 o:0000000000000000 t:-1
RTLD pltgot  = v:1 s:0 p:GxrwRWL-+00078100 b:0000000041000000 l:0000000000071200 o:000000000006fc70 t:-1
initializing thread locks
_rtld_thread_init: done
processing main program's program header
Values from kernel:
        AT_PHDR=v:1 s:0 p:G-rwRWL-+00078100 b:0000000000100000 l:00000000080c0000 o:0000000000020040 t:-1
        AT_BASE=v:1 s:0 p:GxrwRWL-+00078100 b:0000000041000000 l:0000000000071200 o:0000000000000000 t:-1
        AT_ENTRY=v:1 s:0 p:Gxr-R---+00068100 b:0000000000100000 l:00000000080c0000 o:000000000004e760 t:-1

digest_phdr(0, entry=v:1 s:0 p:Gxr-R---+00068100 b:0000000000100000 l:00000000080c0000 o:000000000004e760 t:-1, phdr=v:1 s:0 p:G-rwRWL-+00078100 b:0000000000100000 l:00000000080c0000 o:0000000000020040 t:-1, path=./func-malloc-1)

./func-malloc-1: processing readonly PT_LOAD[1], new text/rodata start  = 0 text/rodata end = 1e758
./func-malloc-1: processing readonly PT_LOAD[2], new text/rodata start  = 0 text/rodata end = 4ed00
./func-malloc-1: Adding PT_GNU_RELRO, new text/rodata start  = 0 text/rodata end = 5f000
note osrel 1300097
note fctl0 0
note crt_no_init
Trapframe Register Dump:
$0: 0                  at: 0x80c0000          v0: 0x70000003         v1: 0x7000000200000000
a0: 0                  a1: 0x1                a2: 0                  a3: 0                 
a4: 0                  a5: 0                  a6: 0                  a7: 0x1               
t0: 0                  t1: 0                  t2: 0x20               t3: 0x7000c001        
s0: 0x4                s1: 0xffd7             s2: 0x6474e551         s3: 0x6474e552        
s4: 0xfffffffffffff000 s5: 0x1                s6: 0                  s7: 0                 
t8: 0x7000c002         t9: 0x2034             k0: 0                  k1: 0                 
gp: 0                  sp: 0x21               s8: 0                  ra: 0                 
status: 0x408084b3 mullo: 0; mulhi: 0; badvaddr: 0x4106b640
cause: 0x48; pc: 0x41027504
BadInstr: 0x48010848 csetbounds c1,c1,at
CHERI cause: ExcCode: 0x01 RegNum: $c01 (length violation)
$ddc: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c01: v:1 s:0 p:0007817d b:0000000000100000 l:00000000080c0000 o:20000 t:-1
$c02: v:1 s:0 p:0007817d b:0000007ffffcef20 l:0000000000000200 o:f t:-1
$c03: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:1 t:-1
$c04: v:1 s:0 p:00068115 b:0000000041003aa5 l:000000000000000c o:0 t:-1
$c05: v:1 s:0 p:0007817d b:0000000000100000 l:00000000080c0000 o:203b0 t:-1
$c06: v:1 s:0 p:0007817d b:0000007ffffcec00 l:0000000000000010 o:0 t:-1
$c07: v:1 s:1 p:00068117 b:0000000041000000 l:0000000000071200 o:4aca0 t:fffffffffffffffe
$c08: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c09: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c10: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c11: v:1 s:0 p:0007817d b:0000007ffbff0000 l:0000000003fe0000 o:3fdf2a0 t:-1
$c12: v:1 s:1 p:00068117 b:0000000041000000 l:0000000000071200 o:41140 t:fffffffffffffffe
$c13: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c14: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c15: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c16: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c17: v:1 s:1 p:00068117 b:0000000041000000 l:0000000000071200 o:272c4 t:fffffffffffffffe
$c18: v:1 s:0 p:0007817d b:0000007ffffefd80 l:0000000000000010 o:0 t:-1
$c19: v:1 s:0 p:00068115 b:0000000041005480 l:000000000000001c o:0 t:-1
$c20: v:1 s:0 p:0006817d b:0000000040192010 l:0000000000000570 o:0 t:-1
$c21: v:1 s:0 p:0007817d b:0000000000100000 l:00000000080c0000 o:20350 t:-1
$c22: v:1 s:0 p:0007817d b:0000000000100000 l:00000000080c0000 o:20350 t:-1
$c23: v:1 s:0 p:00068117 b:0000000041000000 l:0000000000071200 o:6b590 t:-1
$c24: v:1 s:0 p:0007817d b:0000007ffbff0000 l:0000000003fe0000 o:3fdf2a0 t:-1
$c25: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c26: v:1 s:0 p:00068117 b:0000000041000000 l:0000000000071200 o:6b590 t:-1
$c27: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c28: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c29: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c30: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$c31: v:0 s:0 p:00000000 b:0000000000000000 l:ffffffffffffffff o:0 t:-1
$pcc: v:1 s:0 p:00068117 b:0000000041000000 l:0000000000071200 o:27504 t:-1
Signal 34
Jul 17 12:53:37 qemu-cheri128-daemon kernel: USER_CHERI_EXCEPTION: pid 659 tid 100052 (func-malloc-1), uid 0: CP2 fault (type 0x32)
Jul 17 12:53:37 qemu-cheri128-daemon kernel: Process arguments: ./func-malloc-1 

That exception comes from https://github.com/CTSRD-CHERI/cheribsd/blob/1507c329a5e8111cea1facedcbfd82283ddc25f2/libexec/rtld-elf/rtld.c#L1875

obj->relocbase is derived from the AT_PHDR aux vector entry at https://github.com/CTSRD-CHERI/cheribsd/blob/1507c329a5e8111cea1facedcbfd82283ddc25f2/libexec/rtld-elf/rtld.c#L1782 and obj->mapsize is computed at https://github.com/CTSRD-CHERI/cheribsd/blob/1507c329a5e8111cea1facedcbfd82283ddc25f2/libexec/rtld-elf/rtld.c#L1817

gdb thinks that, at the time of the fault, obj->mapsize worked out to being 0x80c0000 (i.e., the length of the AT_PHDR cap and also the value in $at) and obj->relocbase was (caddr_t) 0x120000 [rwRW,0x100000-0x81c0000] "\177ELF\002\002\001\t\003" (which matches what's in $c01).

Is this program being mis-loaded by the kernel? Is this a case where we've had to round the base down to achieve alignment and that's throwing off the delicate dance?

jrtc27 commented 4 years ago

Rounding down the base shouldn’t be noticeable to RTLD, it just does page-based rounding/truncating here with no notion of representability. What’s obj->vaddrbase? And what does llvm-readelf -l func-malloc-1 say?

nwf commented 4 years ago

obj->vaddrbase is 0 and llvm-readelf -l sayeth



Elf file type is EXEC (Executable file)
Entry point 0x3e3d0
There are 14 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000010040 0x0000000000010040 0x000310 0x000310 R   0x8
  INTERP         0x000350 0x0000000000010350 0x0000000000010350 0x000015 0x000015 R   0x1
      [Requesting program interpreter: /libexec/ld-elf.so.1]
  LOAD           0x000000 0x0000000000010000 0x0000000000010000 0x01e3c4 0x01e3c4 R   0x10000
  LOAD           0x01e3d0 0x000000000003e3d0 0x000000000003e3d0 0x01e47c 0x01e47c R E 0x10000
  LOAD           0x03c850 0x000000000006c850 0x000000000006c850 0x000030 0x000030 RW  0x10000
  LOAD           0x03c880 0x000000000007c880 0x000000000007c880 0x001060 0x082780 RW  0x10000
  TLS            0x03c850 0x000000000006c850 0x000000000006c850 0x000008 0x000019 R   0x8
  DYNAMIC        0x003980 0x0000000000013980 0x0000000000013980 0x0001b0 0x0001b0 R   0x8
  GNU_RELRO      0x03c850 0x000000000006c850 0x000000000006c850 0x000030 0x0007b0 R   0x1
  GNU_EH_FRAME   0x019fa0 0x0000000000029fa0 0x0000000000029fa0 0x000e8c 0x000e8c R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x0
  NOTE           0x000368 0x0000000000010368 0x0000000000010368 0x000048 0x000048 R   0x4
  OPTIONS        0x0003c8 0x00000000000103c8 0x00000000000103c8 0x000028 0x000028 R   0x8
  ABIFLAGS       0x0003b0 0x00000000000103b0 0x00000000000103b0 0x000018 0x000018 R   0x8

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.tag .MIPS.abiflags .MIPS.options .dynsym .gnu.version .gnu.version_r .hash .dynamic .dynstr .rodata .eh_frame_hdr .eh_frame 
   03     .text .init .fini 
   04     .tdata .ctors .dtors .jcr 
   05     .data .rld_map .got .bss 
   06     .tdata .tbss 
   07     .dynamic 
   08     .tdata .ctors .dtors .jcr 
   09     .eh_frame_hdr 
   10     
   11     .note.tag 
   12     .MIPS.options 
   13     .MIPS.abiflags 
   None   .comment .pdr .debug_loc .debug_abbrev .debug_info .debug_str .debug_line .debug_frame .debug_aranges .debug_ranges .gdb_index .symtab .shstrtab .strtab
```</s>
jrtc27 commented 4 years ago

That doesn’t seem consistent with your original output.

jrtc27 commented 4 years ago

(Though I have noticed that we don’t do the right thing when there’s only one PT_LOAD, as it’s both the first and last segment...)

nwf commented 4 years ago

D'oh. Too many build directories. Sorry, try this llvm-readelf -l intead:


Elf file type is DYN (Shared object file)
Entry point 0x2e760
There are 14 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x000310 0x000310 R   0x8
  INTERP         0x000350 0x0000000000000350 0x0000000000000350 0x000015 0x000015 R   0x1
      [Requesting program interpreter: /libexec/ld-elf.so.1]
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x01e758 0x01e758 R   0x10000
  LOAD           0x01e760 0x000000000002e760 0x000000000002e760 0x0205a0 0x0205a0 R E 0x10000
  LOAD           0x03ed00 0x000000000005ed00 0x000000000005ed00 0x000020 0x000020 RW  0x10000
  LOAD           0x06ed20 0x000000000006ed20 0x000000000006ed20 0x0022c0 0x80512e0 RW  0x40000
  TLS            0x03ed00 0x000000000005ed00 0x000000000005ed00 0x000010 0x000021 R   0x10
  DYNAMIC        0x003738 0x0000000000003738 0x0000000000003738 0x000250 0x000250 R   0x8
  GNU_RELRO      0x03ed00 0x000000000005ed00 0x000000000005ed00 0x000020 0x000300 R   0x1
  GNU_EH_FRAME   0x015940 0x0000000000015940 0x0000000000015940 0x000df4 0x000df4 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x0
  NOTE           0x000368 0x0000000000000368 0x0000000000000368 0x000048 0x000048 R   0x4
  OPTIONS        0x0003c8 0x00000000000003c8 0x00000000000003c8 0x000028 0x000028 R   0x8
  ABIFLAGS       0x0003b0 0x00000000000003b0 0x00000000000003b0 0x000018 0x000018 R   0x8

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.tag .MIPS.abiflags .MIPS.options .dynsym .gnu.version .gnu.version_r .hash .dynamic .dynstr .rel.dyn .rel.plt .rodata .eh_frame_hdr .eh_frame __cap_relocs 
   03     .text 
   04     .tdata .ctors .dtors 
   05     .data .captable .rld_map .got .bss 
   06     .tdata .tbss 
   07     .dynamic 
   08     .tdata .ctors .dtors 
   09     .eh_frame_hdr 
   10     
   11     .note.tag 
   12     .MIPS.options 
   13     .MIPS.abiflags 
   None   .comment .pdr .debug_loc .debug_abbrev .debug_info .debug_str .debug_line .debug_ranges .gdb_index .symtab .shstrtab .strtab