194 |
195 |
195 // successful conversion, return the pid |
196 // successful conversion, return the pid |
196 return pid; |
197 return pid; |
197 } |
198 } |
198 |
199 |
199 |
200 // Check if the given statbuf is considered a secure directory for |
200 // check if the given path is considered a secure directory for |
201 // the backing store files. Returns true if the directory is considered |
|
202 // a secure location. Returns false if the statbuf is a symbolic link or |
|
203 // if an error occurred. |
|
204 static bool is_statbuf_secure(struct stat *statp) { |
|
205 if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) { |
|
206 // The path represents a link or some non-directory file type, |
|
207 // which is not what we expected. Declare it insecure. |
|
208 // |
|
209 return false; |
|
210 } |
|
211 // We have an existing directory, check if the permissions are safe. |
|
212 if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) { |
|
213 // The directory is open for writing and could be subjected |
|
214 // to a symlink or a hard link attack. Declare it insecure. |
|
215 return false; |
|
216 } |
|
217 // See if the uid of the directory matches the effective uid of the process. |
|
218 // |
|
219 if (statp->st_uid != geteuid()) { |
|
220 // The directory was not created by this user, declare it insecure. |
|
221 return false; |
|
222 } |
|
223 return true; |
|
224 } |
|
225 |
|
226 |
|
227 // Check if the given path is considered a secure directory for |
201 // the backing store files. Returns true if the directory exists |
228 // the backing store files. Returns true if the directory exists |
202 // and is considered a secure location. Returns false if the path |
229 // and is considered a secure location. Returns false if the path |
203 // is a symbolic link or if an error occurred. |
230 // is a symbolic link or if an error occurred. |
204 // |
|
205 static bool is_directory_secure(const char* path) { |
231 static bool is_directory_secure(const char* path) { |
206 struct stat statbuf; |
232 struct stat statbuf; |
207 int result = 0; |
233 int result = 0; |
208 |
234 |
209 RESTARTABLE(::lstat(path, &statbuf), result); |
235 RESTARTABLE(::lstat(path, &statbuf), result); |
210 if (result == OS_ERR) { |
236 if (result == OS_ERR) { |
211 return false; |
237 return false; |
212 } |
238 } |
213 |
239 |
214 // the path exists, now check it's mode |
240 // The path exists, see if it is secure. |
215 if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) { |
241 return is_statbuf_secure(&statbuf); |
216 // the path represents a link or some non-directory file type, |
242 } |
217 // which is not what we expected. declare it insecure. |
243 |
218 // |
244 // (Taken over from Solaris to support the O_NOFOLLOW case on AIX.) |
|
245 // Check if the given directory file descriptor is considered a secure |
|
246 // directory for the backing store files. Returns true if the directory |
|
247 // exists and is considered a secure location. Returns false if the path |
|
248 // is a symbolic link or if an error occurred. |
|
249 static bool is_dirfd_secure(int dir_fd) { |
|
250 struct stat statbuf; |
|
251 int result = 0; |
|
252 |
|
253 RESTARTABLE(::fstat(dir_fd, &statbuf), result); |
|
254 if (result == OS_ERR) { |
219 return false; |
255 return false; |
220 } |
256 } |
221 else { |
257 |
222 // we have an existing directory, check if the permissions are safe. |
258 // The path exists, now check its mode. |
223 // |
259 return is_statbuf_secure(&statbuf); |
224 if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) { |
260 } |
225 // the directory is open for writing and could be subjected |
261 |
226 // to a symlnk attack. declare it insecure. |
262 |
227 // |
263 // Check to make sure fd1 and fd2 are referencing the same file system object. |
228 return false; |
264 static bool is_same_fsobject(int fd1, int fd2) { |
229 } |
265 struct stat statbuf1; |
|
266 struct stat statbuf2; |
|
267 int result = 0; |
|
268 |
|
269 RESTARTABLE(::fstat(fd1, &statbuf1), result); |
|
270 if (result == OS_ERR) { |
|
271 return false; |
|
272 } |
|
273 RESTARTABLE(::fstat(fd2, &statbuf2), result); |
|
274 if (result == OS_ERR) { |
|
275 return false; |
|
276 } |
|
277 |
|
278 if ((statbuf1.st_ino == statbuf2.st_ino) && |
|
279 (statbuf1.st_dev == statbuf2.st_dev)) { |
|
280 return true; |
|
281 } else { |
|
282 return false; |
|
283 } |
|
284 } |
|
285 |
|
286 // Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1. |
|
287 // We use the jdk6 implementation here. |
|
288 #ifndef O_NOFOLLOW |
|
289 // The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour |
|
290 // was done in jdk 5/6 hotspot by Oracle this way |
|
291 static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) { |
|
292 struct stat orig_st; |
|
293 struct stat new_st; |
|
294 bool create; |
|
295 int error; |
|
296 int fd; |
|
297 |
|
298 create = false; |
|
299 |
|
300 if (lstat(path, &orig_st) != 0) { |
|
301 if (errno == ENOENT && (oflag & O_CREAT) != 0) { |
|
302 // File doesn't exist, but_we want to create it, add O_EXCL flag |
|
303 // to make sure no-one creates it (or a symlink) before us |
|
304 // This works as we expect with symlinks, from posix man page: |
|
305 // 'If O_EXCL and O_CREAT are set, and path names a symbolic |
|
306 // link, open() shall fail and set errno to [EEXIST]'. |
|
307 oflag |= O_EXCL; |
|
308 create = true; |
|
309 } else { |
|
310 // File doesn't exist, and we are not creating it. |
|
311 return OS_ERR; |
|
312 } |
|
313 } else { |
|
314 // Lstat success, check if existing file is a link. |
|
315 if ((orig_st.st_mode & S_IFMT) == S_IFLNK) { |
|
316 // File is a symlink. |
|
317 errno = ELOOP; |
|
318 return OS_ERR; |
|
319 } |
|
320 } |
|
321 |
|
322 if (use_mode == true) { |
|
323 fd = open(path, oflag, mode); |
|
324 } else { |
|
325 fd = open(path, oflag); |
|
326 } |
|
327 |
|
328 if (fd == OS_ERR) { |
|
329 return fd; |
|
330 } |
|
331 |
|
332 // Can't do inode checks on before/after if we created the file. |
|
333 if (create == false) { |
|
334 if (fstat(fd, &new_st) != 0) { |
|
335 // Keep errno from fstat, in case close also fails. |
|
336 error = errno; |
|
337 ::close(fd); |
|
338 errno = error; |
|
339 return OS_ERR; |
|
340 } |
|
341 |
|
342 if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) { |
|
343 // File was tampered with during race window. |
|
344 ::close(fd); |
|
345 errno = EEXIST; |
|
346 if (PrintMiscellaneous && Verbose) { |
|
347 warning("possible file tampering attempt detected when opening %s", path); |
|
348 } |
|
349 return OS_ERR; |
|
350 } |
|
351 } |
|
352 |
|
353 return fd; |
|
354 } |
|
355 |
|
356 static int open_o_nofollow(const char* path, int oflag, mode_t mode) { |
|
357 return open_o_nofollow_impl(path, oflag, mode, true); |
|
358 } |
|
359 |
|
360 static int open_o_nofollow(const char* path, int oflag) { |
|
361 return open_o_nofollow_impl(path, oflag, 0, false); |
|
362 } |
|
363 #endif |
|
364 |
|
365 // Open the directory of the given path and validate it. |
|
366 // Return a DIR * of the open directory. |
|
367 static DIR *open_directory_secure(const char* dirname) { |
|
368 // Open the directory using open() so that it can be verified |
|
369 // to be secure by calling is_dirfd_secure(), opendir() and then check |
|
370 // to see if they are the same file system object. This method does not |
|
371 // introduce a window of opportunity for the directory to be attacked that |
|
372 // calling opendir() and is_directory_secure() does. |
|
373 int result; |
|
374 DIR *dirp = NULL; |
|
375 |
|
376 // No O_NOFOLLOW defined at buildtime, and it is not documented for open; |
|
377 // so provide a workaround in this case. |
|
378 #ifdef O_NOFOLLOW |
|
379 RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result); |
|
380 #else |
|
381 // workaround (jdk6 coding) |
|
382 RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result); |
|
383 #endif |
|
384 |
|
385 if (result == OS_ERR) { |
|
386 // Directory doesn't exist or is a symlink, so there is nothing to cleanup. |
|
387 if (PrintMiscellaneous && Verbose) { |
|
388 if (errno == ELOOP) { |
|
389 warning("directory %s is a symlink and is not secure\n", dirname); |
|
390 } else { |
|
391 warning("could not open directory %s: %s\n", dirname, strerror(errno)); |
|
392 } |
|
393 } |
|
394 return dirp; |
|
395 } |
|
396 int fd = result; |
|
397 |
|
398 // Determine if the open directory is secure. |
|
399 if (!is_dirfd_secure(fd)) { |
|
400 // The directory is not a secure directory. |
|
401 os::close(fd); |
|
402 return dirp; |
|
403 } |
|
404 |
|
405 // Open the directory. |
|
406 dirp = ::opendir(dirname); |
|
407 if (dirp == NULL) { |
|
408 // The directory doesn't exist, close fd and return. |
|
409 os::close(fd); |
|
410 return dirp; |
|
411 } |
|
412 |
|
413 // Check to make sure fd and dirp are referencing the same file system object. |
|
414 if (!is_same_fsobject(fd, dirp->dd_fd)) { |
|
415 // The directory is not secure. |
|
416 os::close(fd); |
|
417 os::closedir(dirp); |
|
418 dirp = NULL; |
|
419 return dirp; |
|
420 } |
|
421 |
|
422 // Close initial open now that we know directory is secure |
|
423 os::close(fd); |
|
424 |
|
425 return dirp; |
|
426 } |
|
427 |
|
428 // NOTE: The code below uses fchdir(), open() and unlink() because |
|
429 // fdopendir(), openat() and unlinkat() are not supported on all |
|
430 // versions. Once the support for fdopendir(), openat() and unlinkat() |
|
431 // is available on all supported versions the code can be changed |
|
432 // to use these functions. |
|
433 |
|
434 // Open the directory of the given path, validate it and set the |
|
435 // current working directory to it. |
|
436 // Return a DIR * of the open directory and the saved cwd fd. |
|
437 // |
|
438 static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) { |
|
439 |
|
440 // Open the directory. |
|
441 DIR* dirp = open_directory_secure(dirname); |
|
442 if (dirp == NULL) { |
|
443 // Directory doesn't exist or is insecure, so there is nothing to cleanup. |
|
444 return dirp; |
|
445 } |
|
446 int fd = dirp->dd_fd; |
|
447 |
|
448 // Open a fd to the cwd and save it off. |
|
449 int result; |
|
450 RESTARTABLE(::open(".", O_RDONLY), result); |
|
451 if (result == OS_ERR) { |
|
452 *saved_cwd_fd = -1; |
|
453 } else { |
|
454 *saved_cwd_fd = result; |
|
455 } |
|
456 |
|
457 // Set the current directory to dirname by using the fd of the directory. |
|
458 result = fchdir(fd); |
|
459 |
|
460 return dirp; |
|
461 } |
|
462 |
|
463 // Close the directory and restore the current working directory. |
|
464 static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) { |
|
465 |
|
466 int result; |
|
467 // If we have a saved cwd change back to it and close the fd. |
|
468 if (saved_cwd_fd != -1) { |
|
469 result = fchdir(saved_cwd_fd); |
|
470 ::close(saved_cwd_fd); |
|
471 } |
|
472 |
|
473 // Close the directory. |
|
474 os::closedir(dirp); |
|
475 } |
|
476 |
|
477 // Check if the given file descriptor is considered a secure. |
|
478 static bool is_file_secure(int fd, const char *filename) { |
|
479 |
|
480 int result; |
|
481 struct stat statbuf; |
|
482 |
|
483 // Determine if the file is secure. |
|
484 RESTARTABLE(::fstat(fd, &statbuf), result); |
|
485 if (result == OS_ERR) { |
|
486 if (PrintMiscellaneous && Verbose) { |
|
487 warning("fstat failed on %s: %s\n", filename, strerror(errno)); |
|
488 } |
|
489 return false; |
|
490 } |
|
491 if (statbuf.st_nlink > 1) { |
|
492 // A file with multiple links is not expected. |
|
493 if (PrintMiscellaneous && Verbose) { |
|
494 warning("file %s has multiple links\n", filename); |
|
495 } |
|
496 return false; |
230 } |
497 } |
231 return true; |
498 return true; |
232 } |
499 } |
233 |
500 |
234 |
501 // Return the user name for the given user id. |
235 // return the user name for the given user id |
502 // |
236 // |
503 // The caller is expected to free the allocated memory. |
237 // the caller is expected to free the allocated memory. |
|
238 // |
|
239 static char* get_user_name(uid_t uid) { |
504 static char* get_user_name(uid_t uid) { |
240 |
505 |
241 struct passwd pwent; |
506 struct passwd pwent; |
242 |
507 |
243 // determine the max pwbuf size from sysconf, and hardcode |
508 // Determine the max pwbuf size from sysconf, and hardcode |
244 // a default if this not available through sysconf. |
509 // a default if this not available through sysconf. |
245 // |
|
246 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); |
510 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); |
247 if (bufsize == -1) |
511 if (bufsize == -1) |
248 bufsize = 1024; |
512 bufsize = 1024; |
249 |
513 |
250 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); |
514 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); |
462 " store file %s : %s\n", path, strerror(errno)); |
727 " store file %s : %s\n", path, strerror(errno)); |
463 } |
728 } |
464 } |
729 } |
465 } |
730 } |
466 |
731 |
467 |
732 // Cleanup stale shared memory resources |
468 // remove file |
|
469 // |
|
470 // this method removes the file with the given file name in the |
|
471 // named directory. |
|
472 // |
|
473 static void remove_file(const char* dirname, const char* filename) { |
|
474 |
|
475 size_t nbytes = strlen(dirname) + strlen(filename) + 2; |
|
476 char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
|
477 |
|
478 strcpy(path, dirname); |
|
479 strcat(path, "/"); |
|
480 strcat(path, filename); |
|
481 |
|
482 remove_file(path); |
|
483 |
|
484 FREE_C_HEAP_ARRAY(char, path, mtInternal); |
|
485 } |
|
486 |
|
487 |
|
488 // cleanup stale shared memory resources |
|
489 // |
733 // |
490 // This method attempts to remove all stale shared memory files in |
734 // This method attempts to remove all stale shared memory files in |
491 // the named user temporary directory. It scans the named directory |
735 // the named user temporary directory. It scans the named directory |
492 // for files matching the pattern ^$[0-9]*$. For each file found, the |
736 // for files matching the pattern ^$[0-9]*$. For each file found, the |
493 // process id is extracted from the file name and a test is run to |
737 // process id is extracted from the file name and a test is run to |
494 // determine if the process is alive. If the process is not alive, |
738 // determine if the process is alive. If the process is not alive, |
495 // any stale file resources are removed. |
739 // any stale file resources are removed. |
496 // |
|
497 static void cleanup_sharedmem_resources(const char* dirname) { |
740 static void cleanup_sharedmem_resources(const char* dirname) { |
498 |
741 |
499 // open the user temp directory |
742 int saved_cwd_fd; |
500 DIR* dirp = os::opendir(dirname); |
743 // Open the directory. |
501 |
744 DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd); |
502 if (dirp == NULL) { |
745 if (dirp == NULL) { |
503 // directory doesn't exist, so there is nothing to cleanup |
746 // Directory doesn't exist or is insecure, so there is nothing to cleanup. |
504 return; |
747 return; |
505 } |
748 } |
506 |
749 |
507 if (!is_directory_secure(dirname)) { |
750 // For each entry in the directory that matches the expected file |
508 // the directory is not a secure directory |
|
509 return; |
|
510 } |
|
511 |
|
512 // for each entry in the directory that matches the expected file |
|
513 // name pattern, determine if the file resources are stale and if |
751 // name pattern, determine if the file resources are stale and if |
514 // so, remove the file resources. Note, instrumented HotSpot processes |
752 // so, remove the file resources. Note, instrumented HotSpot processes |
515 // for this user may start and/or terminate during this search and |
753 // for this user may start and/or terminate during this search and |
516 // remove or create new files in this directory. The behavior of this |
754 // remove or create new files in this directory. The behavior of this |
517 // loop under these conditions is dependent upon the implementation of |
755 // loop under these conditions is dependent upon the implementation of |
518 // opendir/readdir. |
756 // opendir/readdir. |
519 // |
|
520 struct dirent* entry; |
757 struct dirent* entry; |
521 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); |
758 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); |
|
759 |
522 errno = 0; |
760 errno = 0; |
523 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { |
761 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { |
524 |
762 |
525 pid_t pid = filename_to_pid(entry->d_name); |
763 pid_t pid = filename_to_pid(entry->d_name); |
526 |
764 |
527 if (pid == 0) { |
765 if (pid == 0) { |
528 |
766 |
529 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
767 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
530 |
768 |
531 // attempt to remove all unexpected files, except "." and ".." |
769 // Attempt to remove all unexpected files, except "." and "..". |
532 remove_file(dirname, entry->d_name); |
770 unlink(entry->d_name); |
533 } |
771 } |
534 |
772 |
535 errno = 0; |
773 errno = 0; |
536 continue; |
774 continue; |
537 } |
775 } |
538 |
776 |
539 // we now have a file name that converts to a valid integer |
777 // We now have a file name that converts to a valid integer |
540 // that could represent a process id . if this process id |
778 // that could represent a process id . if this process id |
541 // matches the current process id or the process is not running, |
779 // matches the current process id or the process is not running, |
542 // then remove the stale file resources. |
780 // then remove the stale file resources. |
543 // |
781 // |
544 // process liveness is detected by sending signal number 0 to |
782 // Process liveness is detected by sending signal number 0 to |
545 // the process id (see kill(2)). if kill determines that the |
783 // the process id (see kill(2)). if kill determines that the |
546 // process does not exist, then the file resources are removed. |
784 // process does not exist, then the file resources are removed. |
547 // if kill determines that that we don't have permission to |
785 // if kill determines that that we don't have permission to |
548 // signal the process, then the file resources are assumed to |
786 // signal the process, then the file resources are assumed to |
549 // be stale and are removed because the resources for such a |
787 // be stale and are removed because the resources for such a |
550 // process should be in a different user specific directory. |
788 // process should be in a different user specific directory. |
551 // |
|
552 if ((pid == os::current_process_id()) || |
789 if ((pid == os::current_process_id()) || |
553 (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) { |
790 (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) { |
554 |
791 |
555 remove_file(dirname, entry->d_name); |
792 unlink(entry->d_name); |
556 } |
793 } |
557 errno = 0; |
794 errno = 0; |
558 } |
795 } |
559 os::closedir(dirp); |
796 |
|
797 // Close the directory and reset the current working directory. |
|
798 close_directory_secure_cwd(dirp, saved_cwd_fd); |
|
799 |
560 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); |
800 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); |
561 } |
801 } |
562 |
802 |
563 // make the user specific temporary directory. Returns true if |
803 // Make the user specific temporary directory. Returns true if |
564 // the directory exists and is secure upon return. Returns false |
804 // the directory exists and is secure upon return. Returns false |
565 // if the directory exists but is either a symlink, is otherwise |
805 // if the directory exists but is either a symlink, is otherwise |
566 // insecure, or if an error occurred. |
806 // insecure, or if an error occurred. |
567 // |
|
568 static bool make_user_tmp_dir(const char* dirname) { |
807 static bool make_user_tmp_dir(const char* dirname) { |
569 |
808 |
570 // create the directory with 0755 permissions. note that the directory |
809 // Create the directory with 0755 permissions. note that the directory |
571 // will be owned by euid::egid, which may not be the same as uid::gid. |
810 // will be owned by euid::egid, which may not be the same as uid::gid. |
572 // |
|
573 if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) { |
811 if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) { |
574 if (errno == EEXIST) { |
812 if (errno == EEXIST) { |
575 // The directory already exists and was probably created by another |
813 // The directory already exists and was probably created by another |
576 // JVM instance. However, this could also be the result of a |
814 // JVM instance. However, this could also be the result of a |
577 // deliberate symlink. Verify that the existing directory is safe. |
815 // deliberate symlink. Verify that the existing directory is safe. |
578 // |
|
579 if (!is_directory_secure(dirname)) { |
816 if (!is_directory_secure(dirname)) { |
580 // directory is not secure |
817 // Directory is not secure. |
581 if (PrintMiscellaneous && Verbose) { |
818 if (PrintMiscellaneous && Verbose) { |
582 warning("%s directory is insecure\n", dirname); |
819 warning("%s directory is insecure\n", dirname); |
583 } |
820 } |
584 return false; |
821 return false; |
585 } |
822 } |
611 // could not make/find the directory or the found directory |
848 // could not make/find the directory or the found directory |
612 // was not secure |
849 // was not secure |
613 return -1; |
850 return -1; |
614 } |
851 } |
615 |
852 |
|
853 int saved_cwd_fd; |
|
854 // Open the directory and set the current working directory to it. |
|
855 DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd); |
|
856 if (dirp == NULL) { |
|
857 // Directory doesn't exist or is insecure, so cannot create shared |
|
858 // memory file. |
|
859 return -1; |
|
860 } |
|
861 |
|
862 // Open the filename in the current directory. |
|
863 // Cannot use O_TRUNC here; truncation of an existing file has to happen |
|
864 // after the is_file_secure() check below. |
616 int result; |
865 int result; |
617 |
866 |
618 RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result); |
867 // No O_NOFOLLOW defined at buildtime, and it is not documented for open; |
|
868 // so provide a workaround in this case. |
|
869 #ifdef O_NOFOLLOW |
|
870 RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result); |
|
871 #else |
|
872 // workaround function (jdk6 code) |
|
873 RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result); |
|
874 #endif |
|
875 |
619 if (result == OS_ERR) { |
876 if (result == OS_ERR) { |
620 if (PrintMiscellaneous && Verbose) { |
877 if (PrintMiscellaneous && Verbose) { |
621 warning("could not create file %s: %s\n", filename, strerror(errno)); |
878 if (errno == ELOOP) { |
622 } |
879 warning("file %s is a symlink and is not secure\n", filename); |
|
880 } else { |
|
881 warning("could not create file %s: %s\n", filename, strerror(errno)); |
|
882 } |
|
883 } |
|
884 // Close the directory and reset the current working directory. |
|
885 close_directory_secure_cwd(dirp, saved_cwd_fd); |
|
886 |
623 return -1; |
887 return -1; |
624 } |
888 } |
|
889 // Close the directory and reset the current working directory. |
|
890 close_directory_secure_cwd(dirp, saved_cwd_fd); |
625 |
891 |
626 // save the file descriptor |
892 // save the file descriptor |
627 int fd = result; |
893 int fd = result; |
628 |
894 |
|
895 // Check to see if the file is secure. |
|
896 if (!is_file_secure(fd, filename)) { |
|
897 ::close(fd); |
|
898 return -1; |
|
899 } |
|
900 |
|
901 // Truncate the file to get rid of any existing data. |
|
902 RESTARTABLE(::ftruncate(fd, (off_t)0), result); |
|
903 if (result == OS_ERR) { |
|
904 if (PrintMiscellaneous && Verbose) { |
|
905 warning("could not truncate shared memory file: %s\n", strerror(errno)); |
|
906 } |
|
907 ::close(fd); |
|
908 return -1; |
|
909 } |
629 // set the file size |
910 // set the file size |
630 RESTARTABLE(::ftruncate(fd, (off_t)size), result); |
911 RESTARTABLE(::ftruncate(fd, (off_t)size), result); |
631 if (result == OS_ERR) { |
912 if (result == OS_ERR) { |
632 if (PrintMiscellaneous && Verbose) { |
913 if (PrintMiscellaneous && Verbose) { |
633 warning("could not set shared memory file size: %s\n", strerror(errno)); |
914 warning("could not set shared memory file size: %s\n", strerror(errno)); |