Browse Source

[Pal] Change the way argv[0] is handled

Before argv[0] was treated specially and was changed to a value
from manifest file. Now this happens only if binary was run as
a manifest i.e. `./pal_loader path_to_manifest_file`.
borysp 4 years ago
parent
commit
9cd6b34747

+ 4 - 4
Documentation/oldwiki/Graphene-Manifest-Syntax.md

@@ -35,10 +35,10 @@ libraries must be separated by commas. The libraries must be ELF binaries.
 
     loader.execname=[STRING]
 
-This syntax specifies the executable name that will be passed as the first argument (`argv[0]`)
-to the executable. If the executable name is not specified in the manifest, the PAL will use the
-URI of the executable or the manifest -- depending on whether the executable or the manifest is
-given as the first argument to the PAL loader -- as `argv[0]` when running the executable.
+This syntax specifies an arbitrary string (typically the executable name) that will be passed as
+the first argument (argv[0]) to the executable only if it is run via the manifest
+(e.g. `./app.manifest arg1 arg2 ...`). If the string is not specified in the manifest, the PAL will
+use the path to the manifest itself (standard UNIX convention).
 
 ### Environment Variables
 

+ 4 - 4
LibOS/shim/test/regression/test_libos.py

@@ -21,14 +21,14 @@ class TC_00_Bootstrap(RegressionTestCase):
 
         # One Argument Given
         self.assertIn('# of Arguments: 1', stdout)
-        self.assertIn('argv[0] = file:bootstrap', stdout)
+        self.assertIn('argv[0] = bootstrap', stdout)
 
 
     def test_101_basic_bootstrapping_five_arguments(self):
         # Five Arguments Given
         stdout, stderr = self.run_binary(['bootstrap', 'a', 'b', 'c', 'd'])
         self.assertIn('# of Arguments: 5', stdout)
-        self.assertIn('argv[0] = file:bootstrap', stdout)
+        self.assertIn('argv[0] = bootstrap', stdout)
         self.assertIn('argv[1] = a', stdout)
         self.assertIn('argv[2] = b', stdout)
         self.assertIn('argv[3] = c', stdout)
@@ -41,14 +41,14 @@ class TC_00_Bootstrap(RegressionTestCase):
     def test_102_basic_bootstrapping_static(self):
         # bootstrap_static
         stdout, stderr = self.run_binary(['bootstrap_static'])
-        self.assertIn('Hello world (file:bootstrap_static)!', stdout)
+        self.assertIn('Hello world (bootstrap_static)!', stdout)
 
     def test_103_basic_bootstrapping_pie(self):
         # bootstrap_pie
         stdout, stderr = self.run_binary(['bootstrap_pie'])
         self.assertIn('User program started', stdout)
         self.assertIn('Local Address in Executable: 0x', stdout)
-        self.assertIn('argv[0] = file:bootstrap_pie', stdout)
+        self.assertIn('argv[0] = bootstrap_pie', stdout)
 
     def test_110_basic_bootstrapping_cxx(self):
         stdout, stderr = self.run_binary(['bootstrap-c++'])

+ 3 - 0
Pal/lib/api.h

@@ -17,6 +17,7 @@
 #ifndef API_H
 #define API_H
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdarg.h>
@@ -91,6 +92,8 @@ void * memmove (void *dstpp, const void *srcpp, size_t len);
 void * memset (void *dstpp, int c, size_t len);
 int memcmp (const void *s1, const void *s2, size_t len);
 
+bool strendswith(const char* haystack, const char* needle);
+
 /* Libc memory allocation functions. stdlib.h. */
 void *malloc(size_t size);
 void free(void *ptr);

+ 13 - 0
Pal/lib/string/strendswith.c

@@ -0,0 +1,13 @@
+#include <api.h>
+
+
+bool strendswith(const char* haystack, const char* needle) {
+    size_t haystack_len = strlen(haystack);
+    size_t needle_len = strlen(needle);
+
+    if (haystack_len < needle_len) {
+        return false;
+    }
+
+    return !memcmp(&haystack[haystack_len - needle_len], needle, needle_len);
+}

+ 1 - 1
Pal/regression/test_pal.py

@@ -50,7 +50,7 @@ class TC_01_Bootstrap(RegressionTestCase):
 
         # One Argument Given
         self.assertIn('# of Arguments: 1', stderr)
-        self.assertIn('argv[0] = file:Bootstrap', stderr)
+        self.assertIn('argv[0] = Bootstrap', stderr)
 
         # Control Block: Debug Stream (Inline)
         self.assertIn('Written to Debug Stream', stdout)

+ 8 - 12
Pal/src/db_main.c

@@ -229,8 +229,6 @@ noreturn void pal_main (
         PAL_STR *  environments      /* environment variables */
     )
 {
-    bool is_parent = (parent_process == NULL);
-
 #if PROFILING == 1
     __pal_control.host_specific_startup_time =
             _DkSystemTimeQuery() - pal_state.start_time;
@@ -395,16 +393,14 @@ noreturn void pal_main (
     pal_state.exec            = exec_uri;
     pal_state.exec_handle     = exec_handle;
 
-    const char * first_argument =
-        (is_parent && exec_uri) ? exec_uri : *arguments;
-    arguments++;
-
-    if (pal_state.root_config) {
+    if (pal_state.root_config && *arguments
+        && (strendswith(*arguments, ".manifest") || strendswith(*arguments, ".manifest.sgx"))) {
+        /* Run as a manifest file,
+         * replace argv[0] with the contents of the manifest's loader.execname */
         char cfgbuf[CONFIG_MAX];
-        ret = get_config(pal_state.root_config, "loader.execname", cfgbuf,
-                         CONFIG_MAX);
+        ret = get_config(pal_state.root_config, "loader.execname", cfgbuf, CONFIG_MAX);
         if (ret > 0)
-            first_argument = malloc_copy(cfgbuf, ret + 1);
+            *arguments = malloc_copy(cfgbuf, ret + 1);
     }
 
     read_environments(&environments);
@@ -465,12 +461,12 @@ noreturn void pal_main (
     __pal_control.manifest_loading_time
                                       = pal_state.manifest_loading_time;
     __pal_control.allocation_time     = pal_state.slab_time;
-    __pal_control.child_creation_time = is_parent ? 0 : pal_state.start_time -
+    __pal_control.child_creation_time = (parent_process == NULL) ? 0 : pal_state.start_time -
                                         pal_state.process_create_time;
 #endif
 
     /* Now we will start the execution */
-    start_execution(first_argument, arguments, environments);
+    start_execution(arguments, environments);
 
  out_fail:
     /* We wish we will never reached here */

+ 4 - 10
Pal/src/db_rtld.c

@@ -1319,9 +1319,7 @@ void * stack_before_call __attribute_unused = NULL;
 #endif
 #endif /* !CALL_ENTRY */
 
-noreturn void start_execution (const char * first_argument,
-                               const char ** arguments, const char ** environs)
-{
+noreturn void start_execution(const char** arguments, const char** environs) {
     /* First we will try to run all the preloaded libraries which come with
        entry points */
     if (exec_map) {
@@ -1334,15 +1332,13 @@ noreturn void start_execution (const char * first_argument,
 #endif
 
     int narguments = 0;
-    if (first_argument)
-        narguments++;
-    for (const char ** a = arguments; *a ; a++, narguments++);
+    for (const char** a = arguments; *a ; a++, narguments++);
 
     /* Let's count the number of cookies, first we will have argc & argv */
     int ncookies = narguments + 3; /* 1 for argc, argc + 2 for argv */
 
     /* Then we count envp */
-    for (const char ** e = environs; *e; e++)
+    for (const char** e = environs; *e; e++)
         ncookies++;
 
     ncookies++; /* for NULL-end */
@@ -1351,13 +1347,11 @@ noreturn void start_execution (const char * first_argument,
                       + sizeof(ElfW(auxv_t)) * 1  /* only AT_NULL */
                       + sizeof(void *) * 4 + 16;
 
-    unsigned long int * cookies = __alloca(cookiesz);
+    unsigned long int* cookies = __alloca(cookiesz);
     int cnt = 0;
 
     /* Let's copy the cookies */
     cookies[cnt++] = (unsigned long int) narguments;
-    if (first_argument)
-        cookies[cnt++] = (unsigned long int) first_argument;
 
     for (int i = 0 ; arguments[i] ; i++)
         cookies[cnt++] = (unsigned long int) arguments[i];

+ 1 - 2
Pal/src/pal_rtld.h

@@ -180,7 +180,6 @@ do_lookup_map (ElfW(Sym) * ref, const char * undef_name,
 void _DkDebugAddMap (struct link_map * map);
 void _DkDebugDelMap (struct link_map * map);
 
-noreturn void start_execution (const char * first_argument,
-                               const char ** arguments, const char ** environs);
+noreturn void start_execution(const char** arguments, const char** environs);
 
 #endif /* PAL_RTLD_H */