github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/gosec/sim.go (about) 1 package gosec 2 3 /* This file implements a simulated environnement to load and execute enclave 4 * binaries without sgx. 5 */ 6 7 import ( 8 "debug/elf" 9 "fmt" 10 "log" 11 "runtime" 12 "sort" 13 "syscall" 14 "unsafe" 15 ) 16 17 func simLoadProgram(path string) { 18 fmt.Println("[DEBUG] loading the program in simulation.") 19 file, err := elf.Open(path) 20 check(err) 21 _, enclWrap = sgxCreateSecs(file) 22 enclWrap.isSim = true 23 srcWrap = transposeOutWrapper(enclWrap) 24 defer func() { check(file.Close()) }() 25 26 // Check that the sections are sorted now. 27 sort.Sort(SortedElfSections(file.Sections)) 28 29 var aggreg []*elf.Section 30 for _, sec := range file.Sections { 31 if sec.Flags&elf.SHF_ALLOC != elf.SHF_ALLOC { 32 continue 33 } 34 if len(aggreg) == 0 || aggreg[len(aggreg)-1].Flags == sec.Flags { 35 aggreg = append(aggreg, sec) 36 continue 37 } 38 mapSections(aggreg) 39 aggreg = nil 40 aggreg = append(aggreg, sec) 41 } 42 mapSections(aggreg) 43 44 //For debugging. 45 enclWrap.DumpDebugInfo() 46 // Map the enclave preallocated heap. 47 simPreallocate(enclWrap) 48 49 for _, tcs := range enclWrap.tcss { 50 prot := _PROT_READ | _PROT_WRITE 51 manon := _MAP_PRIVATE | _MAP_ANON | _MAP_FIXED 52 // mmap the stack 53 _, err = syscall.RMmap(tcs.Stack, int(tcs.Ssiz), prot, manon, -1, 0) 54 check(err) 55 } 56 57 // register the heap, setup the enclave stack 58 etcs := enclWrap.defaultTcs() 59 etcs.Used = true 60 srcWrap.defaultTcs().Used = true 61 runtime.Cooprt.Tcss = enclWrap.tcss 62 _ = runtime.SetupEnclSysStack(etcs.Stack+etcs.Ssiz, enclWrap.mhstart) 63 64 // Create the thread for enclave, setups the stacks. 65 fn := unsafe.Pointer(uintptr(file.Entry)) 66 enclWrap.entry = uintptr(fn) 67 dtcs, stcs := enclWrap.defaultTcs(), srcWrap.defaultTcs() 68 dtcs.Used, stcs.Used = true, true 69 sgxEEnter(uint64(0), dtcs, stcs, nil) 70 } 71 72 func simPreallocate(wrap *sgx_wrapper) { 73 prot := _PROT_READ | _PROT_WRITE 74 flags := _MAP_ANON | _MAP_FIXED | _MAP_PRIVATE 75 76 // The span 77 _, err := syscall.RMmap(wrap.mhstart, int(wrap.mhsize), prot, 78 flags, -1, 0) 79 check(err) 80 81 // The memory buffer for mmap calls. 82 _, err = syscall.RMmap(wrap.membuf, int(MEMBUF_SIZE), prot, 83 flags, -1, 0) 84 check(err) 85 } 86 87 // mapSections mmaps the elf sections. 88 // If wrap nil, simple mmap. Otherwise, mmap to another address space specified 89 // by wrap.mmask for SGX. 90 func mapSections(secs []*elf.Section) { 91 if len(secs) == 0 { 92 return 93 } 94 95 start := uintptr(secs[0].Addr) 96 end := uintptr(secs[len(secs)-1].Addr + secs[len(secs)-1].Size) 97 size := int(end - start) 98 if start >= end { 99 log.Fatalf("Error, sections are not ordered: %#x - %#x", start, end) 100 } 101 102 prot := _PROT_READ | _PROT_WRITE 103 b, err := syscall.RMmap(start, size, prot, _MAP_PRIVATE|_MAP_ANON, -1, 0) 104 check(err) 105 106 for _, sec := range secs { 107 if sec.Type == elf.SHT_NOBITS { 108 continue 109 } 110 data, err := sec.Data() 111 check(err) 112 offset := int(sec.Addr - uint64(start)) 113 for i := range data { 114 b[offset+i] = data[i] 115 } 116 } 117 prot = _PROT_READ 118 if (secs[0].Flags & elf.SHF_WRITE) == elf.SHF_WRITE { 119 prot |= _PROT_WRITE 120 } 121 122 if (secs[0].Flags & elf.SHF_EXECINSTR) == elf.SHF_EXECINSTR { 123 prot |= _PROT_EXEC 124 } 125 126 err = syscall.Mprotect(b, prot) 127 check(err) 128 }