示例#1
0
文件: elf_util.c 项目: vi4m/zerovm
struct NaClElfImage *NaClElfImageNew(struct Gio *gp)
{
  struct NaClElfImage *result;
  struct NaClElfImage image;
  int                 cur_ph;

  memset(image.loadable, 0, sizeof image.loadable);

  /* fail if could not seek to beginning of Gio object containing nexe */
  ZLOGFAIL(-1 == (*gp->vtbl->Seek)(gp, 0, 0), EIO, FAILED_MSG);

  /* fail if could not load elf headers*/
  ZLOGFAIL((*gp->vtbl->Read)(gp, &image.ehdr, sizeof image.ehdr) != sizeof image.ehdr,
      EIO, FAILED_MSG);

  NaClDumpElfHeader(LOG_DEBUG, &image.ehdr);

  /* read program headers. fail if too many prog headers */
  ZLOGFAIL(image.ehdr.e_phnum > NACL_MAX_PROGRAM_HEADERS, ENOEXEC, FAILED_MSG);

  /* fail if ELF program header size too small */
  ZLOGFAIL(image.ehdr.e_phentsize < sizeof image.phdrs[0], ENOEXEC,
      "bad prog headers size. image.ehdr.e_phentsize = 0x%x, sizeof "
      "image.phdrs[0] = 0x%x", image.ehdr.e_phentsize, sizeof image.phdrs[0]);

  /*
   * NB: cast from e_phoff to off_t may not be valid, since off_t can be
   * smaller than Elf64_off, but since invalid values will be rejected
   * by Seek() the cast is safe (cf bsy)
   * d'b: fail if cannot seek tp prog headers
   */
  ZLOGFAIL((*gp->vtbl->Seek)(gp, (off_t)image.ehdr.e_phoff, SEEK_SET) == (off_t)-1,
      EIO, FAILED_MSG);

  /* fail if cannot load tp prog headers */
  ZLOGFAIL((size_t)(*gp->vtbl->Read)(gp, &image.phdrs[0], image.ehdr.e_phnum * sizeof
      image.phdrs[0]) != (image.ehdr.e_phnum * sizeof image.phdrs[0]), EIO, FAILED_MSG);

  ZLOGS(LOG_DEBUG, "%020o (elf segments) %020o", 0, 0);
  for(cur_ph = 0; cur_ph < image.ehdr.e_phnum; ++cur_ph)
    NaClDumpElfProgramHeader(LOG_DEBUG, &image.phdrs[cur_ph]);

  /* we delay allocating till the end to avoid cleanup code */
  /* fail if not enough memory for image meta data */
  result = g_malloc(sizeof image);
  ZLOGFAIL(result == NULL, ENOMEM, FAILED_MSG);

  memcpy(result, &image, sizeof image);
  return result;
}
示例#2
0
struct NaClElfImage *NaClElfImageNew(struct NaClDesc *ndp,
                                     NaClErrorCode *err_code) {
  ssize_t read_ret;
  struct NaClElfImage *result;
  struct NaClElfImage image;
  union {
    Elf32_Ehdr ehdr32;
#if NACL_BUILD_SUBARCH == 64
    Elf64_Ehdr ehdr64;
#endif
  } ehdr;
  int cur_ph;

  memset(image.loadable, 0, sizeof image.loadable);

  /*
   * We read the larger size of an ELFCLASS64 header even if it turns out
   * we're reading an ELFCLASS32 file.  No usable ELFCLASS32 binary could
   * be so small that it's not larger than Elf64_Ehdr anyway.
   */
  read_ret = (*NACL_VTBL(NaClDesc, ndp)->PRead)(ndp, &ehdr, sizeof ehdr, 0);
  if (NaClSSizeIsNegErrno(&read_ret) || (size_t) read_ret != sizeof ehdr) {
    *err_code = LOAD_READ_ERROR;
    NaClLog(2, "could not load elf headers\n");
    return 0;
  }

#if NACL_BUILD_SUBARCH == 64
  if (ELFCLASS64 == ehdr.ehdr64.e_ident[EI_CLASS]) {
    /*
     * Convert ELFCLASS64 format to ELFCLASS32 format.
     * The initial four fields are the same in both classes.
     */
    memcpy(image.ehdr.e_ident, ehdr.ehdr64.e_ident, EI_NIDENT);
    image.ehdr.e_ident[EI_CLASS] = ELFCLASS32;
    image.ehdr.e_type = ehdr.ehdr64.e_type;
    image.ehdr.e_machine = ehdr.ehdr64.e_machine;
    image.ehdr.e_version = ehdr.ehdr64.e_version;
    if (ehdr.ehdr64.e_entry > 0xffffffffU ||
        ehdr.ehdr64.e_phoff > 0xffffffffU ||
        ehdr.ehdr64.e_shoff > 0xffffffffU) {
      *err_code = LOAD_EHDR_OVERFLOW;
      NaClLog(2, "ELFCLASS64 file header fields overflow 32 bits\n");
      return 0;
    }
    image.ehdr.e_entry = (Elf32_Addr) ehdr.ehdr64.e_entry;
    image.ehdr.e_phoff = (Elf32_Off) ehdr.ehdr64.e_phoff;
    image.ehdr.e_shoff = (Elf32_Off) ehdr.ehdr64.e_shoff;
    image.ehdr.e_flags = ehdr.ehdr64.e_flags;
    if (ehdr.ehdr64.e_ehsize != sizeof(ehdr.ehdr64)) {
      *err_code = LOAD_BAD_EHSIZE;
      NaClLog(2, "ELFCLASS64 file e_ehsize != %d\n", (int) sizeof(ehdr.ehdr64));
      return 0;
    }
    image.ehdr.e_ehsize = sizeof(image.ehdr);
    image.ehdr.e_phentsize = sizeof(image.phdrs[0]);
    image.ehdr.e_phnum = ehdr.ehdr64.e_phnum;
    image.ehdr.e_shentsize = ehdr.ehdr64.e_shentsize;
    image.ehdr.e_shnum = ehdr.ehdr64.e_shnum;
    image.ehdr.e_shstrndx = ehdr.ehdr64.e_shstrndx;
  } else
#endif
  {
    image.ehdr = ehdr.ehdr32;
  }

  NaClDumpElfHeader(2, &image.ehdr);

  *err_code = NaClElfImageValidateElfHeader(&image);
  if (LOAD_OK != *err_code) {
    return 0;
  }

  /* read program headers */
  if (image.ehdr.e_phnum > NACL_MAX_PROGRAM_HEADERS) {
    *err_code = LOAD_TOO_MANY_PROG_HDRS;
    NaClLog(2, "too many prog headers\n");
    return 0;
  }

#if NACL_BUILD_SUBARCH == 64
  if (ELFCLASS64 == ehdr.ehdr64.e_ident[EI_CLASS]) {
    /*
     * We'll load the 64-bit phdrs and convert them to 32-bit format.
     */
    Elf64_Phdr phdr64[NACL_MAX_PROGRAM_HEADERS];

    if (ehdr.ehdr64.e_phentsize != sizeof(Elf64_Phdr)) {
      *err_code = LOAD_BAD_PHENTSIZE;
      NaClLog(2, "bad prog headers size\n");
      NaClLog(2, " ehdr64.e_phentsize = 0x%"NACL_PRIxElf_Half"\n",
              ehdr.ehdr64.e_phentsize);
      NaClLog(2, "  sizeof(Elf64_Phdr) = 0x%"NACL_PRIxS"\n",
              sizeof(Elf64_Phdr));
      return 0;
    }

    /*
     * We know the multiplication won't overflow since we rejected
     * e_phnum values larger than the small constant NACL_MAX_PROGRAM_HEADERS.
     */
    read_ret = (*NACL_VTBL(NaClDesc, ndp)->
                PRead)(ndp,
                       &phdr64[0],
                       image.ehdr.e_phnum * sizeof phdr64[0],
                       (nacl_off64_t) image.ehdr.e_phoff);
    if (NaClSSizeIsNegErrno(&read_ret) ||
        (size_t) read_ret != image.ehdr.e_phnum * sizeof phdr64[0]) {
      *err_code = LOAD_READ_ERROR;
      NaClLog(2, "cannot load tp prog headers\n");
      return 0;
    }

    for (cur_ph = 0; cur_ph < image.ehdr.e_phnum; ++cur_ph) {
      if (phdr64[cur_ph].p_offset > 0xffffffffU ||
          phdr64[cur_ph].p_vaddr > 0xffffffffU ||
          phdr64[cur_ph].p_paddr > 0xffffffffU ||
          phdr64[cur_ph].p_filesz > 0xffffffffU ||
          phdr64[cur_ph].p_memsz > 0xffffffffU ||
          phdr64[cur_ph].p_align > 0xffffffffU) {
        *err_code = LOAD_PHDR_OVERFLOW;
        NaClLog(2, "ELFCLASS64 program header fields overflow 32 bits\n");
        return 0;
      }
      image.phdrs[cur_ph].p_type = phdr64[cur_ph].p_type;
      image.phdrs[cur_ph].p_offset = (Elf32_Off) phdr64[cur_ph].p_offset;
      image.phdrs[cur_ph].p_vaddr = (Elf32_Addr) phdr64[cur_ph].p_vaddr;
      image.phdrs[cur_ph].p_paddr = (Elf32_Addr) phdr64[cur_ph].p_paddr;
      image.phdrs[cur_ph].p_filesz = (Elf32_Word) phdr64[cur_ph].p_filesz;
      image.phdrs[cur_ph].p_memsz = (Elf32_Word) phdr64[cur_ph].p_memsz;
      image.phdrs[cur_ph].p_flags = phdr64[cur_ph].p_flags;
      image.phdrs[cur_ph].p_align = (Elf32_Word) phdr64[cur_ph].p_align;
    }
  } else
#endif
  {
    if (image.ehdr.e_phentsize != sizeof image.phdrs[0]) {
      *err_code = LOAD_BAD_PHENTSIZE;
      NaClLog(2, "bad prog headers size\n");
      NaClLog(2, " image.ehdr.e_phentsize = 0x%"NACL_PRIxElf_Half"\n",
              image.ehdr.e_phentsize);
      NaClLog(2, "  sizeof image.phdrs[0] = 0x%"NACL_PRIxS"\n",
              sizeof image.phdrs[0]);
      return 0;
    }

    read_ret = (*NACL_VTBL(NaClDesc, ndp)->
                PRead)(ndp,
                       &image.phdrs[0],
                       image.ehdr.e_phnum * sizeof image.phdrs[0],
                       (nacl_off64_t) image.ehdr.e_phoff);
    if (NaClSSizeIsNegErrno(&read_ret) ||
        (size_t) read_ret != image.ehdr.e_phnum * sizeof image.phdrs[0]) {
      *err_code = LOAD_READ_ERROR;
      NaClLog(2, "cannot load tp prog headers\n");
      return 0;
    }
  }

  NaClLog(2, "=================================================\n");
  NaClLog(2, "Elf Program headers\n");
  NaClLog(2, "==================================================\n");
  for (cur_ph = 0; cur_ph <  image.ehdr.e_phnum; ++cur_ph) {
    NaClDumpElfProgramHeader(2, &image.phdrs[cur_ph]);
  }

  /* we delay allocating till the end to avoid cleanup code */
  result = malloc(sizeof image);
  if (result == 0) {
    *err_code = LOAD_NO_MEMORY;
    NaClLog(LOG_FATAL, "no enough memory for image meta data\n");
    return 0;
  }
  memcpy(result, &image, sizeof image);
  *err_code = LOAD_OK;
  return result;
}
示例#3
0
文件: elf_util.c 项目: camuel/zvm
struct NaClElfImage *NaClElfImageNew(struct Gio     *gp,
                                     NaClErrorCode  *err_code) {
  struct NaClElfImage *result;
  struct NaClElfImage image;
  int                 cur_ph;

  memset(image.loadable, 0, sizeof image.loadable);
  if (-1 == (*gp->vtbl->Seek)(gp, 0, 0)) {
    NaClLog(2, "could not seek to beginning of Gio object containing nexe\n");
    if (NULL != err_code) {
      *err_code = LOAD_READ_ERROR;
    }
    return 0;
  }
  if ((*gp->vtbl->Read)(gp,
                        &image.ehdr,
                        sizeof image.ehdr)
      != sizeof image.ehdr) {
    if (NULL != err_code) {
      *err_code = LOAD_READ_ERROR;
    }
    NaClLog(2, "could not load elf headers\n");
    return 0;
  }

  NaClDumpElfHeader(2, &image.ehdr);

  /* read program headers */
  if (image.ehdr.e_phnum > NACL_MAX_PROGRAM_HEADERS) {
    if (NULL != err_code)
      *err_code = LOAD_TOO_MANY_PROG_HDRS;
    NaClLog(2, "too many prog headers\n");
    return 0;
  }

  if (image.ehdr.e_phentsize < sizeof image.phdrs[0]) {
    if (NULL != err_code) {
      *err_code = LOAD_PROG_HDR_SIZE_TOO_SMALL;
    }
    NaClLog(2, "bad prog headers size\n");
    NaClLog(2, " image.ehdr.e_phentsize = 0x%"NACL_PRIxElf_Half"\n",
            image.ehdr.e_phentsize);
    NaClLog(2, "  sizeof image.phdrs[0] = 0x%"NACL_PRIxS"\n",
            sizeof image.phdrs[0]);
    return 0;
  }

  /*
   * NB: cast from e_phoff to off_t may not be valid, since off_t can be
   * smaller than Elf64_off, but since invalid values will be rejected
   * by Seek() the cast is safe (cf bsy)
   */
  if ((*gp->vtbl->Seek)(gp,
                        (off_t) image.ehdr.e_phoff,
                        SEEK_SET) == (off_t) -1) {
    if (NULL != err_code) {
      *err_code = LOAD_READ_ERROR;
    }
    NaClLog(2, "cannot seek tp prog headers\n");
    return 0;
  }

  if ((size_t) (*gp->vtbl->Read)(gp,
                                 &image.phdrs[0],
                                 image.ehdr.e_phnum * sizeof image.phdrs[0])
      != (image.ehdr.e_phnum * sizeof image.phdrs[0])) {
    if (NULL != err_code) {
      *err_code = LOAD_READ_ERROR;
    }
    NaClLog(2, "cannot load tp prog headers\n");
    return 0;
  }

  NaClLog(2, "=================================================\n");
  NaClLog(2, "Elf Program headers\n");
  NaClLog(2, "==================================================\n");
  for (cur_ph = 0; cur_ph <  image.ehdr.e_phnum; ++cur_ph) {
    NaClDumpElfProgramHeader(2, &image.phdrs[cur_ph]);
  }

  /* we delay allocating till the end to avoid cleanup code */
  result = malloc(sizeof image);
  if (result == 0) {
    if (NULL != err_code) {
      *err_code = LOAD_NO_MEMORY;
    }
    NaClLog(LOG_FATAL, "no enough memory for image meta data\n");
    return 0;
  }
  memcpy(result, &image, sizeof image);
  return result;
}