On Tue, Nov 17, 2020 at 06:26:50PM +0100, Borislav Petkov wrote: > On Fri, Nov 13, 2020 at 12:01:31AM +0200, Jarkko Sakkinen wrote: > > +bool encl_load(const char *path, struct encl *encl) > > +{ > > + Elf64_Phdr *phdr_tbl; > > + off_t src_offset; > > + Elf64_Ehdr *ehdr; > > + int i, j; > > + int ret; > > + > > + memset(encl, 0, sizeof(*encl)); > > + > > + ret = open("/dev/sgx_enclave", O_RDWR); > > + if (ret < 0) { > > + fprintf(stderr, "Unable to open /dev/sgx_enclave\n"); > > + goto err; > > + } > > + > > + encl->fd = ret; > > + > > + if (!encl_map_bin(path, encl)) > > + goto err; > > + > > + ehdr = encl->bin; > > + phdr_tbl = encl->bin + ehdr->e_phoff; > > + > > + for (i = 0; i < ehdr->e_phnum; i++) { > > + Elf64_Phdr *phdr = &phdr_tbl[i]; > > + > > + if (phdr->p_type == PT_LOAD) > > + encl->nr_segments++; > > + } > > + > > + encl->segment_tbl = calloc(encl->nr_segments, > > + sizeof(struct encl_segment)); > > + if (!encl->segment_tbl) > > + goto err; > > + > > + for (i = 0, j = 0; i < ehdr->e_phnum; i++) { > > + Elf64_Phdr *phdr = &phdr_tbl[i]; > > + unsigned int flags = phdr->p_flags; > > + struct encl_segment *seg; > > + > > + if (phdr->p_type != PT_LOAD) > > + continue; > > + > > + seg = &encl->segment_tbl[j]; > > + > > + if (!!(flags & ~(PF_R | PF_W | PF_X))) { > > + fprintf(stderr, > > + "%d has invalid segment flags 0x%02x.\n", i, > > + phdr->p_flags); > > + goto err; > > + } > > + > > + if (j == 0 && flags != (PF_R | PF_W)) { > > + fprintf(stderr, > > + "TCS has invalid segment flags 0x%02x.\n", > > + phdr->p_flags); > > + goto err; > > + } > > + > > + if (j == 0) { > > + src_offset = (phdr->p_offset & PAGE_MASK) - src_offset; > > + > > + seg->prot = PROT_READ | PROT_WRITE; > > + seg->flags = SGX_PAGE_TYPE_TCS << 8; > > + } else { > > + seg->prot = (phdr->p_flags & PF_R) ? PROT_READ : 0; > > + seg->prot |= (phdr->p_flags & PF_W) ? PROT_WRITE : 0; > > + seg->prot |= (phdr->p_flags & PF_X) ? PROT_EXEC : 0; > > + seg->flags = (SGX_PAGE_TYPE_REG << 8) | seg->prot; > > + } > > + > > + seg->offset = (phdr->p_offset & PAGE_MASK) - src_offset; > > + seg->size = (phdr->p_filesz + PAGE_SIZE - 1) & PAGE_MASK; > > + > > + printf("0x%016lx 0x%016lx 0x%02x\n", seg->offset, seg->size, > > + seg->prot); > > + > > + j++; > > + } > > + > > + assert(j == encl->nr_segments); > > + > > + encl->src = encl->bin + src_offset; > > + encl->src_size = encl->segment_tbl[j - 1].offset + > > + encl->segment_tbl[j - 1].size; > > + > > + for (encl->encl_size = 4096; encl->encl_size < encl->src_size; ) > > + encl->encl_size <<= 1; > > Something's fishy. That selftest fails with > > mmap: Cannot allocate memory > > I sprinkled some printfs at this size computation above and here's what > it says: > > 0x00007fdd3b4ca190 0x0000000000002000 0x03 > 0x00007fdd3b4cc190 0x0000000000001000 0x05 > 0x00007fdd3b4cd190 0x0000000000003000 0x03 > encl_load: encl->nr_segments: 3 > encl_load: seg2 offset: 0x7fdd3b4cd190, seg2 size: 12288 > encl_load: encl_size: 140737488355328, src_size: 140588159402384 > encl_map_area: encl_size: 140737488355328 > mmap: Cannot allocate memory > > src_size is computed by adding the offset and size of the last segment > which is at index 2. src_size does not look right. I'll debug. > The loop computes encl_size to 0x0000800000000000 then and mmap tries to > map double that in encl_map_area(). Looks like too much to me too. The enclave base must be naturally aligned in relative to its size. > What's up? > > -- > Regards/Gruss, > Boris. > > https://people.kernel.org/tglx/notes-about-netiquette /Jarkko