Browse Source

[Pal/Linux-SGX] Add manifest option sgx.enclave_pal_file

Path to enclave file had been a fixed string that is determined at
build time. Therefore Runtime binares were not allowed to move
their location. This commit adds sgx.enclave_pal_file manifest
option to specify the uri of libpal-Linux-SGX.so.
Yunjong Jeong 4 years ago
parent
commit
9df502b4ab

+ 2 - 0
LibOS/shim/test/native/manifest.template

@@ -20,6 +20,8 @@ net.allow_bind.1 = 127.0.0.1:8000
 net.allow_peer.1 = 127.0.0.1:8000
 
 # sgx-related
+sgx.enclave_pal_file = file:$(LIBCDIR)/libpal-Linux-SGX.so
+
 sgx.trusted_files.ld = file:$(LIBCDIR)/ld-linux-x86-64.so.2
 sgx.trusted_files.libc = file:$(LIBCDIR)/libc.so.6
 sgx.trusted_files.libdl = file:$(LIBCDIR)/libdl.so.2

+ 1 - 1
Pal/src/host/Linux-SGX/db_main.c

@@ -243,7 +243,7 @@ void pal_linux_main(char * uptr_args, uint64_t args_size,
 
     /* relocate PAL itself */
     pal_map.l_addr = elf_machine_load_address();
-    pal_map.l_name = ENCLAVE_FILENAME;
+    pal_map.l_name = ENCLAVE_PAL_FILENAME;
     elf_get_dynamic_info((void *) pal_map.l_addr + elf_machine_dynamic(),
                          pal_map.l_info, pal_map.l_addr);
 

+ 1 - 1
Pal/src/host/Linux-SGX/pal_linux.h

@@ -35,7 +35,7 @@
 # include "sysdep-x86_64.h"
 #endif
 
-#define ENCLAVE_FILENAME RUNTIME_FILE("libpal-Linux-SGX.so")
+#define ENCLAVE_PAL_FILENAME RUNTIME_FILE("libpal-Linux-SGX.so")
 
 #define IS_ERR INTERNAL_SYSCALL_ERROR
 #define IS_ERR_P INTERNAL_SYSCALL_ERROR_P

+ 24 - 6
Pal/src/host/Linux-SGX/sgx_main.c

@@ -234,7 +234,8 @@ int load_enclave_binary (sgx_arch_secs_t * secs, int fd,
 int initialize_enclave (struct pal_enclave * enclave)
 {
     int ret = 0;
-    int                    enclave_image;
+    int                    enclave_image = -1;
+    char*                  enclave_uri = NULL;
     sgx_arch_token_t       enclave_token;
     sgx_arch_enclave_css_t enclave_sigstruct;
     sgx_arch_secs_t        enclave_secs;
@@ -244,15 +245,31 @@ int initialize_enclave (struct pal_enclave * enclave)
     /* this array may overflow the stack, so we allocate it in BSS */
     static void* tcs_addrs[MAX_DBG_THREADS];
 
-    enclave_image = INLINE_SYSCALL(open, 3, ENCLAVE_FILENAME, O_RDONLY, 0);
+    char cfgbuf[CONFIG_MAX];
+    const char* errstring = "out of memory";
+
+    /* Use sgx.enclave_pal_file from manifest if exists */
+    if (get_config(enclave->config, "sgx.enclave_pal_file", cfgbuf, sizeof(cfgbuf)) > 0) {
+        enclave_uri = resolve_uri(cfgbuf, &errstring);
+    } else {
+        enclave_uri = alloc_concat(URI_PREFIX_FILE, URI_PREFIX_FILE_LEN, ENCLAVE_PAL_FILENAME, -1);
+    }
+
+    if (!enclave_uri) {
+        SGX_DBG(DBG_E,
+                "Cannot open in-enclave PAL: %s (incorrect sgx.enclave_pal_file in manifest?)\n",
+                errstring);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    enclave_image = INLINE_SYSCALL(open, 3, enclave_uri + URI_PREFIX_FILE_LEN, O_RDONLY, 0);
     if (IS_ERR(enclave_image)) {
-        SGX_DBG(DBG_E, "Cannot find %s\n", ENCLAVE_FILENAME);
+        SGX_DBG(DBG_E, "Cannot find enclave image: %s\n", enclave_uri);
         ret = -ERRNO(enclave_image);
         goto out;
     }
 
-    char cfgbuf[CONFIG_MAX];
-
     /* Reading sgx.enclave_size from manifest */
     if (get_config(enclave->config, "sgx.enclave_size", cfgbuf, sizeof(cfgbuf)) <= 0) {
         SGX_DBG(DBG_E, "Enclave size is not specified\n");
@@ -384,7 +401,7 @@ int initialize_enclave (struct pal_enclave * enclave)
 
     ret = scan_enclave_binary(enclave_image, &pal_area->addr, &pal_area->size, &enclave_entry_addr);
     if (ret < 0) {
-        SGX_DBG(DBG_E, "Scanning Pal binary (%s) failed: %d\n", ENCLAVE_FILENAME, -ret);
+        SGX_DBG(DBG_E, "Scanning Pal binary (%s) failed: %d\n", enclave_uri, -ret);
         goto out;
     }
 
@@ -573,6 +590,7 @@ int initialize_enclave (struct pal_enclave * enclave)
 out:
     if (enclave_image >= 0)
         INLINE_SYSCALL(close, 1, enclave_image);
+    free(enclave_uri);
 
     return ret;
 }

+ 26 - 16
Pal/src/host/Linux-SGX/signer/pal-sgx-sign

@@ -89,17 +89,8 @@ def read_manifest(filename):
 def exec_sig_manifest(args, manifest):
     if 'exec' not in args or args.get('depend'):
         if 'loader.exec' in manifest:
-            exec_url = manifest['loader.exec']
-            if not exec_url.startswith('file:'):
-                print("executable must be a local file", file=sys.stderr)
-                return 1
-
-            exec_path = exec_url[5:]  # strip preceding 'file:'
-            if os.path.isabs(exec_path):
-                args['exec'] = exec_path
-            else:
-                args['exec'] = os.path.join(
-                    os.path.dirname(args['manifest']), exec_path)
+            args['exec'] = resolve_manifest_uri(args['manifest'],
+                    manifest['loader.exec'])
 
     if 'sgx.sigfile' in manifest:
         args['sigfile'] = resolve_uri(manifest['sgx.sigfile'],
@@ -113,6 +104,14 @@ def exec_sig_manifest(args, manifest):
         args['sigfile'] = sigfile + '.sig'
         manifest['sgx.sigfile'] = 'file:' + os.path.basename(args['sigfile'])
 
+    if args.get('libpal', None) is None:
+        if 'sgx.enclave_pal_file' in manifest:
+            args['libpal'] = resolve_manifest_uri(args['manifest'],
+                    manifest['sgx.enclave_pal_file'])
+        else:
+            print("Either --libpal or sgx.enclave_pal_file must be given", file=sys.stderr)
+            return 1
+
     return 0
 
 
@@ -211,7 +210,7 @@ def get_enclave_attributes(manifest):
 def resolve_uri(uri, check_exist=True):
     orig_uri = uri
     if uri.startswith('file:'):
-        target = os.path.normpath(uri[5:])
+        target = os.path.normpath(uri[len('file:'):])
     else:
         target = os.path.normpath(uri)
     if check_exist and not os.path.exists(target):
@@ -219,6 +218,14 @@ def resolve_uri(uri, check_exist=True):
             'Cannot resolve ' + orig_uri + ' or the file does not exist.')
     return target
 
+# Resolve an URI relative to manifest file to its absolute path
+def resolve_manifest_uri(manifest_path, uri):
+    if not uri.startswith('file:'):
+        raise Exception('URI ' + uri + ' is not a local file')
+    path = uri[len('file:'):]
+    if os.path.isabs(path):
+        return path
+    return os.path.join(os.path.dirname(manifest_path), path)
 
 def get_checksum(filename):
     digest = hashlib.sha256()
@@ -736,7 +743,9 @@ def generate_sigstruct(attr, args, mrenclave):
 # Main Program
 
 argparser = argparse.ArgumentParser(
-    epilog='With sign mode(without -depend), libpal and key are also required')
+    epilog='With sign mode(without -depend), libpal and key are also required. '
+           'exec and libpal may be given through manifest options '
+           'loader.exec and sgx.enclave_pal_file.')
 argparser.add_argument('--output', '-output', metavar='OUTPUT',
                        type=str, required=True,
                        help='Output .manifest.sgx file '
@@ -774,9 +783,9 @@ def parse_args(args):
     if args.depend:
         args_dict['depend'] = True
     else:
-        # libpal and key are required
-        if args.libpal is None or args.key is None:
-            argparser.error("libpal and key are also required to sign")
+        # key is required and not found in manifest
+        if args.key is None:
+            argparser.error("a key is required to sign")
             return None
 
     return args_dict
@@ -902,6 +911,7 @@ def make_depend(args):
     for filename in get_trusted_children(manifest, check_exist=False,
                                          do_checksum=False).values():
         dependencies.add(filename[1])
+    dependencies.add(args['libpal'])
 
     with open(output, 'w') as file:
         manifest_sgx = output