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

Unified Diff: src/trusted/service_runtime/elf_util.c

Issue 8161004: Handle ELFCLASS32 files for x86-64 (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: rebased; binary testdata committed separately 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
« no previous file with comments | « src/trusted/service_runtime/build.scons ('k') | src/trusted/service_runtime/nacl_error_code.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/trusted/service_runtime/elf_util.c
diff --git a/src/trusted/service_runtime/elf_util.c b/src/trusted/service_runtime/elf_util.c
index 2c4365ee7053aeee43fb0d2d263454b5c96f4a93..07a63722a8855dee5dd4c00ec3ff736c9f650e6e 100644
--- a/src/trusted/service_runtime/elf_util.c
+++ b/src/trusted/service_runtime/elf_util.c
@@ -155,17 +155,10 @@ NaClErrorCode NaClElfImageValidateElfHeader(struct NaClElfImage *image) {
return LOAD_BAD_ELF_MAGIC;
}
-#if NACL_TARGET_SUBARCH == 64
- if (ELFCLASS64 != hdr->e_ident[EI_CLASS]) {
- NaClLog(LOG_ERROR, "bad elf class\n");
- return LOAD_NOT_64_BIT;
- }
-#else
if (ELFCLASS32 != hdr->e_ident[EI_CLASS]) {
NaClLog(LOG_ERROR, "bad elf class\n");
return LOAD_NOT_32_BIT;
}
-#endif
if (ET_EXEC != hdr->e_type) {
NaClLog(LOG_ERROR, "non executable\n");
@@ -282,8 +275,9 @@ NaClErrorCode NaClElfImageValidateProgramHeaders(
return LOAD_SEGMENT_OUTSIDE_ADDRSPACE;
}
/*
- * integer overflow? Elf_Addr and Elf_Word are uint32_t or
- * uint64_t, so the addition/comparison is well defined.
+ * integer overflow? Elf_Addr and Elf_Word are always uint32_t,
+ * so the addition/comparison is well defined but we need to do
+ * a 64-bit comparison when addr_bits is 32.
*/
if (php->p_vaddr + php->p_memsz < php->p_vaddr) {
NaClLog(2,
@@ -291,7 +285,7 @@ NaClErrorCode NaClElfImageValidateProgramHeaders(
segnum);
return LOAD_SEGMENT_OUTSIDE_ADDRSPACE;
}
- if (php->p_vaddr + php->p_memsz >= ((Elf_Addr) 1U << addr_bits)) {
+ if (php->p_vaddr + php->p_memsz >= ((uint64_t) 1U << addr_bits)) {
bsy 2011/10/11 00:26:52 the sum can overflow since the add is done as uint
NaClLog(2,
"Segment %d: too large, ends at 0x%08"NACL_PRIxElf_Addr"\n",
segnum,
@@ -363,6 +357,12 @@ struct NaClElfImage *NaClElfImageNew(struct Gio *gp,
NaClErrorCode *err_code) {
struct NaClElfImage *result;
struct NaClElfImage image;
+ union {
+ Elf32_Ehdr ehdr32;
+#if NACL_TARGET_SUBARCH == 64
+ Elf64_Ehdr ehdr64;
+#endif
+ } ehdr;
int cur_ph;
memset(image.loadable, 0, sizeof image.loadable);
@@ -374,9 +374,9 @@ struct NaClElfImage *NaClElfImageNew(struct Gio *gp,
return 0;
}
if ((*gp->vtbl->Read)(gp,
- &image.ehdr,
- sizeof image.ehdr)
- != sizeof image.ehdr) {
+ &ehdr,
+ sizeof ehdr)
bsy 2011/10/11 00:26:52 maybe a comment here that reading the size of the
+ != sizeof ehdr) {
if (NULL != err_code) {
*err_code = LOAD_READ_ERROR;
}
@@ -384,6 +384,49 @@ struct NaClElfImage *NaClElfImageNew(struct Gio *gp,
return 0;
}
+#if NACL_TARGET_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) {
+ if (NULL != err_code) {
+ *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)) {
+ if (NULL != err_code) {
+ *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);
/* read program headers */
@@ -394,18 +437,6 @@ struct NaClElfImage *NaClElfImageNew(struct Gio *gp,
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
@@ -421,15 +452,83 @@ struct NaClElfImage *NaClElfImageNew(struct Gio *gp,
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;
+#if NACL_TARGET_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)) {
+ if (NULL != err_code) {
+ *err_code = LOAD_PROG_HDR_SIZE_TOO_SMALL;
+ }
+ 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;
+ }
+
+ if ((size_t) (*gp->vtbl->Read)(gp,
+ &phdr64[0],
+ image.ehdr.e_phnum * sizeof phdr64[0])
+ != (image.ehdr.e_phnum * sizeof phdr64[0])) {
+ if (NULL != err_code) {
+ *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) {
+ if (NULL != err_code) {
+ *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]) {
+ 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;
+ }
+
+ 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, "cannot load tp prog headers\n");
- return 0;
}
NaClLog(2, "=================================================\n");
@@ -608,7 +707,7 @@ NaClErrorCode NaClElfImageLoadDynamically(struct NaClElfImage *image,
* instead.)
*/
result = NaClCommonSysMmapIntern(
- nap, (void *) php->p_vaddr, mapping_size,
+ nap, (void *) (uintptr_t) php->p_vaddr, mapping_size,
NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE,
NACL_ABI_MAP_ANONYMOUS | NACL_ABI_MAP_PRIVATE,
-1, 0);
« no previous file with comments | « src/trusted/service_runtime/build.scons ('k') | src/trusted/service_runtime/nacl_error_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698