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 |