 Chromium Code Reviews
 Chromium Code Reviews Issue 1690983004:
  Extended restricted filesystem to support relative paths.  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
    
  
    Issue 1690983004:
  Extended restricted filesystem to support relative paths.  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (c) 2016 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2016 The Native Client Authors. All rights reserved. | 
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be | 
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. | 
| 5 */ | 5 */ | 
| 6 | 6 | 
| 7 #include "native_client/src/trusted/service_runtime/sel_ldr_filename.h" | 7 #include "native_client/src/trusted/service_runtime/sel_ldr_filename.h" | 
| 8 | 8 | 
| 9 #include <errno.h> | 9 #include <errno.h> | 
| 10 #include <string.h> | 10 #include <string.h> | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 return 0; | 37 return 0; | 
| 38 return 1; | 38 return 1; | 
| 39 } | 39 } | 
| 40 | 40 | 
| 41 #if !NACL_WINDOWS | 41 #if !NACL_WINDOWS | 
| 42 /* | 42 /* | 
| 43 * Given a |virtual_path| (a path supplied by the user with no knowledge of | 43 * Given a |virtual_path| (a path supplied by the user with no knowledge of | 
| 44 * the mounted directory) transform it into an |absolute_path|, which is an | 44 * the mounted directory) transform it into an |absolute_path|, which is an | 
| 45 * absolute path prefixed by the root mount directory. | 45 * absolute path prefixed by the root mount directory. | 
| 46 * | 46 * | 
| 47 * TODO(smklein): The virtual_path is assumed to be absolute. Change this. | |
| 48 * | |
| 49 * @param[in] virtual_path Virtual path supplied by user. | 47 * @param[in] virtual_path Virtual path supplied by user. | 
| 50 * @param[out] absolute_path The absolute path referenced by the |virtual_path|. | 48 * @param[out] absolute_path The absolute path referenced by the |virtual_path|. | 
| 51 * @param[in] absolute_path_size The size of the |absolute_path| buffer. | 49 * @param[in] absolute_path_size The size of the |absolute_path| buffer. | 
| 52 * @return 0 on success, else a negated NaCl errno. | 50 * @return 0 on success, else a negated NaCl errno. | 
| 53 */ | 51 */ | 
| 54 static uint32_t VirtualToAbsolutePath(const char *virtual_path, | 52 static uint32_t VirtualToAbsolutePath(const char *virtual_path, | 
| 55 char *absolute_path, | 53 char *absolute_path, | 
| 56 size_t absolute_path_max_size) { | 54 size_t absolute_path_max_size) { | 
| 55 size_t cwd_path_len; | |
| 57 size_t virtual_path_len = strlen(virtual_path); | 56 size_t virtual_path_len = strlen(virtual_path); | 
| 58 /* Check that we have enough room to prepend the prefix (absolute case). */ | 57 if (virtual_path[0] == '/') { | 
| 59 if (virtual_path_len + NaClRootDirLen + 1 > absolute_path_max_size) { | 58 /* Absolute Path = Prefix + Absolute Virtual Path + '\0' */ | 
| 60 NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); | 59 if (virtual_path_len + NaClRootDirLen + 1 > absolute_path_max_size) { | 
| 61 return -NACL_ABI_ENAMETOOLONG; | 60 NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); | 
| 61 return -NACL_ABI_ENAMETOOLONG; | |
| 62 } | |
| 63 /* Prefix */ | |
| 64 memcpy(absolute_path, NaClRootDir, NaClRootDirLen); | |
| 65 /* Prefix + Virtual Path */ | |
| 66 memcpy(absolute_path + NaClRootDirLen, virtual_path, virtual_path_len); | |
| 67 /* Prefix + Virtual Path + Terminator */ | |
| 68 absolute_path[virtual_path_len + NaClRootDirLen] = '\0'; | |
| 69 } else { | |
| 70 /* Absolute Path = Cwd + '/' + Relative Virtual Path + '\0' */ | |
| 71 if (NaClHostDescGetcwd(absolute_path, absolute_path_max_size) != 0) { | |
| 72 NaClLog(LOG_ERROR, "NaClHostDescGetcwd failed\n"); | |
| 73 return -NaClXlateErrno(errno); | |
| 
Sam Clegg
2016/02/11 22:45:26
NaClHostDescGetcwd returns the translated errno al
 
Sean Klein
2016/02/11 23:00:52
Done.
 | |
| 74 } | |
| 75 cwd_path_len = strlen(absolute_path); | |
| 76 /* | |
| 77 * The prefix cannot be mounted at the root, so we can safely assume that | |
| 78 * the Cwd consists of some path component after "/", such as "/foo". This | |
| 79 * means that before inserting the relative path, we must insert an | |
| 80 * additional "/" at the end of the Cwd. | |
| 81 */ | |
| 82 CHECK(NaClRootDirLen > 1); | |
| 83 CHECK(strncmp(absolute_path, NaClRootDir, NaClRootDirLen) == 0); | |
| 84 /* | |
| 85 * While verifying that the Cwd is inside a root (such as "/root"), ensure | |
| 86 * that the Cwd is not only matching the prefix of the root (such as | |
| 87 * "/root_but_not_really"). | |
| 88 */ | |
| 89 CHECK((absolute_path[NaClRootDirLen] == '/') || | |
| 90 (absolute_path[NaClRootDirLen] == '\0')); | |
| 91 if (cwd_path_len + 1 + virtual_path_len + 1 > absolute_path_max_size) { | |
| 92 NaClLog(LOG_ERROR, "Pathname too long: %s\n", virtual_path); | |
| 93 return -NACL_ABI_ENAMETOOLONG; | |
| 94 } | |
| 95 /* Cwd + '/' */ | |
| 96 memcpy(absolute_path + cwd_path_len, "/", 1); | |
| 97 /* Cwd + '/' + Relative Path */ | |
| 98 memcpy(absolute_path + cwd_path_len + 1, virtual_path, virtual_path_len); | |
| 99 /* Cwd + '/' + Relative Path + Terminator */ | |
| 100 absolute_path[cwd_path_len + 1 + virtual_path_len] = '\0'; | |
| 
Sam Clegg
2016/02/11 22:45:26
Is there some reason you are not using strcat here
 
Sean Klein
2016/02/11 23:00:52
Well, strcat is slower, since it requires scanning
 | |
| 62 } | 101 } | 
| 63 | 102 | 
| 64 /* Prefix */ | |
| 65 memcpy(absolute_path, NaClRootDir, NaClRootDirLen); | |
| 66 /* Prefix + Virtual Path */ | |
| 67 memcpy(absolute_path + NaClRootDirLen, virtual_path, virtual_path_len); | |
| 68 /* Prefix + Virtual Path + Terminator */ | |
| 69 absolute_path[virtual_path_len + NaClRootDirLen] = '\0'; | |
| 70 | |
| 71 return 0; | 103 return 0; | 
| 72 } | 104 } | 
| 73 | 105 | 
| 74 /* | 106 /* | 
| 75 * Determine if |path| points to a symbolic link. | 107 * Determine if |path| points to a symbolic link. | 
| 76 * | 108 * | 
| 77 * @param[in] path Path of file to be checked. | 109 * @param[in] path Path of file to be checked. | 
| 78 * @return Nonzero if path is symbolic link. | 110 * @return Nonzero if path is symbolic link. | 
| 79 */ | 111 */ | 
| 80 static int IsSymbolicLink(const char *path) { | 112 static int IsSymbolicLink(const char *path) { | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 * @param[in] dest_max_size The size of the buffer holding dest. | 159 * @param[in] dest_max_size The size of the buffer holding dest. | 
| 128 * @return 0 on success, else a NaCl errno. | 160 * @return 0 on success, else a NaCl errno. | 
| 129 */ | 161 */ | 
| 130 static uint32_t CopyHostPathMounted(char *dest, size_t dest_max_size) { | 162 static uint32_t CopyHostPathMounted(char *dest, size_t dest_max_size) { | 
| 131 uint32_t retval; | 163 uint32_t retval; | 
| 132 char raw_path[NACL_CONFIG_PATH_MAX]; | 164 char raw_path[NACL_CONFIG_PATH_MAX]; | 
| 133 | 165 | 
| 134 if (dest_max_size <= 0 || dest[0] == '\0') { | 166 if (dest_max_size <= 0 || dest[0] == '\0') { | 
| 135 NaClLog(LOG_ERROR, "Dest cannot be empty path\n"); | 167 NaClLog(LOG_ERROR, "Dest cannot be empty path\n"); | 
| 136 return -NACL_ABI_ENOENT; | 168 return -NACL_ABI_ENOENT; | 
| 137 } else if (dest[0] != '/') { | |
| 138 /* TODO(smklein): Allow usage of relative paths. */ | |
| 139 NaClLog(LOG_ERROR, "Pathname is not absolute: %s\n", dest); | |
| 140 return -NACL_ABI_EACCES; | |
| 141 } | 169 } | 
| 142 | 170 | 
| 143 CHECK(dest_max_size == NACL_CONFIG_PATH_MAX); | 171 CHECK(dest_max_size == NACL_CONFIG_PATH_MAX); | 
| 144 CHECK(strlen(dest) < NACL_CONFIG_PATH_MAX); | 172 CHECK(strlen(dest) < NACL_CONFIG_PATH_MAX); | 
| 145 strcpy(raw_path, dest); | 173 strcpy(raw_path, dest); | 
| 146 | 174 | 
| 147 /* Transform the user's raw path into an absolute path. */ | 175 /* | 
| 176 * Transform the user's raw path into an absolute path. | |
| 177 * The path may be either absolute or relative here -- but it will | |
| 178 * be absolute once VirtualToAbsolutePath returns successfully. | |
| 179 */ | |
| 148 retval = VirtualToAbsolutePath(raw_path, dest, dest_max_size); | 180 retval = VirtualToAbsolutePath(raw_path, dest, dest_max_size); | 
| 149 if (retval != 0) | 181 if (retval != 0) | 
| 150 return retval; | 182 return retval; | 
| 151 | 183 | 
| 152 /* Verify that the path cannot escape root. */ | 184 /* Verify that the path cannot escape root. */ | 
| 153 return ValidateAbsolutePath(dest); | 185 return ValidateAbsolutePath(dest); | 
| 154 } | 186 } | 
| 155 #endif /* !NACL_WINDOWS */ | 187 #endif /* !NACL_WINDOWS */ | 
| 156 | 188 | 
| 157 uint32_t CopyHostPathInFromUser(struct NaClApp *nap, | 189 uint32_t CopyHostPathInFromUser(struct NaClApp *nap, | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 return (uint32_t) -NACL_ABI_EFAULT; | 250 return (uint32_t) -NACL_ABI_EFAULT; | 
| 219 return 0; | 251 return 0; | 
| 220 } | 252 } | 
| 221 | 253 | 
| 222 /* Copy out everything after the root dir (including the slash). */ | 254 /* Copy out everything after the root dir (including the slash). */ | 
| 223 if (!NaClCopyOutToUser(nap, dst_usr_addr, path + NaClRootDirLen, | 255 if (!NaClCopyOutToUser(nap, dst_usr_addr, path + NaClRootDirLen, | 
| 224 path_len - NaClRootDirLen + 1)) | 256 path_len - NaClRootDirLen + 1)) | 
| 225 return (uint32_t) -NACL_ABI_EFAULT; | 257 return (uint32_t) -NACL_ABI_EFAULT; | 
| 226 return 0; | 258 return 0; | 
| 227 } | 259 } | 
| OLD | NEW |