Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2013 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/sys_filename.h" | 7 #include "native_client/src/trusted/service_runtime/sys_filename.h" |
| 8 | 8 |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 return -NACL_ABI_EFAULT; | 37 return -NACL_ABI_EFAULT; |
| 38 } | 38 } |
| 39 | 39 |
| 40 NaClLog(LOG_ERROR, "NaClSys: pathname string too long\n"); | 40 NaClLog(LOG_ERROR, "NaClSys: pathname string too long\n"); |
| 41 return -NACL_ABI_ENAMETOOLONG; | 41 return -NACL_ABI_ENAMETOOLONG; |
| 42 } | 42 } |
| 43 | 43 |
| 44 return 0; | 44 return 0; |
| 45 } | 45 } |
| 46 | 46 |
| 47 static uint32_t CopyHostPathFromUser(struct NaClApp *nap, | |
| 48 char *dest, | |
| 49 size_t num_bytes, | |
| 50 uintptr_t src) { | |
| 51 /* | |
| 52 * The purpose of this function is to not only copy the path bytes from the | |
| 53 * NaClApp, but to make sure the path is properly sanitized and has the | |
| 54 * NaClRootFolder prefixed, if provided. | |
| 55 * Start and see if there even is a root. | |
| 56 */ | |
| 57 if (NaClRootFolder == NULL) { | |
| 58 return CopyPathFromUser(nap, dest, num_bytes, src); | |
| 59 } | |
| 60 /* | |
| 61 * Make sure we have room for the trailing null byte and an actual path. | |
| 62 */ | |
| 63 if (NaClRootFolderLen + 1 >= num_bytes) { | |
| 64 return -NACL_ABI_ENAMETOOLONG; | |
| 65 } | |
| 66 /* | |
| 67 * Okay, add the root folder to dest (which will have a trailing slash | |
| 68 * already), then copy the path in after. | |
| 69 */ | |
| 70 memcpy(dest, NaClRootFolder, NaClRootFolderLen); | |
| 71 return CopyPathFromUser(nap, | |
| 72 dest + NaClRootFolderLen, | |
| 73 num_bytes - NaClRootFolderLen, | |
| 74 src); | |
| 75 /* | |
| 76 * TODO(jtolds): make sure we sanitize the path we just got so it has no ".." | |
| 77 * path elements. | |
|
jtolds
2015/06/25 23:05:05
does this even need to happen?
Mark Seaborn
2015/06/25 23:55:09
If you don't remove ".." elements, isn't it trivia
jtolds
2015/06/26 22:07:11
currently working through these comments, but i ju
| |
| 78 */ | |
| 79 } | |
| 80 | |
| 81 int NaClCopyHostPathOutToUser(struct NaClApp *nap, | |
| 82 uintptr_t dst_usr_addr, | |
| 83 char *path) { | |
| 84 /* | |
| 85 * TODO(jtolds): remove NaClRootFolder prefix and fail if it doesn't match | |
|
jtolds
2015/06/25 23:05:05
this function is only used to get the CWD. what sh
| |
| 86 */ | |
| 87 return NaClCopyOutToUser(nap, dst_usr_addr, path, strlen(path) + 1); | |
| 88 } | |
| 89 | |
| 47 int32_t NaClSysOpen(struct NaClAppThread *natp, | 90 int32_t NaClSysOpen(struct NaClAppThread *natp, |
| 48 uint32_t pathname, | 91 uint32_t pathname, |
| 49 int flags, | 92 int flags, |
| 50 int mode) { | 93 int mode) { |
| 51 struct NaClApp *nap = natp->nap; | 94 struct NaClApp *nap = natp->nap; |
| 52 uint32_t retval = -NACL_ABI_EINVAL; | 95 uint32_t retval = -NACL_ABI_EINVAL; |
| 53 char path[NACL_CONFIG_PATH_MAX]; | 96 char path[NACL_CONFIG_PATH_MAX]; |
| 54 nacl_host_stat_t stbuf; | 97 nacl_host_stat_t stbuf; |
| 55 int allowed_flags; | 98 int allowed_flags; |
| 56 | 99 |
| 57 NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", " | 100 NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", " |
| 58 "0x%08"NACL_PRIx32", 0x%x, 0x%x)\n", | 101 "0x%08"NACL_PRIx32", 0x%x, 0x%x)\n", |
| 59 (uintptr_t) natp, pathname, flags, mode); | 102 (uintptr_t) natp, pathname, flags, mode); |
| 60 | 103 |
| 61 if (!NaClAclBypassChecks) { | 104 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 62 return -NACL_ABI_EACCES; | 105 return -NACL_ABI_EACCES; |
| 63 } | 106 } |
| 64 | 107 |
| 65 retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname); | 108 retval = CopyHostPathFromUser(nap, path, sizeof path, (uintptr_t) pathname); |
| 66 if (0 != retval) | 109 if (0 != retval) |
| 67 goto cleanup; | 110 goto cleanup; |
| 68 | 111 |
| 69 allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT | NACL_ABI_O_EXCL | 112 allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT | NACL_ABI_O_EXCL |
| 70 | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND | 113 | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND |
| 71 | NACL_ABI_O_DIRECTORY); | 114 | NACL_ABI_O_DIRECTORY); |
| 72 if (0 != (flags & ~allowed_flags)) { | 115 if (0 != (flags & ~allowed_flags)) { |
| 73 NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n", | 116 NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n", |
| 74 flags); | 117 flags); |
| 75 flags &= allowed_flags; | 118 flags &= allowed_flags; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 uint32_t nasp) { | 202 uint32_t nasp) { |
| 160 struct NaClApp *nap = natp->nap; | 203 struct NaClApp *nap = natp->nap; |
| 161 int32_t retval = -NACL_ABI_EINVAL; | 204 int32_t retval = -NACL_ABI_EINVAL; |
| 162 char path[NACL_CONFIG_PATH_MAX]; | 205 char path[NACL_CONFIG_PATH_MAX]; |
| 163 nacl_host_stat_t stbuf; | 206 nacl_host_stat_t stbuf; |
| 164 | 207 |
| 165 NaClLog(3, | 208 NaClLog(3, |
| 166 ("Entered NaClSysStat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIx32"," | 209 ("Entered NaClSysStat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIx32"," |
| 167 " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, pathname, nasp); | 210 " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, pathname, nasp); |
| 168 | 211 |
| 169 if (!NaClAclBypassChecks) { | 212 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 170 return -NACL_ABI_EACCES; | 213 return -NACL_ABI_EACCES; |
| 171 } | 214 } |
| 172 | 215 |
| 173 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 216 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 174 if (0 != retval) | 217 if (0 != retval) |
| 175 goto cleanup; | 218 goto cleanup; |
| 176 | 219 |
| 177 /* | 220 /* |
| 178 * Perform a host stat. | 221 * Perform a host stat. |
| 179 */ | 222 */ |
| 180 retval = NaClHostDescStat(path, &stbuf); | 223 retval = NaClHostDescStat(path, &stbuf); |
| 181 if (0 == retval) { | 224 if (0 == retval) { |
| 182 struct nacl_abi_stat abi_stbuf; | 225 struct nacl_abi_stat abi_stbuf; |
| 183 | 226 |
| 184 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf, &stbuf); | 227 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf, &stbuf); |
| 185 if (!NaClCopyOutToUser(nap, nasp, &abi_stbuf, sizeof abi_stbuf)) { | 228 if (!NaClCopyOutToUser(nap, nasp, &abi_stbuf, sizeof abi_stbuf)) { |
| 186 retval = -NACL_ABI_EFAULT; | 229 retval = -NACL_ABI_EFAULT; |
| 187 } | 230 } |
| 188 } | 231 } |
| 189 cleanup: | 232 cleanup: |
| 190 return retval; | 233 return retval; |
| 191 } | 234 } |
| 192 | 235 |
| 193 int32_t NaClSysMkdir(struct NaClAppThread *natp, | 236 int32_t NaClSysMkdir(struct NaClAppThread *natp, |
| 194 uint32_t pathname, | 237 uint32_t pathname, |
| 195 int mode) { | 238 int mode) { |
| 196 struct NaClApp *nap = natp->nap; | 239 struct NaClApp *nap = natp->nap; |
| 197 char path[NACL_CONFIG_PATH_MAX]; | 240 char path[NACL_CONFIG_PATH_MAX]; |
| 198 int32_t retval = -NACL_ABI_EINVAL; | 241 int32_t retval = -NACL_ABI_EINVAL; |
| 199 | 242 |
| 200 if (!NaClAclBypassChecks) { | 243 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 201 retval = -NACL_ABI_EACCES; | 244 retval = -NACL_ABI_EACCES; |
| 202 goto cleanup; | 245 goto cleanup; |
| 203 } | 246 } |
| 204 | 247 |
| 205 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 248 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 206 if (0 != retval) | 249 if (0 != retval) |
| 207 goto cleanup; | 250 goto cleanup; |
| 208 | 251 |
| 209 retval = NaClHostDescMkdir(path, mode); | 252 retval = NaClHostDescMkdir(path, mode); |
| 210 cleanup: | 253 cleanup: |
| 211 return retval; | 254 return retval; |
| 212 } | 255 } |
| 213 | 256 |
| 214 int32_t NaClSysRmdir(struct NaClAppThread *natp, | 257 int32_t NaClSysRmdir(struct NaClAppThread *natp, |
| 215 uint32_t pathname) { | 258 uint32_t pathname) { |
| 216 struct NaClApp *nap = natp->nap; | 259 struct NaClApp *nap = natp->nap; |
| 217 char path[NACL_CONFIG_PATH_MAX]; | 260 char path[NACL_CONFIG_PATH_MAX]; |
| 218 int32_t retval = -NACL_ABI_EINVAL; | 261 int32_t retval = -NACL_ABI_EINVAL; |
| 219 | 262 |
| 220 if (!NaClAclBypassChecks) { | 263 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 221 retval = -NACL_ABI_EACCES; | 264 retval = -NACL_ABI_EACCES; |
| 222 goto cleanup; | 265 goto cleanup; |
| 223 } | 266 } |
| 224 | 267 |
| 225 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 268 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 226 if (0 != retval) | 269 if (0 != retval) |
| 227 goto cleanup; | 270 goto cleanup; |
| 228 | 271 |
| 229 retval = NaClHostDescRmdir(path); | 272 retval = NaClHostDescRmdir(path); |
| 230 cleanup: | 273 cleanup: |
| 231 return retval; | 274 return retval; |
| 232 } | 275 } |
| 233 | 276 |
| 234 int32_t NaClSysChdir(struct NaClAppThread *natp, | 277 int32_t NaClSysChdir(struct NaClAppThread *natp, |
| 235 uint32_t pathname) { | 278 uint32_t pathname) { |
| 236 struct NaClApp *nap = natp->nap; | 279 struct NaClApp *nap = natp->nap; |
| 237 char path[NACL_CONFIG_PATH_MAX]; | 280 char path[NACL_CONFIG_PATH_MAX]; |
| 238 int32_t retval = -NACL_ABI_EINVAL; | 281 int32_t retval = -NACL_ABI_EINVAL; |
| 239 | 282 |
| 240 if (!NaClAclBypassChecks) { | 283 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 241 retval = -NACL_ABI_EACCES; | 284 retval = -NACL_ABI_EACCES; |
| 242 goto cleanup; | 285 goto cleanup; |
| 243 } | 286 } |
| 244 | 287 |
| 245 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 288 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 246 if (0 != retval) | 289 if (0 != retval) |
| 247 goto cleanup; | 290 goto cleanup; |
| 248 | 291 |
| 249 retval = NaClHostDescChdir(path); | 292 retval = NaClHostDescChdir(path); |
| 250 cleanup: | 293 cleanup: |
| 251 return retval; | 294 return retval; |
| 252 } | 295 } |
| 253 | 296 |
| 254 int32_t NaClSysGetcwd(struct NaClAppThread *natp, | 297 int32_t NaClSysGetcwd(struct NaClAppThread *natp, |
| 255 uint32_t buffer, | 298 uint32_t buffer, |
| 256 int len) { | 299 int len) { |
| 257 struct NaClApp *nap = natp->nap; | 300 struct NaClApp *nap = natp->nap; |
| 258 int32_t retval = -NACL_ABI_EINVAL; | 301 int32_t retval = -NACL_ABI_EINVAL; |
| 259 char path[NACL_CONFIG_PATH_MAX]; | 302 char path[NACL_CONFIG_PATH_MAX]; |
| 260 | 303 |
| 261 if (!NaClAclBypassChecks) { | 304 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 262 retval = -NACL_ABI_EACCES; | 305 retval = -NACL_ABI_EACCES; |
| 263 goto cleanup; | 306 goto cleanup; |
| 264 } | 307 } |
| 265 | 308 |
| 266 if (len >= NACL_CONFIG_PATH_MAX) | 309 if (len >= NACL_CONFIG_PATH_MAX) |
| 267 len = NACL_CONFIG_PATH_MAX - 1; | 310 len = NACL_CONFIG_PATH_MAX - 1; |
| 268 | 311 |
| 269 retval = NaClHostDescGetcwd(path, len); | 312 retval = NaClHostDescGetcwd(path, len); |
| 270 if (retval != 0) | 313 if (retval != 0) |
| 271 goto cleanup; | 314 goto cleanup; |
| 272 | 315 |
| 273 if (!NaClCopyOutToUser(nap, buffer, &path, strlen(path) + 1)) | 316 if (!NaClCopyHostPathOutToUser(nap, buffer, &path[0])) |
| 274 retval = -NACL_ABI_EFAULT; | 317 retval = -NACL_ABI_EFAULT; |
| 275 | 318 |
| 276 cleanup: | 319 cleanup: |
| 277 return retval; | 320 return retval; |
| 278 } | 321 } |
| 279 | 322 |
| 280 int32_t NaClSysUnlink(struct NaClAppThread *natp, | 323 int32_t NaClSysUnlink(struct NaClAppThread *natp, |
| 281 uint32_t pathname) { | 324 uint32_t pathname) { |
| 282 struct NaClApp *nap = natp->nap; | 325 struct NaClApp *nap = natp->nap; |
| 283 char path[NACL_CONFIG_PATH_MAX]; | 326 char path[NACL_CONFIG_PATH_MAX]; |
| 284 int32_t retval = -NACL_ABI_EINVAL; | 327 int32_t retval = -NACL_ABI_EINVAL; |
| 285 | 328 |
| 286 if (!NaClAclBypassChecks) { | 329 if (!NaClAclBypassChecks && NaClRootFolder == NULL) { |
| 287 retval = -NACL_ABI_EACCES; | 330 retval = -NACL_ABI_EACCES; |
| 288 goto cleanup; | 331 goto cleanup; |
| 289 } | 332 } |
| 290 | 333 |
| 291 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 334 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 292 if (0 != retval) | 335 if (0 != retval) |
| 293 goto cleanup; | 336 goto cleanup; |
| 294 | 337 |
| 295 retval = NaClHostDescUnlink(path); | 338 retval = NaClHostDescUnlink(path); |
| 296 NaClLog(3, "NaClHostDescUnlink '%s' -> %d\n", path, retval); | 339 NaClLog(3, "NaClHostDescUnlink '%s' -> %d\n", path, retval); |
| 297 cleanup: | 340 cleanup: |
| 298 return retval; | 341 return retval; |
| 299 } | 342 } |
| 300 | 343 |
| 301 int32_t NaClSysTruncate(struct NaClAppThread *natp, | 344 int32_t NaClSysTruncate(struct NaClAppThread *natp, |
| 302 uint32_t pathname, | 345 uint32_t pathname, |
| 303 uint32_t length_addr) { | 346 uint32_t length_addr) { |
| 304 struct NaClApp *nap = natp->nap; | 347 struct NaClApp *nap = natp->nap; |
| 305 char path[NACL_CONFIG_PATH_MAX]; | 348 char path[NACL_CONFIG_PATH_MAX]; |
| 306 int32_t retval = -NACL_ABI_EINVAL; | 349 int32_t retval = -NACL_ABI_EINVAL; |
| 307 nacl_abi_off_t length; | 350 nacl_abi_off_t length; |
| 308 | 351 |
| 309 if (!NaClAclBypassChecks) | 352 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 310 return -NACL_ABI_EACCES; | 353 return -NACL_ABI_EACCES; |
| 311 | 354 |
| 312 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | 355 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); |
| 313 if (0 != retval) | 356 if (0 != retval) |
| 314 return retval; | 357 return retval; |
| 315 | 358 |
| 316 if (!NaClCopyInFromUser(nap, &length, length_addr, sizeof length)) | 359 if (!NaClCopyInFromUser(nap, &length, length_addr, sizeof length)) |
| 317 return -NACL_ABI_EFAULT; | 360 return -NACL_ABI_EFAULT; |
| 318 | 361 |
| 319 retval = NaClHostDescTruncate(path, length); | 362 retval = NaClHostDescTruncate(path, length); |
| 320 NaClLog(3, "NaClHostDescTruncate '%s' %"NACL_PRId64" -> %d\n", | 363 NaClLog(3, "NaClHostDescTruncate '%s' %"NACL_PRId64" -> %d\n", |
| 321 path, length, retval); | 364 path, length, retval); |
| 322 return retval; | 365 return retval; |
| 323 } | 366 } |
| 324 | 367 |
| 325 int32_t NaClSysLstat(struct NaClAppThread *natp, | 368 int32_t NaClSysLstat(struct NaClAppThread *natp, |
| 326 uint32_t pathname, | 369 uint32_t pathname, |
| 327 uint32_t nasp) { | 370 uint32_t nasp) { |
| 328 struct NaClApp *nap = natp->nap; | 371 struct NaClApp *nap = natp->nap; |
| 329 int32_t retval = -NACL_ABI_EINVAL; | 372 int32_t retval = -NACL_ABI_EINVAL; |
| 330 char path[NACL_CONFIG_PATH_MAX]; | 373 char path[NACL_CONFIG_PATH_MAX]; |
| 331 nacl_host_stat_t stbuf; | 374 nacl_host_stat_t stbuf; |
| 332 | 375 |
| 333 NaClLog(3, | 376 NaClLog(3, |
| 334 ("Entered NaClSysLstat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIx32"," | 377 ("Entered NaClSysLstat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIx32"," |
| 335 " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, pathname, nasp); | 378 " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, pathname, nasp); |
| 336 | 379 |
| 337 if (!NaClAclBypassChecks) { | 380 if (NaClRootFolder != NULL) { |
| 381 retval = CopyHostPathFromUser(nap, path, sizeof path, pathname); | |
| 382 if (0 != retval) | |
| 383 return retval; | |
| 384 | |
| 385 /* | |
| 386 * Mounted root folders don't support symlinks yet, so pretend they don't | |
| 387 * exist, and all symlinks are actually whatever they point to. CAREFUL, | |
| 388 * this means having symlinks that point outside of your mounted root | |
|
Mark Seaborn
2015/06/25 23:55:09
Furthermore, note that if you have a relative syml
| |
| 389 * folder can allow chroot jail breaking! | |
| 390 * For this reason, symlink creation is also disabled. | |
| 391 */ | |
| 392 retval = NaClHostDescStat(path, &stbuf); | |
| 393 if (0 == retval) { | |
| 394 struct nacl_abi_stat abi_stbuf; | |
| 395 | |
| 396 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf, &stbuf); | |
| 397 if (!NaClCopyOutToUser(nap, nasp, &abi_stbuf, sizeof abi_stbuf)) { | |
| 398 return -NACL_ABI_EFAULT; | |
| 399 } | |
| 400 } | |
| 401 return retval; | |
| 402 | |
| 403 } else if (NaClAclBypassChecks) { | |
| 404 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | |
| 405 if (0 != retval) | |
| 406 return retval; | |
| 407 | |
| 408 /* | |
| 409 * Perform a host lstat directly | |
| 410 */ | |
| 411 retval = NaClHostDescLstat(path, &stbuf); | |
| 412 if (0 == retval) { | |
| 413 struct nacl_abi_stat abi_stbuf; | |
| 414 | |
| 415 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf, &stbuf); | |
| 416 if (!NaClCopyOutToUser(nap, nasp, &abi_stbuf, sizeof abi_stbuf)) { | |
| 417 return -NACL_ABI_EFAULT; | |
| 418 } | |
| 419 } | |
| 420 return retval; | |
| 421 | |
| 422 } else { | |
| 338 return -NACL_ABI_EACCES; | 423 return -NACL_ABI_EACCES; |
| 339 } | 424 } |
| 340 | |
| 341 retval = CopyPathFromUser(nap, path, sizeof path, pathname); | |
| 342 if (0 != retval) | |
| 343 return retval; | |
| 344 | |
| 345 /* | |
| 346 * Perform a host stat. | |
| 347 */ | |
| 348 retval = NaClHostDescLstat(path, &stbuf); | |
| 349 if (0 == retval) { | |
| 350 struct nacl_abi_stat abi_stbuf; | |
| 351 | |
| 352 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf, &stbuf); | |
| 353 if (!NaClCopyOutToUser(nap, nasp, &abi_stbuf, sizeof abi_stbuf)) { | |
| 354 return -NACL_ABI_EFAULT; | |
| 355 } | |
| 356 } | |
| 357 return retval; | |
| 358 } | 425 } |
| 359 | 426 |
| 360 int32_t NaClSysLink(struct NaClAppThread *natp, | 427 int32_t NaClSysLink(struct NaClAppThread *natp, |
| 361 uint32_t oldname, | 428 uint32_t oldname, |
| 362 uint32_t newname) { | 429 uint32_t newname) { |
| 363 struct NaClApp *nap = natp->nap; | 430 struct NaClApp *nap = natp->nap; |
| 364 char oldpath[NACL_CONFIG_PATH_MAX]; | 431 char oldpath[NACL_CONFIG_PATH_MAX]; |
| 365 char newpath[NACL_CONFIG_PATH_MAX]; | 432 char newpath[NACL_CONFIG_PATH_MAX]; |
| 366 int32_t retval = -NACL_ABI_EINVAL; | 433 int32_t retval = -NACL_ABI_EINVAL; |
| 367 | 434 |
| 368 if (!NaClAclBypassChecks) | 435 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 369 return -NACL_ABI_EACCES; | 436 return -NACL_ABI_EACCES; |
| 370 | 437 |
| 371 retval = CopyPathFromUser(nap, oldpath, sizeof oldpath, oldname); | 438 retval = CopyHostPathFromUser(nap, oldpath, sizeof oldpath, oldname); |
| 372 if (0 != retval) | 439 if (0 != retval) |
| 373 return retval; | 440 return retval; |
| 374 | 441 |
| 375 retval = CopyPathFromUser(nap, newpath, sizeof newpath, newname); | 442 retval = CopyHostPathFromUser(nap, newpath, sizeof newpath, newname); |
| 376 if (0 != retval) | 443 if (0 != retval) |
| 377 return retval; | 444 return retval; |
| 378 | 445 |
| 379 return NaClHostDescLink(oldpath, newpath); | 446 return NaClHostDescLink(oldpath, newpath); |
| 380 } | 447 } |
| 381 | 448 |
| 382 int32_t NaClSysRename(struct NaClAppThread *natp, | 449 int32_t NaClSysRename(struct NaClAppThread *natp, |
| 383 uint32_t oldname, | 450 uint32_t oldname, |
| 384 uint32_t newname) { | 451 uint32_t newname) { |
| 385 struct NaClApp *nap = natp->nap; | 452 struct NaClApp *nap = natp->nap; |
| 386 char oldpath[NACL_CONFIG_PATH_MAX]; | 453 char oldpath[NACL_CONFIG_PATH_MAX]; |
| 387 char newpath[NACL_CONFIG_PATH_MAX]; | 454 char newpath[NACL_CONFIG_PATH_MAX]; |
| 388 int32_t retval = -NACL_ABI_EINVAL; | 455 int32_t retval = -NACL_ABI_EINVAL; |
| 389 | 456 |
| 390 if (!NaClAclBypassChecks) | 457 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 391 return -NACL_ABI_EACCES; | 458 return -NACL_ABI_EACCES; |
| 392 | 459 |
| 393 retval = CopyPathFromUser(nap, oldpath, sizeof oldpath, oldname); | 460 retval = CopyHostPathFromUser(nap, oldpath, sizeof oldpath, oldname); |
| 394 if (0 != retval) | 461 if (0 != retval) |
| 395 return retval; | 462 return retval; |
| 396 | 463 |
| 397 retval = CopyPathFromUser(nap, newpath, sizeof newpath, newname); | 464 retval = CopyHostPathFromUser(nap, newpath, sizeof newpath, newname); |
| 398 if (0 != retval) | 465 if (0 != retval) |
| 399 return retval; | 466 return retval; |
| 400 | 467 |
| 401 return NaClHostDescRename(oldpath, newpath); | 468 return NaClHostDescRename(oldpath, newpath); |
| 402 } | 469 } |
| 403 | 470 |
| 404 int32_t NaClSysSymlink(struct NaClAppThread *natp, | 471 int32_t NaClSysSymlink(struct NaClAppThread *natp, |
| 405 uint32_t oldname, | 472 uint32_t oldname, |
| 406 uint32_t newname) { | 473 uint32_t newname) { |
| 407 struct NaClApp *nap = natp->nap; | 474 struct NaClApp *nap = natp->nap; |
| 408 char oldpath[NACL_CONFIG_PATH_MAX]; | 475 char oldpath[NACL_CONFIG_PATH_MAX]; |
| 409 char newpath[NACL_CONFIG_PATH_MAX]; | 476 char newpath[NACL_CONFIG_PATH_MAX]; |
| 410 int32_t retval = -NACL_ABI_EINVAL; | 477 int32_t retval = -NACL_ABI_EINVAL; |
| 411 | 478 |
| 479 if (NaClRootFolder != NULL) { | |
| 480 /* | |
| 481 * Mounted root folders don't support symlinks yet, so pretend they don't | |
| 482 * exist and can't be created. See also lstat and readlink. | |
| 483 * Could be convinced to do ENOSYS instead of EPERM. | |
| 484 */ | |
| 485 return -NACL_ABI_EPERM; | |
| 486 } | |
| 487 | |
| 412 if (!NaClAclBypassChecks) | 488 if (!NaClAclBypassChecks) |
| 413 return -NACL_ABI_EACCES; | 489 return -NACL_ABI_EACCES; |
| 414 | 490 |
| 415 retval = CopyPathFromUser(nap, oldpath, sizeof oldpath, oldname); | 491 retval = CopyPathFromUser(nap, oldpath, sizeof oldpath, oldname); |
| 416 if (0 != retval) | 492 if (0 != retval) |
| 417 return retval; | 493 return retval; |
| 418 | 494 |
| 419 retval = CopyPathFromUser(nap, newpath, sizeof newpath, newname); | 495 retval = CopyPathFromUser(nap, newpath, sizeof newpath, newname); |
| 420 if (0 != retval) | 496 if (0 != retval) |
| 421 return retval; | 497 return retval; |
| 422 | 498 |
| 423 return NaClHostDescSymlink(oldpath, newpath); | 499 return NaClHostDescSymlink(oldpath, newpath); |
| 424 } | 500 } |
| 425 | 501 |
| 426 int32_t NaClSysChmod(struct NaClAppThread *natp, | 502 int32_t NaClSysChmod(struct NaClAppThread *natp, |
| 427 uint32_t path, | 503 uint32_t path, |
| 428 nacl_abi_mode_t mode) { | 504 nacl_abi_mode_t mode) { |
| 429 struct NaClApp *nap = natp->nap; | 505 struct NaClApp *nap = natp->nap; |
| 430 char pathname[NACL_CONFIG_PATH_MAX]; | 506 char pathname[NACL_CONFIG_PATH_MAX]; |
| 431 int32_t retval = -NACL_ABI_EINVAL; | 507 int32_t retval = -NACL_ABI_EINVAL; |
| 432 | 508 |
| 433 if (!NaClAclBypassChecks) | 509 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 434 return -NACL_ABI_EACCES; | 510 return -NACL_ABI_EACCES; |
| 435 | 511 |
| 436 retval = CopyPathFromUser(nap, pathname, sizeof pathname, path); | 512 retval = CopyHostPathFromUser(nap, pathname, sizeof pathname, path); |
| 437 if (0 != retval) | 513 if (0 != retval) |
| 438 return retval; | 514 return retval; |
| 439 | 515 |
| 440 return NaClHostDescChmod(pathname, mode); | 516 return NaClHostDescChmod(pathname, mode); |
| 441 } | 517 } |
| 442 | 518 |
| 443 int32_t NaClSysAccess(struct NaClAppThread *natp, | 519 int32_t NaClSysAccess(struct NaClAppThread *natp, |
| 444 uint32_t path, | 520 uint32_t path, |
| 445 int amode) { | 521 int amode) { |
| 446 struct NaClApp *nap = natp->nap; | 522 struct NaClApp *nap = natp->nap; |
| 447 char pathname[NACL_CONFIG_PATH_MAX]; | 523 char pathname[NACL_CONFIG_PATH_MAX]; |
| 448 int32_t retval = -NACL_ABI_EINVAL; | 524 int32_t retval = -NACL_ABI_EINVAL; |
| 449 | 525 |
| 450 if (!NaClAclBypassChecks) | 526 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 451 return -NACL_ABI_EACCES; | 527 return -NACL_ABI_EACCES; |
| 452 | 528 |
| 453 /* | 529 /* |
| 454 * amode must either be F_OK or some combination of the three permission bits. | 530 * amode must either be F_OK or some combination of the three permission bits. |
| 455 */ | 531 */ |
| 456 if (amode != NACL_ABI_F_OK | 532 if (amode != NACL_ABI_F_OK |
| 457 && (amode & ~(NACL_ABI_R_OK | NACL_ABI_W_OK | NACL_ABI_X_OK)) != 0) | 533 && (amode & ~(NACL_ABI_R_OK | NACL_ABI_W_OK | NACL_ABI_X_OK)) != 0) |
| 458 return -NACL_ABI_EINVAL; | 534 return -NACL_ABI_EINVAL; |
| 459 | 535 |
| 460 retval = CopyPathFromUser(nap, pathname, sizeof pathname, path); | 536 retval = CopyHostPathFromUser(nap, pathname, sizeof pathname, path); |
| 461 if (0 != retval) | 537 if (0 != retval) |
| 462 return retval; | 538 return retval; |
| 463 | 539 |
| 464 retval = NaClHostDescAccess(pathname, amode); | 540 retval = NaClHostDescAccess(pathname, amode); |
| 465 NaClLog(3, "NaClHostDescAccess '%s' %d -> %d\n", pathname, amode, retval); | 541 NaClLog(3, "NaClHostDescAccess '%s' %d -> %d\n", pathname, amode, retval); |
| 466 return retval; | 542 return retval; |
| 467 } | 543 } |
| 468 | 544 |
| 469 int32_t NaClSysReadlink(struct NaClAppThread *natp, | 545 int32_t NaClSysReadlink(struct NaClAppThread *natp, |
| 470 uint32_t path, | 546 uint32_t path, |
| 471 uint32_t buffer, | 547 uint32_t buffer, |
| 472 uint32_t buffer_size) { | 548 uint32_t buffer_size) { |
| 473 struct NaClApp *nap = natp->nap; | 549 struct NaClApp *nap = natp->nap; |
| 474 char pathname[NACL_CONFIG_PATH_MAX]; | 550 char pathname[NACL_CONFIG_PATH_MAX]; |
| 475 char realpath[NACL_CONFIG_PATH_MAX]; | 551 char realpath[NACL_CONFIG_PATH_MAX]; |
| 476 int32_t retval = -NACL_ABI_EINVAL; | 552 int32_t retval = -NACL_ABI_EINVAL; |
| 477 uint32_t result_size; | 553 uint32_t result_size; |
| 478 | 554 |
| 555 if (NaClRootFolder != NULL) { | |
| 556 /* We're going to return an error, but perhaps in this case we should | |
| 557 * try and find out if the file even exists, so we can return ENOENT first, | |
| 558 * and then return EINVAL otherwise? Dunno. | |
| 559 */ | |
| 560 return -NACL_ABI_ENOSYS; | |
| 561 } | |
| 562 | |
| 479 if (!NaClAclBypassChecks) | 563 if (!NaClAclBypassChecks) |
| 480 return -NACL_ABI_EACCES; | 564 return -NACL_ABI_EACCES; |
| 481 | 565 |
| 482 retval = CopyPathFromUser(nap, pathname, sizeof pathname, path); | 566 retval = CopyPathFromUser(nap, pathname, sizeof pathname, path); |
| 483 if (0 != retval) | 567 if (0 != retval) |
| 484 return retval; | 568 return retval; |
| 485 | 569 |
| 486 retval = NaClHostDescReadlink(pathname, realpath, sizeof(realpath)); | 570 retval = NaClHostDescReadlink(pathname, realpath, sizeof(realpath)); |
| 487 if (retval < 0) | 571 if (retval < 0) |
| 488 return retval; | 572 return retval; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 511 return result_size; | 595 return result_size; |
| 512 } | 596 } |
| 513 | 597 |
| 514 int32_t NaClSysUtimes(struct NaClAppThread *natp, | 598 int32_t NaClSysUtimes(struct NaClAppThread *natp, |
| 515 uint32_t path, | 599 uint32_t path, |
| 516 uint32_t times) { | 600 uint32_t times) { |
| 517 struct NaClApp *nap = natp->nap; | 601 struct NaClApp *nap = natp->nap; |
| 518 char pathname[NACL_CONFIG_PATH_MAX]; | 602 char pathname[NACL_CONFIG_PATH_MAX]; |
| 519 int32_t retval = -NACL_ABI_EINVAL; | 603 int32_t retval = -NACL_ABI_EINVAL; |
| 520 | 604 |
| 521 if (!NaClAclBypassChecks) | 605 if (!NaClAclBypassChecks && NaClRootFolder == NULL) |
| 522 return -NACL_ABI_EACCES; | 606 return -NACL_ABI_EACCES; |
| 523 | 607 |
| 524 retval = CopyPathFromUser(nap, pathname, sizeof pathname, path); | 608 retval = CopyHostPathFromUser(nap, pathname, sizeof pathname, path); |
| 525 if (0 != retval) | 609 if (0 != retval) |
| 526 return retval; | 610 return retval; |
| 527 | 611 |
| 528 if (times == 0) | 612 if (times == 0) |
| 529 return -NACL_ABI_EACCES; | 613 return -NACL_ABI_EACCES; |
| 530 | 614 |
| 531 /* TODO(sbc): implement in terms of NaClHost function. */ | 615 /* TODO(sbc): implement in terms of NaClHost function. */ |
| 532 return -NACL_ABI_ENOSYS; | 616 return -NACL_ABI_ENOSYS; |
| 533 } | 617 } |
| OLD | NEW |