Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(984)

Unified Diff: src/trusted/validator/ncfileutil.c

Issue 8161004: Handle ELFCLASS32 files for x86-64 (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: typo fixes in last iteration Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator/ncfileutil.c
diff --git a/src/trusted/validator/ncfileutil.c b/src/trusted/validator/ncfileutil.c
index bb7e6279fe31ab0e95d20dd704176651c1394afb..1814eb3e66c8715a672ace74ed86c3e91074e05d 100644
--- a/src/trusted/validator/ncfileutil.c
+++ b/src/trusted/validator/ncfileutil.c
@@ -83,8 +83,16 @@ static const char* GetEiClassName(unsigned char c) {
}
static int nc_load(ncfile *ncf, int fd) {
-
- Elf_Ehdr h;
+ union {
+ Elf32_Ehdr h32;
+#if NACL_TARGET_SUBARCH == 64
+ Elf64_Ehdr h64;
+#endif
+ } h;
+ Elf_Half phnum;
+ Elf_Half shnum;
+ Elf_Off phoff;
+ Elf_Off shoff;
ssize_t nread;
Elf_Addr vmemlo, vmemhi;
size_t shsize, phsize;
@@ -98,42 +106,100 @@ static int nc_load(ncfile *ncf, int fd) {
}
/* do a bunch of sanity checks */
- if (strncmp((char *)h.e_ident, ELFMAG, strlen(ELFMAG))) {
+ if (memcmp(h.h32.e_ident, ELFMAG, SELFMAG)) {
ncf->error_fn("nc_load(%s): bad magic number", ncf->fname);
return -1;
}
- if (h.e_ident[EI_CLASS] != NACL_ELF_CLASS) {
- ncf->error_fn("nc_load(%s): bad EI CLASS %d %s\n", ncf->fname,
- h.e_ident[EI_CLASS], GetEiClassName(h.e_ident[EI_CLASS]));
+#if NACL_TARGET_SUBARCH == 64
+ if (h.h32.e_ident[EI_CLASS] == ELFCLASS64) {
+ if (h.h64.e_phoff > 0xffffffffU) {
+ ncf->error_fn("nc_load(%s): e_phoff overflows 32 bits\n", ncf->fname);
+ return -1;
+ }
+ if (h.h64.e_shoff > 0xffffffffU) {
+ ncf->error_fn("nc_load(%s): e_shoff overflows 32 bits\n", ncf->fname);
+ return -1;
+ }
+ phoff = (Elf32_Off) h.h64.e_phoff;
+ shoff = (Elf32_Off) h.h64.e_shoff;
+ phnum = h.h64.e_phnum;
+ shnum = h.h64.e_shnum;
+ } else
+#endif
+ {
+ if (h.h32.e_ident[EI_CLASS] == ELFCLASS32) {
+ phoff = h.h32.e_phoff;
+ shoff = h.h32.e_shoff;
+ phnum = h.h32.e_phnum;
+ shnum = h.h32.e_shnum;
+ } else {
+ ncf->error_fn("nc_load(%s): bad EI CLASS %d %s\n", ncf->fname,
+ h.h32.e_ident[EI_CLASS],
+ GetEiClassName(h.h32.e_ident[EI_CLASS]));
+ return -1;
+ }
}
/* We now support only 32-byte bundle alignment. */
ncf->ncalign = 32;
/* Read the program header table */
- if (h.e_phnum <= 0 || h.e_phnum > kMaxPhnum) {
- ncf->error_fn("nc_load(%s): h.e_phnum %d > kMaxPhnum %d\n",
- ncf->fname, h.e_phnum, kMaxPhnum);
+ if (phnum <= 0 || phnum > kMaxPhnum) {
+ ncf->error_fn("nc_load(%s): e_phnum %d > kMaxPhnum %d\n",
+ ncf->fname, phnum, kMaxPhnum);
return -1;
}
- ncf->phnum = h.e_phnum;
- ncf->pheaders = (Elf_Phdr *)calloc(h.e_phnum, sizeof(Elf_Phdr));
+ ncf->phnum = phnum;
+ ncf->pheaders = (Elf_Phdr *)calloc(phnum, sizeof(Elf_Phdr));
if (NULL == ncf->pheaders) {
ncf->error_fn("nc_load(%s): calloc(%d, %"NACL_PRIdS") failed\n",
- ncf->fname, h.e_phnum, sizeof(Elf_Phdr));
+ ncf->fname, phnum, sizeof(Elf_Phdr));
return -1;
}
- phsize = h.e_phnum * sizeof(*ncf->pheaders);
- /* TODO(karl) Remove the cast to size_t, or verify size. */
- nread = readat(ncf, fd, ncf->pheaders, (off_t) phsize, (off_t) h.e_phoff);
- if (nread < 0 || (size_t) nread < phsize) return -1;
+ phsize = phnum * sizeof(*ncf->pheaders);
+#if NACL_TARGET_SUBARCH == 64
+ if (h.h32.e_ident[EI_CLASS] == ELFCLASS64) {
+ /*
+ * Read 64-bit program headers and convert them.
+ */
+ Elf64_Phdr phdr64[kMaxPhnum];
+ nread = readat(ncf, fd, phdr64, (off_t) (phnum * sizeof(phdr64[0])),
+ (off_t) phoff);
+ if (nread < 0 || (size_t) nread < phsize) return -1;
+ for (i = 0; i < phnum; ++i) {
+ if (phdr64[i].p_offset > 0xffffffffU ||
+ phdr64[i].p_vaddr > 0xffffffffU ||
+ phdr64[i].p_paddr > 0xffffffffU ||
+ phdr64[i].p_filesz > 0xffffffffU ||
+ phdr64[i].p_memsz > 0xffffffffU ||
+ phdr64[i].p_align > 0xffffffffU) {
+ ncf->error_fn("nc_load(%s): phdr[%d] fields overflow 32 bits\n",
+ ncf->fname, i);
+ return -1;
+ }
+ ncf->pheaders[i].p_type = phdr64[i].p_type;
+ ncf->pheaders[i].p_flags = phdr64[i].p_flags;
+ ncf->pheaders[i].p_offset = (Elf32_Off) phdr64[i].p_offset;
+ ncf->pheaders[i].p_vaddr = (Elf32_Addr) phdr64[i].p_vaddr;
+ ncf->pheaders[i].p_paddr = (Elf32_Addr) phdr64[i].p_paddr;
+ ncf->pheaders[i].p_filesz = (Elf32_Word) phdr64[i].p_filesz;
+ ncf->pheaders[i].p_memsz = (Elf32_Word) phdr64[i].p_memsz;
+ ncf->pheaders[i].p_align = (Elf32_Word) phdr64[i].p_align;
+ }
+ } else
+#endif
+ {
+ /* TODO(karl) Remove the cast to size_t, or verify size. */
+ nread = readat(ncf, fd, ncf->pheaders, (off_t) phsize, (off_t) phoff);
+ if (nread < 0 || (size_t) nread < phsize) return -1;
+ }
/* Iterate through the program headers to find the virtual */
/* size of loaded text. */
vmemlo = MAX_ELF_ADDR;
vmemhi = MIN_ELF_ADDR;
- for (i = 0; i < h.e_phnum; i++) {
+ for (i = 0; i < phnum; i++) {
if (ncf->pheaders[i].p_type != PT_LOAD) continue;
if (0 == (ncf->pheaders[i].p_flags & PF_X)) continue;
/* This is executable text. Check low and high addrs */
@@ -153,7 +219,7 @@ static int nc_load(ncfile *ncf, int fd) {
}
/* Load program text segments */
- for (i = 0; i < h.e_phnum; i++) {
+ for (i = 0; i < phnum; i++) {
const Elf_Phdr *p = &ncf->pheaders[i];
if (p->p_type != PT_LOAD) continue;
if (0 == (ncf->pheaders[i].p_flags & PF_X)) continue;
@@ -169,8 +235,9 @@ static int nc_load(ncfile *ncf, int fd) {
return -1;
}
}
+
/* load the section headers */
- ncf->shnum = h.e_shnum;
+ ncf->shnum = shnum;
shsize = ncf->shnum * sizeof(*ncf->sheaders);
ncf->sheaders = (Elf_Shdr *)calloc(1, shsize);
if (NULL == ncf->sheaders) {
@@ -178,12 +245,56 @@ static int nc_load(ncfile *ncf, int fd) {
ncf->fname, shsize);
return -1;
}
- /* TODO(karl) Remove the cast to size_t, or verify value in range. */
- nread = readat(ncf, fd, ncf->sheaders, (off_t) shsize, (off_t) h.e_shoff);
- if (nread < 0 || (size_t) nread < shsize) {
- ncf->error_fn("nc_load(%s): could not read section headers\n",
- ncf->fname);
- return -1;
+#if NACL_TARGET_SUBARCH == 64
+ if (h.h32.e_ident[EI_CLASS] == ELFCLASS64) {
+ /*
+ * Read 64-bit section headers and convert them.
+ */
+ Elf64_Shdr *shdr64 = (Elf64_Shdr *)calloc(shnum, sizeof(shdr64[0]));
+ if (NULL == shdr64) {
+ ncf->error_fn(
+ "nc_load(%s): calloc(%"NACL_PRIdS", %"NACL_PRIdS") failed\n",
+ ncf->fname, (size_t) shnum, sizeof(shdr64[0]));
+ return -1;
+ }
+ shsize = ncf->shnum * sizeof(shdr64[0]);
+ nread = readat(ncf, fd, shdr64, (off_t) shsize, (off_t) shoff);
+ if (nread < 0 || (size_t) nread < shsize) {
+ ncf->error_fn("nc_load(%s): could not read section headers\n",
+ ncf->fname);
+ return -1;
+ }
+ for (i = 0; i < shnum; ++i) {
+ if (shdr64[i].sh_flags > 0xffffffffU ||
+ shdr64[i].sh_size > 0xffffffffU ||
+ shdr64[i].sh_addralign > 0xffffffffU ||
+ shdr64[i].sh_entsize > 0xffffffffU) {
+ ncf->error_fn("nc_load(%s): shdr[%d] fields overflow 32 bits\n",
+ ncf->fname, i);
+ return -1;
+ }
+ ncf->sheaders[i].sh_name = shdr64[i].sh_name;
+ ncf->sheaders[i].sh_type = shdr64[i].sh_type;
+ ncf->sheaders[i].sh_flags = (Elf32_Word) shdr64[i].sh_flags;
+ ncf->sheaders[i].sh_addr = (Elf32_Addr) shdr64[i].sh_addr;
+ ncf->sheaders[i].sh_offset = (Elf32_Off) shdr64[i].sh_offset;
+ ncf->sheaders[i].sh_size = (Elf32_Word) shdr64[i].sh_size;
+ ncf->sheaders[i].sh_link = shdr64[i].sh_link;
+ ncf->sheaders[i].sh_info = shdr64[i].sh_info;
+ ncf->sheaders[i].sh_addralign = (Elf32_Word) shdr64[i].sh_addralign;
+ ncf->sheaders[i].sh_entsize = (Elf32_Word) shdr64[i].sh_entsize;
+ }
+ free(shdr64);
+ } else
+#endif
+ {
+ /* TODO(karl) Remove the cast to size_t, or verify value in range. */
+ nread = readat(ncf, fd, ncf->sheaders, (off_t) shsize, (off_t) shoff);
+ if (nread < 0 || (size_t) nread < shsize) {
+ ncf->error_fn("nc_load(%s): could not read section headers\n",
+ ncf->fname);
+ return -1;
+ }
}
/* success! */
« no previous file with comments | « src/trusted/service_runtime/testdata/x86_64/text_too_big.stderr ('k') | src/trusted/validator_x86/build.scons » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698