PAL should give a clearer error when the executable cannot be found. Add it, and make a unit test for this behavior.

Fix loading by manifest on the SGX PAL, and fix the unit test that should be testing this.
This commit is contained in:
Don Porter
2018-11-29 12:55:56 -08:00
committed by Chia-Che Tsai
parent 0ca3acb9dc
commit 4ebad2401e
3 changed files with 63 additions and 17 deletions
+13 -2
View File
@@ -100,10 +100,11 @@ if rv: sys.exit(rv)
# Running Bootstrap2
regression = Regression(loader, "Bootstrap2")
regression = Regression(loader, manifest_file("Bootstrap2"))
regression.add_check(name="Control Block: Manifest as Executable Name",
check=lambda res: "Loaded Manifest: file:" + manifest_file("Bootstrap2") in res[0].log)
check=lambda res: "Loaded Manifest: file:" + manifest_file("Bootstrap2") in res[0].log
and "User Program Started" in res[0].log)
rv = regression.run_checks()
if rv: sys.exit(rv)
@@ -178,3 +179,13 @@ regression.add_check(name="Load Large Number of Items in Manifest",
rv = regression.run_checks()
if rv: sys.exit(rv)
# Running an executable that doesn't exist, should at least warn you
regression = Regression(loader, "fakenews")
regression.add_check(name="Error on missing executable and manifest",
check=lambda res: "Executable not found" in res[0].log and
any([line.startswith("USAGE: ") for line in res[0].log]))
rv = regression.run_checks()
if rv: sys.exit(rv)
+49 -15
View File
@@ -667,7 +667,8 @@ finalize:
static int load_enclave (struct pal_enclave * enclave,
const char * manifest_uri,
const char * exec_uri,
const char ** arguments, const char ** environments)
const char ** arguments, const char ** environments,
bool exec_uri_inferred)
{
struct pal_sec * pal_sec = &enclave->pal_sec;
int ret;
@@ -726,13 +727,15 @@ static int load_enclave (struct pal_enclave * enclave,
return -EINVAL;
}
if (exec_uri == NULL) {
if (get_config(enclave->config, "loader.exec", cfgbuf, CONFIG_MAX) > 0) {
exec_uri = resolve_uri(cfgbuf, &errstring);
if (!exec_uri) {
SGX_DBG(DBG_E, "%s: %s\n", errstring, cfgbuf);
return -EINVAL;
}
// A manifest can specify an executable with a different base name
// than the manifest itself. Always give the exec field of the manifest
// precedence if specified.
if (get_config(enclave->config, "loader.exec", cfgbuf, CONFIG_MAX) > 0) {
exec_uri = resolve_uri(cfgbuf, &errstring);
exec_uri_inferred = false;
if (!exec_uri) {
SGX_DBG(DBG_E, "%s: %s\n", errstring, cfgbuf);
return -EINVAL;
}
}
@@ -741,8 +744,18 @@ static int load_enclave (struct pal_enclave * enclave,
exec_uri + static_strlen("file:"),
O_RDONLY|O_CLOEXEC, 0);
if (IS_ERR(enclave->exec)) {
SGX_DBG(DBG_E, "cannot open executable %s\n", exec_uri);
return -EINVAL;
if (exec_uri_inferred) {
// It is valid for an enclave not to have an executable.
// We need to catch the case where we inferred the executable
// 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);
enclave->exec = -1;
} else {
SGX_DBG(DBG_E, "cannot open executable %s\n", exec_uri);
return -EINVAL;
}
}
} else {
enclave->exec = -1;
@@ -843,9 +856,13 @@ static int load_enclave (struct pal_enclave * enclave,
int main (int argc, const char ** argv, const char ** envp)
{
const char * manifest_uri = NULL, * exec_uri = NULL;
const char * manifest_uri = NULL;
char * exec_uri = NULL;
const char * pal_loader = argv[0];
int retval = -EINVAL;
bool exec_uri_inferred = false; // Handle the case where the exec uri is
// inferred from the manifest name somewhat
// differently
argc--;
argv++;
@@ -879,6 +896,8 @@ int main (int argc, const char ** argv, const 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;
}
@@ -905,8 +924,19 @@ int main (int argc, const char ** argv, const char ** envp)
}
if (memcmp(filebuf, "\177ELF", 4)) {
manifest_uri = exec_uri;
exec_uri = NULL;
// In this case the manifest is given as the executable. Set
// manifest_uri to sgx_manifest (should be the same), and
// and drop the .manifest* from exec_uri, so that the program
// loads properly.
manifest_uri = sgx_manifest;
size_t exec_len = strlen(exec_uri);
if (strcmp_static(exec_uri + exec_len - strlen(".manifest"), ".manifest")) {
exec_uri[exec_len - strlen(".manifest")] = '\0';
exec_uri_inferred = true;
} else if (strcmp_static(exec_uri + exec_len - strlen(".manifest.sgx"), ".manifest.sgx")) {
exec_uri[exec_len - strlen(".manifest.sgx")] = '\0';
exec_uri_inferred = true;
}
}
fd = INLINE_SYSCALL(open, 3, sgx_manifest, O_RDONLY|O_CLOEXEC, 0);
@@ -920,8 +950,12 @@ int main (int argc, const char ** argv, const char ** envp)
}
SGX_DBG(DBG_I, "manifest file: %s\n", manifest_uri);
if (exec_uri)
SGX_DBG(DBG_I, "executable file: %s\n", exec_uri);
else
SGX_DBG(DBG_I, "executable file not found\n");
return load_enclave(enclave, manifest_uri, exec_uri, argv, envp);
return load_enclave(enclave, manifest_uri, exec_uri, argv, envp, exec_uri_inferred);
usage:
SGX_DBG(DBG_E, "USAGE: %s [executable|manifest] args ...\n", pal_loader);
@@ -949,5 +983,5 @@ int pal_init_enclave (const char * manifest_uri,
memset(enclave, 0, sizeof(struct pal_enclave));
return load_enclave(enclave, manifest_uri, exec_uri,
arguments, environments);
arguments, environments, 0);
}
+1
View File
@@ -281,6 +281,7 @@ void pal_linux_main (void * args)
done_init:
if (!parent && !exec && !manifest) {
printf("Executable not found\n");
printf("USAGE: %s [executable|manifest] args ...\n", pal_name);
_DkProcessExit(0);
return;