| 
					
				 | 
			
			
				@@ -76,7 +76,7 @@ static unsigned long parse_int (const char * str) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return num; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static const char * resolve_uri (const char * uri, const char ** errstring) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static char * resolve_uri (const char * uri, const char ** errstring) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (!strpartcmp_static(uri, "file:")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         *errstring = "Invalid URI"; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -227,7 +227,7 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int                  enclave_image; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int                  enclave_image = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int                  enclave_thread_num = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sgx_arch_token_t     enclave_token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sgx_arch_sigstruct_t enclave_sigstruct; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -236,37 +236,27 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     void *               tcs_addrs[MAX_DBG_THREADS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     unsigned long        heap_min = DEAFULT_HEAP_MIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define TRY(func, ...)                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ({                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ret = (func)(__VA_ARGS__);                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ret < 0) {                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            SGX_DBG(DBG_E, "initializing enclave failed: " #func ": %d\n",  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   -ret);                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return ret;                                             \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } ret;                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave_image = INLINE_SYSCALL(open, 3, ENCLAVE_FILENAME, O_RDONLY, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR(enclave_image)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "cannot find %s\n", ENCLAVE_FILENAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -ERRNO(ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot find %s\n", ENCLAVE_FILENAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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, CONFIG_MAX) <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "enclave_size is not specified\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Enclave size is not specified\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave->size = parse_int(cfgbuf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* DEP 1/21/17: SGX currently only supports power-of-two enclaves. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Give users a better warning about this. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (enclave->size & (enclave->size - 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "Enclave size not a power of two.  SGX requires power-of-two enclaves.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Enclave size not a power of two (an SGX-imposed requirement)\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Reading sgx.thread_num from manifest */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -275,21 +265,33 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (enclave_thread_num > MAX_DBG_THREADS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SGX_DBG(DBG_E, "Too many threads to debug\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Reading sgx.static_address from manifest */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (get_config(enclave->config, "sgx.static_address", cfgbuf, CONFIG_MAX) > 0 && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cfgbuf[0] == '1') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (get_config(enclave->config, "sgx.static_address", cfgbuf, CONFIG_MAX) > 0 && cfgbuf[0] == '1') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         enclave->baseaddr = heap_min; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         enclave->baseaddr = heap_min = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    TRY(read_enclave_token, enclave->token, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    TRY(read_enclave_sigstruct, enclave->sigfile, &enclave_sigstruct); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = read_enclave_token(enclave->token, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Reading enclave token failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    TRY(create_enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        &enclave_secs, enclave->baseaddr, enclave->size, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = read_enclave_sigstruct(enclave->sigfile, &enclave_sigstruct); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Reading enclave sigstruct failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = create_enclave(&enclave_secs, enclave->baseaddr, enclave->size, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Creating enclave failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave->baseaddr = enclave_secs.baseaddr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave->size = enclave_secs.size; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -297,8 +299,11 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     struct stat stat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = INLINE_SYSCALL(fstat, 2, enclave->manifest, &stat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (IS_ERR(ret)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -ERRNO(ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (IS_ERR(ret)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Reading manifest file's size failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -ERRNO(ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int manifest_size = stat.st_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Start populating enclave memory */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -315,53 +320,74 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         __alloca(sizeof(areas[0]) * (10 + enclave->thread_num)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int area_num = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define SET_AREA(_desc, _skip_eextend, _is_binary, _fd, _addr, _size, _prot, _type) \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ({                                                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        struct mem_area* _a = &areas[area_num++];        \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->desc            = (_desc);                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->skip_eextend    = (_skip_eextend);           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->is_binary       = (_is_binary);              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->fd              = (_fd);                     \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->addr            = (_addr);                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->size            = (_size);                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->prot            = (_prot);                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a->type            = (_type);                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _a;                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* The manifest needs to be allocated at the upper end of the enclave 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * memory. That's used by pal_linux_main to find the manifest area. So add 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * it first to the list with memory areas. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SET_AREA("manifest", false, false, enclave->manifest, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             0, ALLOC_ALIGNUP(manifest_size), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             PROT_READ, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * ssa_area = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("ssa", false, false, -1, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 enclave->thread_num * enclave->ssaframesize * SSAFRAMENUM, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 PROT_READ|PROT_WRITE, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * tcs_area = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("tcs", false, false, -1, 0, enclave->thread_num * pagesize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 0, SGX_PAGE_TCS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * tls_area = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("tls", false, false, -1, 0, enclave->thread_num * pagesize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 PROT_READ|PROT_WRITE, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * stack_areas = &areas[area_num]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (uint32_t t = 0 ; t < enclave->thread_num ; t++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("stack", false, false, -1, 0, ENCLAVE_STACK_SIZE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 PROT_READ|PROT_WRITE, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * pal_area = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("pal", false, true, enclave_image, 0, 0, 0, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    TRY(scan_enclave_binary, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        enclave_image, &pal_area->addr, &pal_area->size, &enclave_entry_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    struct mem_area * exec_area = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .desc = "manifest", .skip_eextend = false, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .fd = enclave->manifest, .addr = 0, .size = ALLOC_ALIGNUP(manifest_size), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .prot = PROT_READ, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    area_num++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .desc = "ssa", .skip_eextend = false, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .fd = -1, .addr = 0, .size = enclave->thread_num * enclave->ssaframesize * SSAFRAMENUM, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .prot = PROT_READ | PROT_WRITE, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* ssa_area = &areas[area_num++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .desc = "tcs", .skip_eextend = false, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .fd = -1, .addr = 0, .size = enclave->thread_num * pagesize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .prot = 0, .type = SGX_PAGE_TCS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* tcs_area = &areas[area_num++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .desc = "tls", .skip_eextend = false, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .fd = -1, .addr = 0, .size = enclave->thread_num * pagesize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .prot = PROT_READ | PROT_WRITE, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* tls_area = &areas[area_num++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* stack_areas = &areas[area_num]; /* memorize for later use */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (uint32_t t = 0; t < enclave->thread_num; t++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .desc = "stack", .skip_eextend = false, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .fd = -1, .addr = 0, .size = ENCLAVE_STACK_SIZE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .prot = PROT_READ | PROT_WRITE, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        area_num++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .desc = "pal", .skip_eextend = false, .is_binary = true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .fd = enclave_image, .addr = 0, .size = 0 /* set below */, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .prot = 0, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* pal_area = &areas[area_num++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct mem_area* exec_area = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (enclave->exec != -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        exec_area = SET_AREA("exec", false, true, enclave->exec, 0, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             PROT_WRITE, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        TRY(scan_enclave_binary, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            enclave->exec, &exec_area->addr, &exec_area->size, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .desc = "exec", .skip_eextend = false, .is_binary = true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .fd = enclave->exec, .addr = 0, .size = 0 /* set below */, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .prot = PROT_WRITE, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        exec_area = &areas[area_num++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = scan_enclave_binary(enclave->exec, &exec_area->addr, &exec_area->size, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SGX_DBG(DBG_E, "Scanning application binary failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     unsigned long populating = enclave->size; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -378,16 +404,24 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave_entry_addr += pal_area->addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (exec_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (exec_area->addr + exec_area->size > pal_area->addr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (exec_area->addr + exec_area->size > pal_area->addr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SGX_DBG(DBG_E, "Application binary overlaps with Pal binary\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (exec_area->addr + exec_area->size < populating) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (populating > heap_min) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 unsigned long addr = exec_area->addr + exec_area->size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (addr < heap_min) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     addr = heap_min; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                SET_AREA("free", true, false, -1, addr, populating - addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         PROT_READ|PROT_WRITE|PROT_EXEC, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .desc = "free", .skip_eextend = true, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .fd = -1, .addr = addr, .size = populating - addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .prot = PROT_READ | PROT_WRITE | PROT_EXEC, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                area_num++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             populating = exec_area->addr; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -395,14 +429,21 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (populating > heap_min) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SET_AREA("free", true, false, -1, heap_min, populating - heap_min, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 PROT_READ|PROT_WRITE|PROT_EXEC, SGX_PAGE_REG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        areas[area_num] = (struct mem_area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .desc = "free", .skip_eextend = true, .is_binary = false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .fd = -1, .addr = heap_min, .size = populating - heap_min, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .prot = PROT_READ | PROT_WRITE | PROT_EXEC, .type = SGX_PAGE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        area_num++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (int i = 0 ; i < area_num ; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (areas[i].fd != -1 && areas[i].is_binary) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            TRY(load_enclave_binary, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                &enclave_secs, areas[i].fd, areas[i].addr, areas[i].prot); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ret = load_enclave_binary(&enclave_secs, areas[i].fd, areas[i].addr, areas[i].prot); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_E, "Loading enclave binary failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -412,6 +453,11 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             data = (void *) INLINE_SYSCALL(mmap, 6, NULL, areas[i].size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            PROT_READ|PROT_WRITE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (data == (void *)-1 || data == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                /* Note that Graphene currently doesn't handle 0x0 addresses */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_E, "Allocating memory for tls pages failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (uint32_t t = 0 ; t < enclave->thread_num ; t++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 struct enclave_tls * gs = data + pagesize * t; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -436,6 +482,11 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             data = (void *) INLINE_SYSCALL(mmap, 6, NULL, areas[i].size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            PROT_READ|PROT_WRITE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (data == (void *)-1 || data == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                /* Note that Graphene currently doesn't handle 0x0 addresses */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_E, "Allocating memory for tcs pages failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (uint32_t t = 0 ; t < enclave->thread_num ; t++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 sgx_arch_tcs_t * tcs = data + pagesize * t; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -451,22 +502,35 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 tcs_addrs[t] = (void *) enclave_secs.baseaddr + tcs_area->addr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     + pagesize * t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (areas[i].fd != -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (areas[i].fd != -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             data = (void *) INLINE_SYSCALL(mmap, 6, NULL, areas[i].size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            PROT_READ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            MAP_FILE|MAP_PRIVATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            areas[i].fd, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (data == (void *)-1 || data == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                /* Note that Graphene currently doesn't handle 0x0 addresses */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_E, "Allocating memory for file %s failed\n", areas[i].desc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        TRY(add_pages_to_enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &enclave_secs, (void *) areas[i].addr, data, areas[i].size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            areas[i].type, areas[i].prot, areas[i].skip_eextend, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            areas[i].desc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = add_pages_to_enclave(&enclave_secs, (void *) areas[i].addr, data, areas[i].size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                areas[i].type, areas[i].prot, areas[i].skip_eextend, areas[i].desc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             INLINE_SYSCALL(munmap, 2, data, areas[i].size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SGX_DBG(DBG_E, "Adding pages (%s) to enclave failed: %d\n", areas[i].desc, -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    TRY(init_enclave, &enclave_secs, &enclave_sigstruct, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = init_enclave(&enclave_secs, &enclave_sigstruct, &enclave_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Initializing enclave failed: %d\n", -ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     create_tcs_mapper((void *) enclave_secs.baseaddr + tcs_area->addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                       enclave->thread_num); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -478,22 +542,25 @@ int initialize_enclave (struct pal_enclave * enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            -1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR_P(dbg)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "Cannot allocate debug info\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot allocate debug information (GDB will not work)\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->pid = INLINE_SYSCALL(getpid, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->base = enclave->baseaddr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->size = enclave->size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->ssaframesize = enclave->ssaframesize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->aep  = async_exit_pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dbg->thread_tids[0] = dbg->pid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0 ; i < MAX_DBG_THREADS ; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dbg->tcs_addrs[i] = tcs_addrs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->pid = INLINE_SYSCALL(getpid, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->base = enclave->baseaddr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->size = enclave->size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->ssaframesize = enclave->ssaframesize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->aep  = async_exit_pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dbg->thread_tids[0] = dbg->pid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (int i = 0 ; i < MAX_DBG_THREADS ; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dbg->tcs_addrs[i] = tcs_addrs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#undef SET_AREA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#undef TRY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave_image >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(close, 1, enclave_image); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static int mcast_s (int port) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -587,24 +654,26 @@ static void create_instance (struct pal_sec * pal_sec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int load_manifest (int fd, struct config_store ** config_ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int retval = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int nbytes = INLINE_SYSCALL(lseek, 3, fd, 0, SEEK_END); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (IS_ERR(nbytes)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int nbytes = INLINE_SYSCALL(lseek, 3, fd, 0, SEEK_END); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (IS_ERR(nbytes)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot detect size of manifest file\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -ERRNO(nbytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     struct config_store * config = malloc(sizeof(struct config_store)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Not enough memory for config_store of manifest\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -ENOMEM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     void * config_raw = (void *) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            INLINE_SYSCALL(mmap, 6, NULL, nbytes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           PROT_READ, MAP_PRIVATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           fd, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(mmap, 6, NULL, nbytes, PROT_READ, MAP_PRIVATE, fd, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR_P(config_raw)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        retval = -ERRNO_P(config_raw); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot mmap manifest file\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -ERRNO_P(config_raw); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     config->raw_data = config_raw; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -613,30 +682,28 @@ int load_manifest (int fd, struct config_store ** config_ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     config->free     = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char * errstring = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int ret = read_config(config, NULL, &errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = read_config(config, NULL, &errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "can't read manifest: %s\n", errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        retval = ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot read manifest: %s\n", errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *config_ptr = config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-finalize: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        free(config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!IS_ERR_P(config_raw)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        INLINE_SYSCALL(munmap, 2, config_raw, nbytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            free(config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!IS_ERR_P(config_raw)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            INLINE_SYSCALL(munmap, 2, config_raw, nbytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return retval; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         const char * manifest_uri, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         const char * exec_uri, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         char * manifest_uri, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         char * exec_uri, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                          char * args, size_t args_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                          char * env, size_t env_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                          bool exec_uri_inferred) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -669,7 +736,7 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     size_t env_i = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while (env_i < env_size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (strcmp_static(&env[env_i], "IN_GDB=1")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            SGX_DBG(DBG_I, "being GDB'ed!!!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SGX_DBG(DBG_I, "[ Running under GDB ]\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             pal_sec->in_gdb = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -689,13 +756,13 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     enclave->manifest = INLINE_SYSCALL(open, 3, manifest_uri + 5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR(enclave->manifest)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         SGX_DBG(DBG_E, "cannot open manifest %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         SGX_DBG(DBG_E, "Cannot open manifest %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = load_manifest(enclave->manifest, &enclave->config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "invalid manifest: %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Invalid manifest: %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -722,10 +789,13 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // from the manifest file name, but it doesn't exist, and let 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // the enclave go a bit further.  Go ahead and warn the user, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // though. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                SGX_DBG(DBG_I, "Inferred executable cannot be opened: %s.  This may be ok, or may represent a manifest misconfiguration. This typically represents advanced usage, and if it is not what you intended, try setting the loader.exec field in the manifest.\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_I, "Inferred executable cannot be opened: %s.  This may be ok, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "or may represent a manifest misconfiguration. This typically " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "represents advanced usage, and if it is not what you intended, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "try setting the loader.exec field in the manifest.\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 enclave->exec = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                SGX_DBG(DBG_E, "cannot open executable %s\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SGX_DBG(DBG_E, "Cannot open executable %s\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -734,40 +804,45 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (get_config(enclave->config, "sgx.sigfile", cfgbuf, CONFIG_MAX) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "sigstruct file not found. Must have \'sgx.sigfile\' in the manifest\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Sigstruct file not found ('sgx.sigfile' must be specified in manifest)\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const char * uri = resolve_uri(cfgbuf, &errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!uri) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char * sig_uri = resolve_uri(cfgbuf, &errstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!sig_uri) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SGX_DBG(DBG_E, "%s: %s\n", errstring, cfgbuf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!strcmp_static(uri + strlen(uri) - 4, ".sig")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!strcmp_static(sig_uri + strlen(sig_uri) - 4, ".sig")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SGX_DBG(DBG_E, "Invalid sigstruct file URI as %s\n", cfgbuf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(sig_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    enclave->sigfile = INLINE_SYSCALL(open, 3, uri + 5, O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enclave->sigfile = INLINE_SYSCALL(open, 3, sig_uri + 5, O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR(enclave->sigfile)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "cannot open sigstruct file %s\n", uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot open sigstruct file %s\n", sig_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(sig_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    uri = alloc_concat(uri, strlen(uri) - 4, ".token", -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    enclave->token = INLINE_SYSCALL(open, 3, uri + 5, O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char * token_uri = alloc_concat(sig_uri, strlen(sig_uri) - 4, ".token", -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    free(sig_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enclave->token = INLINE_SYSCALL(open, 3, token_uri + 5, O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR(enclave->token)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "cannot open token \'%s\'. Use \'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot open token \'%s\'. Use \'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 PAL_FILE("pal-sgx-get-token") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                "\' on the runtime host, or run \'make SGX_RUN=1\' " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                "in the Graphene source, to create the token file.\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "\' on the runtime host or run \'make SGX_RUN=1\' " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "in the Graphene source to create the token file.\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                token_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(token_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SGX_DBG(DBG_I, "token file: %s\n", uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SGX_DBG(DBG_I, "Token file: %s\n", token_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    free(token_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* Initialize the enclave */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = initialize_enclave(enclave); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (ret < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return ret; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -799,7 +874,6 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* setup signal handling */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = sgx_signal_setup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (ret < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return ret; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -823,10 +897,10 @@ static int load_enclave (struct pal_enclave * enclave, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const char * manifest_uri = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char * manifest_uri = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char * exec_uri = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char * pal_loader = argv[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int retval = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     bool exec_uri_inferred = false; // Handle the case where the exec uri is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     // inferred from the manifest name somewhat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     // differently 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -841,8 +915,8 @@ int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int is_child = sgx_init_child_process(&enclave->pal_sec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (is_child < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        retval = is_child; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = is_child; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (!is_child) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -864,14 +938,12 @@ int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int fd = INLINE_SYSCALL(open, 3, exec_uri + 5, O_RDONLY|O_CLOEXEC, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (IS_ERR(fd)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SGX_DBG(DBG_E, "Executable not found\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "USAGE: <pal> [executable|manifest] args ...\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        retval = -ERRNO(fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto usage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char filebuf[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* check if the first argument is a executable. If it is, try finding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-       all the possible manifest files */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Check if the first argument is a executable. If it is, try finding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       all the possible manifest files. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     INLINE_SYSCALL(read, 3, fd, filebuf, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     INLINE_SYSCALL(close, 1, fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -879,8 +951,8 @@ int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int len = get_base_name(exec_uri + static_strlen("file:"), sgx_manifest, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             URI_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (len < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        retval = len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (strcmp_static(sgx_manifest + len - strlen(".manifest"), ".manifest")) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -912,15 +984,15 @@ int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     sgx_manifest, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         INLINE_SYSCALL(close, 1, fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if (!manifest_uri) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_E, "cannot open manifest file: %s\n", sgx_manifest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_E, "Cannot open manifest file: %s\n", sgx_manifest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto usage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SGX_DBG(DBG_I, "manifest file: %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SGX_DBG(DBG_I, "Manifest file: %s\n", manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (exec_uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_I, "executable file: %s\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_I, "Executable file: %s\n", exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SGX_DBG(DBG_I, "executable file not found\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SGX_DBG(DBG_I, "Executable file not found\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * While C does not guarantee that the argv[i] and envp[i] strings are 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -938,18 +1010,29 @@ int main (int argc, char ** argv, char ** envp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     size_t env_size = envc > 0 ? (envp[envc - 1] - envp[0]) + strlen(envp[envc - 1]) + 1: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return load_enclave(enclave, manifest_uri, exec_uri, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        args, args_size, env, env_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        exec_uri_inferred); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = load_enclave(enclave, manifest_uri, exec_uri, args, args_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            env, env_size, exec_uri_inferred); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave->manifest >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(close, 1, enclave->manifest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave->exec >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(close, 1, enclave->exec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave->sigfile >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(close, 1, enclave->sigfile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave->token >= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        INLINE_SYSCALL(close, 1, enclave->token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enclave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(enclave); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (exec_uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(exec_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (manifest_uri && manifest_uri != sgx_manifest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        free(manifest_uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 usage: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     SGX_DBG(DBG_E, "USAGE: %s [executable|manifest] args ...\n", pal_loader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    retval = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    goto finalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-finalize: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (enclave) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        free(enclave); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return retval; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |