Index: src/trusted/service_runtime/sel_ldr_filename.c |
diff --git a/src/trusted/service_runtime/sel_ldr_filename.c b/src/trusted/service_runtime/sel_ldr_filename.c |
index 97556b653420b7513dffa02a1c543b70ea1f68da..30aa0b62c2bf6cec6cff4f8b56e9d0a4383bfc16 100644 |
--- a/src/trusted/service_runtime/sel_ldr_filename.c |
+++ b/src/trusted/service_runtime/sel_ldr_filename.c |
@@ -44,8 +44,6 @@ static int PathContainsRootPrefix(const char *path, size_t path_len) { |
* the mounted directory) transform it into an |absolute_path|, which is an |
* absolute path prefixed by the root mount directory. |
* |
- * TODO(smklein): The virtual_path is assumed to be absolute. Change this. |
- * |
* @param[in] virtual_path Virtual path supplied by user. |
* @param[out] absolute_path The absolute path referenced by the |virtual_path|. |
* @param[in] absolute_path_size The size of the |absolute_path| buffer. |
@@ -54,20 +52,52 @@ static int PathContainsRootPrefix(const char *path, size_t path_len) { |
static uint32_t VirtualToAbsolutePath(const char *virtual_path, |
char *absolute_path, |
size_t absolute_path_max_size) { |
+ size_t cwd_path_len; |
size_t virtual_path_len = strlen(virtual_path); |
- /* Check that we have enough room to prepend the prefix (absolute case). */ |
- if (virtual_path_len + NaClRootDirLen + 1 > absolute_path_max_size) { |
- NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); |
- return -NACL_ABI_ENAMETOOLONG; |
+ absolute_path[0] = '\0'; /* Required to strcat from start of path. */ |
+ if (virtual_path[0] == '/') { |
+ /* Absolute Path = Prefix + Absolute Virtual Path + '\0' */ |
+ if (virtual_path_len + NaClRootDirLen + 1 > absolute_path_max_size) { |
+ NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); |
+ return -NACL_ABI_ENAMETOOLONG; |
+ } |
+ /* Prefix */ |
+ strcat(absolute_path, NaClRootDir); |
+ /* Prefix + Virtual Path */ |
+ strcat(absolute_path, virtual_path); |
+ } else { |
+ /* Absolute Path = Cwd + '/' + Relative Virtual Path + '\0' */ |
Mark Seaborn
2016/02/17 22:13:23
You don't actually need to do this concatenation.
Sean Klein
2016/02/17 22:42:39
Although I know it's technically not necessary now
Mark Seaborn
2016/02/18 19:32:02
So you plan to handle paths containing "..", but w
Sean Klein
2016/02/19 18:49:06
That is the short-term plan, yes.
|
+ int retval = NaClHostDescGetcwd(absolute_path, absolute_path_max_size); |
+ if (retval != 0) { |
+ NaClLog(LOG_ERROR, "NaClHostDescGetcwd failed\n"); |
+ return retval; |
+ } |
+ cwd_path_len = strlen(absolute_path); |
+ /* |
+ * The prefix cannot be mounted at the root, so we can safely assume that |
+ * the Cwd consists of some path component after "/", such as "/foo". This |
+ * means that before inserting the relative path, we must insert an |
+ * additional "/" at the end of the Cwd. |
+ */ |
+ CHECK(NaClRootDirLen > 1); |
+ CHECK(strncmp(absolute_path, NaClRootDir, NaClRootDirLen) == 0); |
+ /* |
+ * While verifying that the Cwd is inside a root (such as "/root"), ensure |
+ * that the Cwd is not only matching the prefix of the root (such as |
+ * "/root_but_not_really"). |
+ */ |
+ CHECK((absolute_path[NaClRootDirLen] == '/') || |
+ (absolute_path[NaClRootDirLen] == '\0')); |
+ if (cwd_path_len + 1 + virtual_path_len + 1 > absolute_path_max_size) { |
+ NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); |
+ return -NACL_ABI_ENAMETOOLONG; |
+ } |
+ /* Cwd + '/' */ |
+ strcat(absolute_path, "/"); |
+ /* Cwd + '/' + Relative Path */ |
+ strcat(absolute_path, virtual_path); |
} |
- /* Prefix */ |
- memcpy(absolute_path, NaClRootDir, NaClRootDirLen); |
- /* Prefix + Virtual Path */ |
- memcpy(absolute_path + NaClRootDirLen, virtual_path, virtual_path_len); |
- /* Prefix + Virtual Path + Terminator */ |
- absolute_path[virtual_path_len + NaClRootDirLen] = '\0'; |
- |
return 0; |
} |
@@ -134,17 +164,17 @@ static uint32_t CopyHostPathMounted(char *dest, size_t dest_max_size) { |
if (dest_max_size <= 0 || dest[0] == '\0') { |
NaClLog(LOG_ERROR, "Dest cannot be empty path\n"); |
return -NACL_ABI_ENOENT; |
- } else if (dest[0] != '/') { |
- /* TODO(smklein): Allow usage of relative paths. */ |
- NaClLog(LOG_ERROR, "Pathname is not absolute: %s\n", dest); |
- return -NACL_ABI_EACCES; |
} |
CHECK(dest_max_size == NACL_CONFIG_PATH_MAX); |
CHECK(strlen(dest) < NACL_CONFIG_PATH_MAX); |
strcpy(raw_path, dest); |
- /* Transform the user's raw path into an absolute path. */ |
+ /* |
+ * Transform the user's raw path into an absolute path. |
+ * The path may be either absolute or relative here -- but it will |
+ * be absolute once VirtualToAbsolutePath returns successfully. |
+ */ |
retval = VirtualToAbsolutePath(raw_path, dest, dest_max_size); |
if (retval != 0) |
return retval; |