lkml.org 
[lkml]   [2020]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v41 20/24] selftests/x86: Add a selftest for SGX
    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.

    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.

    What's up?

    --
    Regards/Gruss,
    Boris.

    https://people.kernel.org/tglx/notes-about-netiquette

    \
     
     \ /
      Last update: 2020-11-17 18:29    [W:4.623 / U:0.744 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site