Browse Source

[Pal/Linux-SGX] Do not perform _DkStreamRead() on already mmapped exec file

Isaku Yamahata 4 years ago
parent
commit
f0b91c22b2
3 changed files with 23 additions and 12 deletions
  1. 10 3
      Pal/src/db_main.c
  2. 12 9
      Pal/src/db_rtld.c
  3. 1 0
      Pal/src/pal_internal.h

+ 10 - 3
Pal/src/db_main.c

@@ -380,9 +380,16 @@ noreturn void pal_main (
         }
     }
 
-    /* must be a ELF */
-    if (exec_handle && check_elf_object(exec_handle) < 0)
-        INIT_FAIL(PAL_ERROR_INVAL, "executable is not a ELF binary");
+    /* must be an ELF */
+    if (exec_handle) {
+        if (exec_loaded_addr) {
+            if (check_elf_magic(exec_loaded_addr, sizeof(ElfW(Ehdr))))
+                INIT_FAIL(PAL_ERROR_INVAL, "executable is not an ELF binary");
+        } else {
+            if (check_elf_object(exec_handle) < 0)
+                INIT_FAIL(PAL_ERROR_INVAL, "executable is not an ELF binary");
+        }
+    }
 
     pal_state.manifest        = manifest_uri;
     pal_state.manifest_handle = manifest_handle;

+ 12 - 9
Pal/src/db_rtld.c

@@ -433,20 +433,13 @@ postmap:
     return l;
 }
 
-int check_elf_object (PAL_HANDLE handle)
+int check_elf_magic (const void* header, size_t len)
 {
 #define ELF_MAGIC_SIZE EI_CLASS
-    unsigned char buffer[ELF_MAGIC_SIZE];
-
-    int len = _DkStreamRead(handle, 0, ELF_MAGIC_SIZE, buffer, NULL, 0);
-
-    if (len < 0)
-        return -len;
-
     if (len < ELF_MAGIC_SIZE)
         return -PAL_ERROR_INVAL;
 
-    ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *) buffer;
+    ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *) header;
 
     static const unsigned char expected[EI_CLASS] =
     {
@@ -463,6 +456,16 @@ int check_elf_object (PAL_HANDLE handle)
     return 0;
 }
 
+int check_elf_object (PAL_HANDLE handle)
+{
+    unsigned char buffer[ELF_MAGIC_SIZE];
+    int64_t len = _DkStreamRead(handle, 0, sizeof(buffer), buffer, NULL, 0);
+
+    if (__builtin_expect(len < 0, 0))
+        return len;
+    return check_elf_magic(buffer, len);
+}
+
 void free_elf_object (struct link_map * map)
 {
     _DkVirtualMemoryFree((void *) map->l_map_start,

+ 1 - 0
Pal/src/pal_internal.h

@@ -360,6 +360,7 @@ int _DkCpuIdRetrieve (unsigned int leaf, unsigned int subleaf, unsigned int valu
 /* function and definition for loading binaries */
 enum object_type { OBJECT_RTLD, OBJECT_EXEC, OBJECT_PRELOAD, OBJECT_EXTERNAL };
 
+int check_elf_magic (const void* header, size_t len);
 int check_elf_object (PAL_HANDLE handle);
 int load_elf_object (const char * uri, enum object_type type);
 int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type);