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..48bb43e399e12b8d7458974adce8ff2856585f98 100644 |
--- a/src/trusted/service_runtime/sel_ldr_filename.c |
+++ b/src/trusted/service_runtime/sel_ldr_filename.c |
@@ -41,33 +41,38 @@ static int PathContainsRootPrefix(const char *path, size_t path_len) { |
#if !NACL_WINDOWS |
/* |
* Given a |virtual_path| (a path supplied by the user with no knowledge of |
- * 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. |
+ * the mounted directory) transform it into an |real_path|, which is either |
+ * an absolute path prefixed by the root mount directory, or a relative path. |
* |
* @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. |
+ * @param[out] real_path The real path referenced by the |virtual_path|. |
+ * @param[in] real_path_size The size of the |real_path| buffer. |
* @return 0 on success, else a negated NaCl errno. |
*/ |
-static uint32_t VirtualToAbsolutePath(const char *virtual_path, |
- char *absolute_path, |
- size_t absolute_path_max_size) { |
+static uint32_t VirtualToRealPath(const char *virtual_path, |
+ char *real_path, |
+ size_t real_path_max_size) { |
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; |
+ real_path[0] = '\0'; /* Required to strcat from start of path. */ |
Mark Seaborn
2016/02/24 21:19:19
Why not just use strcpy() instead of the first cal
Sean Klein
2016/02/24 23:40:43
Done.
|
+ if (virtual_path[0] == '/') { |
+ /* Absolute Path = Prefix + Absolute Virtual Path + '\0' */ |
+ if (virtual_path_len + NaClRootDirLen + 1 > real_path_max_size) { |
+ NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); |
+ return -NACL_ABI_ENAMETOOLONG; |
+ } |
+ /* Prefix */ |
+ strcat(real_path, NaClRootDir); |
+ /* Prefix + Virtual Path */ |
+ strcat(real_path, virtual_path); |
+ } else { |
+ /* Relative Path = Relative Virtual Path + '\0' */ |
+ if (virtual_path_len + 1 > real_path_max_size) { |
+ NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); |
+ return -NACL_ABI_ENAMETOOLONG; |
+ } |
+ strcat(real_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; |
} |
@@ -84,19 +89,17 @@ static int IsSymbolicLink(const char *path) { |
} |
/* |
- * Preconditions: |
- * The path is absolute (aka, it starts with "/"). |
- * |
* @param[in] path The path to be verified. |
* @return 0 if the path is valid, else a negated NaCl errno. |
*/ |
-static uint32_t ValidateAbsolutePath(const char *path) { |
+static uint32_t ValidatePath(const char *path) { |
if (strstr(path, "..")) { |
NaClLog(LOG_ERROR, "Pathname contains ..: %s\n", path); |
return -NACL_ABI_EACCES; |
} |
- CHECK(PathContainsRootPrefix(path, strlen(path))); |
+ if (path[0] == '/') |
+ CHECK(PathContainsRootPrefix(path, strlen(path))); |
/* |
* This is an informal check, and we still require the users of sel_ldr to |
@@ -119,9 +122,9 @@ static uint32_t ValidateAbsolutePath(const char *path) { |
} |
/* |
- * Transforms a raw file path from the user into an absolute path |
- * prefixed by the mounted file system root. Also validates the path to |
- * ensure it does not access anything outside the mount point. |
+ * Transforms a raw file path from the user into an absolute path prefixed by |
+ * the mounted file system root (or leave it as a relative path). Also validates |
+ * the path to ensure it does not access anything outside the mount point. |
* |
* @param[in/out] dest The raw file path from the user |
* @param[in] dest_max_size The size of the buffer holding dest. |
@@ -134,23 +137,23 @@ 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. */ |
- retval = VirtualToAbsolutePath(raw_path, dest, dest_max_size); |
+ /* |
+ * Transform the user's raw path into the actual path. |
+ * The path will reference a file inside the mount directory once |
+ * VirtualToRealPath returns successfully. |
+ */ |
+ retval = VirtualToRealPath(raw_path, dest, dest_max_size); |
if (retval != 0) |
return retval; |
/* Verify that the path cannot escape root. */ |
- return ValidateAbsolutePath(dest); |
+ return ValidatePath(dest); |
} |
#endif /* !NACL_WINDOWS */ |