Browse Source

[Pal, LibOS] Pass AT_RANDOM ELF auxiliary vector with 16B random value

New versions of Glibc read AT_RANDOM aux vector during start-up. This
vector contains a pointer to a 16B area with a random value. This commit
passes AT_RANDOM to in-enclave executable and initializes this 16B area.
Isaku Yamahata 5 years ago
parent
commit
c4a29250e8
3 changed files with 26 additions and 5 deletions
  1. 11 1
      LibOS/shim/src/elf/shim_rtld.c
  2. 5 0
      LibOS/shim/src/shim_init.c
  3. 10 4
      Pal/src/db_rtld.c

+ 11 - 1
LibOS/shim/src/elf/shim_rtld.c

@@ -1570,6 +1570,14 @@ void execute_elf_object (struct shim_handle * exec,
     assert((uintptr_t)argcp % 16 == 0);  // Stack should be aligned to 16 on entry point.
     assert((void*)argcp + sizeof(long) == argp || argp == NULL);
 
+    /* random 16 bytes follows auxp */
+    ElfW(Addr) random = (ElfW(Addr))&auxp[7];
+    int ret = DkRandomBitsRead((PAL_PTR)random, 16);
+    if (ret < 0) {
+        debug("execute_elf_object: DkRandomBitsRead failed.\n");
+        DkThreadExit();
+    }
+
     auxp[0].a_type = AT_PHDR;
     auxp[0].a_un.a_val = (__typeof(auxp[0].a_un.a_val)) exec_map->l_phdr;
     auxp[1].a_type = AT_PHNUM;
@@ -1580,7 +1588,9 @@ void execute_elf_object (struct shim_handle * exec,
     auxp[3].a_un.a_val = exec_map->l_entry;
     auxp[4].a_type = AT_BASE;
     auxp[4].a_un.a_val = interp_map ? interp_map->l_addr : 0;
-    auxp[5].a_type = AT_NULL;
+    auxp[5].a_type = AT_RANDOM;
+    auxp[5].a_un.a_val = random;
+    auxp[6].a_type = AT_NULL;
 
     ElfW(Addr) entry = interp_map ? interp_map->l_entry : exec_map->l_entry;
 

+ 5 - 0
LibOS/shim/src/shim_init.c

@@ -342,6 +342,11 @@ copy_envp:
             memcpy(new_auxp, *auxpp, nauxv * sizeof(elf_auxv_t));
     }
 
+    /* reserve at least 16 bytes on the stack to accommodate AT_RANDOM bytes
+     * later
+     */
+    ALLOCATE_TOP(16);
+
     /* x86_64 ABI requires 16 bytes alignment on stack on every function
        call. */
     size_t move_size = stack_bottom - stack;

+ 10 - 4
Pal/src/db_rtld.c

@@ -1331,7 +1331,7 @@ void start_execution (const char * first_argument, const char ** arguments,
     ncookies++; /* for NULL-end */
 
     int cookiesz = sizeof(unsigned long int) * ncookies
-                      + sizeof(ElfW(auxv_t)) * 6
+                      + sizeof(ElfW(auxv_t)) * 6 + 16
                       + sizeof(void *) * 4 + 16;
 
     unsigned long int * cookies = __alloca(cookiesz);
@@ -1350,6 +1350,12 @@ void start_execution (const char * first_argument, const char ** arguments,
     cookies[cnt++] = 0;
 
     ElfW(auxv_t) * auxv = (ElfW(auxv_t) *) &cookies[cnt];
+    /* random 16 bytes follows auxp */
+    ElfW(Addr) random = (ElfW(Addr))&auxv[7];
+    int ret = DkRandomBitsRead((PAL_PTR)random, 16);
+    if (ret < 0)
+        INIT_FAIL(-ret, "start_execution: DkRandomBitsRead failed\n");
+
     auxv[0].a_type = AT_PHDR;
     auxv[0].a_un.a_val = exec_map ? (unsigned long) exec_map->l_phdr  : 0;
     auxv[1].a_type = AT_PHNUM;
@@ -1360,9 +1366,9 @@ void start_execution (const char * first_argument, const char ** arguments,
     auxv[3].a_un.a_val = exec_map ? exec_map->l_entry : 0;
     auxv[4].a_type = AT_BASE;
     auxv[4].a_un.a_val = exec_map ? exec_map->l_addr  : 0;
-    auxv[5].a_type = AT_NULL;
-
-    *(void **) &auxv[6] = NULL;
+    auxv[5].a_type = AT_RANDOM;
+    auxv[5].a_un.a_val = random;
+    auxv[6].a_type = AT_NULL;
 
 #if PROFILING == 1
     __pal_control.startup_time = _DkSystemTimeQuery() - pal_state.start_time;