8062675: jmap is unable to display information about java processes and prints only pids

Mon, 10 Nov 2014 09:47:41 -0800

author
asaha
date
Mon, 10 Nov 2014 09:47:41 -0800
changeset 7711
fb677d6aebea
parent 7710
b1cf34d57e78
child 7712
9a227eaac2dc

8062675: jmap is unable to display information about java processes and prints only pids
Summary: backout fix 8050808 which caused this regression and as requested.
Reviewed-by: hseigel

src/os/bsd/vm/perfMemory_bsd.cpp file | annotate | diff | comparison | revisions
src/os/linux/vm/perfMemory_linux.cpp file | annotate | diff | comparison | revisions
src/os/solaris/vm/perfMemory_solaris.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/vmError.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/bsd/vm/perfMemory_bsd.cpp	Thu Nov 06 09:39:49 2014 -0800
     1.2 +++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Mon Nov 10 09:47:41 2014 -0800
     1.3 @@ -197,38 +197,7 @@
     1.4  }
     1.5  
     1.6  
     1.7 -// Check if the given statbuf is considered a secure directory for
     1.8 -// the backing store files. Returns true if the directory is considered
     1.9 -// a secure location. Returns false if the statbuf is a symbolic link or
    1.10 -// if an error occurred.
    1.11 -//
    1.12 -static bool is_statbuf_secure(struct stat *statp) {
    1.13 -  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
    1.14 -    // The path represents a link or some non-directory file type,
    1.15 -    // which is not what we expected. Declare it insecure.
    1.16 -    //
    1.17 -    return false;
    1.18 -  }
    1.19 -  // We have an existing directory, check if the permissions are safe.
    1.20 -  //
    1.21 -  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
    1.22 -    // The directory is open for writing and could be subjected
    1.23 -    // to a symlink or a hard link attack. Declare it insecure.
    1.24 -    //
    1.25 -    return false;
    1.26 -  }
    1.27 -  // See if the uid of the directory matches the effective uid of the process.
    1.28 -  //
    1.29 -  if (statp->st_uid != geteuid()) {
    1.30 -    // The directory was not created by this user, declare it insecure.
    1.31 -    //
    1.32 -    return false;
    1.33 -  }
    1.34 -  return true;
    1.35 -}
    1.36 -
    1.37 -
    1.38 -// Check if the given path is considered a secure directory for
    1.39 +// check if the given path is considered a secure directory for
    1.40  // the backing store files. Returns true if the directory exists
    1.41  // and is considered a secure location. Returns false if the path
    1.42  // is a symbolic link or if an error occurred.
    1.43 @@ -242,185 +211,27 @@
    1.44      return false;
    1.45    }
    1.46  
    1.47 -  // The path exists, see if it is secure.
    1.48 -  return is_statbuf_secure(&statbuf);
    1.49 -}
    1.50 -
    1.51 -
    1.52 -// Check if the given directory file descriptor is considered a secure
    1.53 -// directory for the backing store files. Returns true if the directory
    1.54 -// exists and is considered a secure location. Returns false if the path
    1.55 -// is a symbolic link or if an error occurred.
    1.56 -//
    1.57 -static bool is_dirfd_secure(int dir_fd) {
    1.58 -  struct stat statbuf;
    1.59 -  int result = 0;
    1.60 -
    1.61 -  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
    1.62 -  if (result == OS_ERR) {
    1.63 +  // the path exists, now check it's mode
    1.64 +  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
    1.65 +    // the path represents a link or some non-directory file type,
    1.66 +    // which is not what we expected. declare it insecure.
    1.67 +    //
    1.68      return false;
    1.69    }
    1.70 -
    1.71 -  // The path exists, now check its mode.
    1.72 -  return is_statbuf_secure(&statbuf);
    1.73 -}
    1.74 -
    1.75 -
    1.76 -// Check to make sure fd1 and fd2 are referencing the same file system object.
    1.77 -//
    1.78 -static bool is_same_fsobject(int fd1, int fd2) {
    1.79 -  struct stat statbuf1;
    1.80 -  struct stat statbuf2;
    1.81 -  int result = 0;
    1.82 -
    1.83 -  RESTARTABLE(::fstat(fd1, &statbuf1), result);
    1.84 -  if (result == OS_ERR) {
    1.85 -    return false;
    1.86 -  }
    1.87 -  RESTARTABLE(::fstat(fd2, &statbuf2), result);
    1.88 -  if (result == OS_ERR) {
    1.89 -    return false;
    1.90 -  }
    1.91 -
    1.92 -  if ((statbuf1.st_ino == statbuf2.st_ino) &&
    1.93 -      (statbuf1.st_dev == statbuf2.st_dev)) {
    1.94 -    return true;
    1.95 -  } else {
    1.96 -    return false;
    1.97 -  }
    1.98 -}
    1.99 -
   1.100 -
   1.101 -// Open the directory of the given path and validate it.
   1.102 -// Return a DIR * of the open directory.
   1.103 -//
   1.104 -static DIR *open_directory_secure(const char* dirname) {
   1.105 -  // Open the directory using open() so that it can be verified
   1.106 -  // to be secure by calling is_dirfd_secure(), opendir() and then check
   1.107 -  // to see if they are the same file system object.  This method does not
   1.108 -  // introduce a window of opportunity for the directory to be attacked that
   1.109 -  // calling opendir() and is_directory_secure() does.
   1.110 -  int result;
   1.111 -  DIR *dirp = NULL;
   1.112 -  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
   1.113 -  if (result == OS_ERR) {
   1.114 -    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
   1.115 -    if (PrintMiscellaneous && Verbose) {
   1.116 -      if (errno == ELOOP) {
   1.117 -        warning("directory %s is a symlink and is not secure\n", dirname);
   1.118 -      } else {
   1.119 -        warning("could not open directory %s: %s\n", dirname, strerror(errno));
   1.120 -      }
   1.121 +  else {
   1.122 +    // we have an existing directory, check if the permissions are safe.
   1.123 +    //
   1.124 +    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
   1.125 +      // the directory is open for writing and could be subjected
   1.126 +      // to a symlnk attack. declare it insecure.
   1.127 +      //
   1.128 +      return false;
   1.129      }
   1.130 -    return dirp;
   1.131 -  }
   1.132 -  int fd = result;
   1.133 -
   1.134 -  // Determine if the open directory is secure.
   1.135 -  if (!is_dirfd_secure(fd)) {
   1.136 -    // The directory is not a secure directory.
   1.137 -    os::close(fd);
   1.138 -    return dirp;
   1.139 -  }
   1.140 -
   1.141 -  // Open the directory.
   1.142 -  dirp = ::opendir(dirname);
   1.143 -  if (dirp == NULL) {
   1.144 -    // The directory doesn't exist, close fd and return.
   1.145 -    os::close(fd);
   1.146 -    return dirp;
   1.147 -  }
   1.148 -
   1.149 -  // Check to make sure fd and dirp are referencing the same file system object.
   1.150 -  if (!is_same_fsobject(fd, dirfd(dirp))) {
   1.151 -    // The directory is not secure.
   1.152 -    os::close(fd);
   1.153 -    os::closedir(dirp);
   1.154 -    dirp = NULL;
   1.155 -    return dirp;
   1.156 -  }
   1.157 -
   1.158 -  // Close initial open now that we know directory is secure
   1.159 -  os::close(fd);
   1.160 -
   1.161 -  return dirp;
   1.162 -}
   1.163 -
   1.164 -// NOTE: The code below uses fchdir(), open() and unlink() because
   1.165 -// fdopendir(), openat() and unlinkat() are not supported on all
   1.166 -// versions.  Once the support for fdopendir(), openat() and unlinkat()
   1.167 -// is available on all supported versions the code can be changed
   1.168 -// to use these functions.
   1.169 -
   1.170 -// Open the directory of the given path, validate it and set the
   1.171 -// current working directory to it.
   1.172 -// Return a DIR * of the open directory and the saved cwd fd.
   1.173 -//
   1.174 -static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
   1.175 -
   1.176 -  // Open the directory.
   1.177 -  DIR* dirp = open_directory_secure(dirname);
   1.178 -  if (dirp == NULL) {
   1.179 -    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
   1.180 -    return dirp;
   1.181 -  }
   1.182 -  int fd = dirfd(dirp);
   1.183 -
   1.184 -  // Open a fd to the cwd and save it off.
   1.185 -  int result;
   1.186 -  RESTARTABLE(::open(".", O_RDONLY), result);
   1.187 -  if (result == OS_ERR) {
   1.188 -    *saved_cwd_fd = -1;
   1.189 -  } else {
   1.190 -    *saved_cwd_fd = result;
   1.191 -  }
   1.192 -
   1.193 -  // Set the current directory to dirname by using the fd of the directory.
   1.194 -  result = fchdir(fd);
   1.195 -
   1.196 -  return dirp;
   1.197 -}
   1.198 -
   1.199 -// Close the directory and restore the current working directory.
   1.200 -//
   1.201 -static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
   1.202 -
   1.203 -  int result;
   1.204 -  // If we have a saved cwd change back to it and close the fd.
   1.205 -  if (saved_cwd_fd != -1) {
   1.206 -    result = fchdir(saved_cwd_fd);
   1.207 -    ::close(saved_cwd_fd);
   1.208 -  }
   1.209 -
   1.210 -  // Close the directory.
   1.211 -  os::closedir(dirp);
   1.212 -}
   1.213 -
   1.214 -// Check if the given file descriptor is considered a secure.
   1.215 -//
   1.216 -static bool is_file_secure(int fd, const char *filename) {
   1.217 -
   1.218 -  int result;
   1.219 -  struct stat statbuf;
   1.220 -
   1.221 -  // Determine if the file is secure.
   1.222 -  RESTARTABLE(::fstat(fd, &statbuf), result);
   1.223 -  if (result == OS_ERR) {
   1.224 -    if (PrintMiscellaneous && Verbose) {
   1.225 -      warning("fstat failed on %s: %s\n", filename, strerror(errno));
   1.226 -    }
   1.227 -    return false;
   1.228 -  }
   1.229 -  if (statbuf.st_nlink > 1) {
   1.230 -    // A file with multiple links is not expected.
   1.231 -    if (PrintMiscellaneous && Verbose) {
   1.232 -      warning("file %s has multiple links\n", filename);
   1.233 -    }
   1.234 -    return false;
   1.235    }
   1.236    return true;
   1.237  }
   1.238  
   1.239 +
   1.240  // return the user name for the given user id
   1.241  //
   1.242  // the caller is expected to free the allocated memory.
   1.243 @@ -506,10 +317,9 @@
   1.244  
   1.245    const char* tmpdirname = os::get_temp_directory();
   1.246  
   1.247 -  // open the temp directory
   1.248 -  DIR* tmpdirp = open_directory_secure(tmpdirname);
   1.249 +  DIR* tmpdirp = os::opendir(tmpdirname);
   1.250 +
   1.251    if (tmpdirp == NULL) {
   1.252 -    // Cannot open the directory to get the user name, return.
   1.253      return NULL;
   1.254    }
   1.255  
   1.256 @@ -534,14 +344,25 @@
   1.257      strcat(usrdir_name, "/");
   1.258      strcat(usrdir_name, dentry->d_name);
   1.259  
   1.260 -    // open the user directory
   1.261 -    DIR* subdirp = open_directory_secure(usrdir_name);
   1.262 +    DIR* subdirp = os::opendir(usrdir_name);
   1.263  
   1.264      if (subdirp == NULL) {
   1.265        FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   1.266        continue;
   1.267      }
   1.268  
   1.269 +    // Since we don't create the backing store files in directories
   1.270 +    // pointed to by symbolic links, we also don't follow them when
   1.271 +    // looking for the files. We check for a symbolic link after the
   1.272 +    // call to opendir in order to eliminate a small window where the
   1.273 +    // symlink can be exploited.
   1.274 +    //
   1.275 +    if (!is_directory_secure(usrdir_name)) {
   1.276 +      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   1.277 +      os::closedir(subdirp);
   1.278 +      continue;
   1.279 +    }
   1.280 +
   1.281      struct dirent* udentry;
   1.282      char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
   1.283      errno = 0;
   1.284 @@ -644,6 +465,26 @@
   1.285  }
   1.286  
   1.287  
   1.288 +// remove file
   1.289 +//
   1.290 +// this method removes the file with the given file name in the
   1.291 +// named directory.
   1.292 +//
   1.293 +static void remove_file(const char* dirname, const char* filename) {
   1.294 +
   1.295 +  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
   1.296 +  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   1.297 +
   1.298 +  strcpy(path, dirname);
   1.299 +  strcat(path, "/");
   1.300 +  strcat(path, filename);
   1.301 +
   1.302 +  remove_file(path);
   1.303 +
   1.304 +  FREE_C_HEAP_ARRAY(char, path, mtInternal);
   1.305 +}
   1.306 +
   1.307 +
   1.308  // cleanup stale shared memory resources
   1.309  //
   1.310  // This method attempts to remove all stale shared memory files in
   1.311 @@ -655,11 +496,16 @@
   1.312  //
   1.313  static void cleanup_sharedmem_resources(const char* dirname) {
   1.314  
   1.315 -  int saved_cwd_fd;
   1.316 -  // open the directory and set the current working directory to it
   1.317 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   1.318 +  // open the user temp directory
   1.319 +  DIR* dirp = os::opendir(dirname);
   1.320 +
   1.321    if (dirp == NULL) {
   1.322 -    // directory doesn't exist or is insecure, so there is nothing to cleanup
   1.323 +    // directory doesn't exist, so there is nothing to cleanup
   1.324 +    return;
   1.325 +  }
   1.326 +
   1.327 +  if (!is_directory_secure(dirname)) {
   1.328 +    // the directory is not a secure directory
   1.329      return;
   1.330    }
   1.331  
   1.332 @@ -673,7 +519,6 @@
   1.333    //
   1.334    struct dirent* entry;
   1.335    char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   1.336 -
   1.337    errno = 0;
   1.338    while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
   1.339  
   1.340 @@ -684,7 +529,7 @@
   1.341        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
   1.342  
   1.343          // attempt to remove all unexpected files, except "." and ".."
   1.344 -        unlink(entry->d_name);
   1.345 +        remove_file(dirname, entry->d_name);
   1.346        }
   1.347  
   1.348        errno = 0;
   1.349 @@ -707,14 +552,11 @@
   1.350      if ((pid == os::current_process_id()) ||
   1.351          (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
   1.352  
   1.353 -        unlink(entry->d_name);
   1.354 +        remove_file(dirname, entry->d_name);
   1.355      }
   1.356      errno = 0;
   1.357    }
   1.358 -
   1.359 -  // close the directory and reset the current working directory
   1.360 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   1.361 -
   1.362 +  os::closedir(dirp);
   1.363    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
   1.364  }
   1.365  
   1.366 @@ -771,54 +613,19 @@
   1.367      return -1;
   1.368    }
   1.369  
   1.370 -  int saved_cwd_fd;
   1.371 -  // open the directory and set the current working directory to it
   1.372 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   1.373 -  if (dirp == NULL) {
   1.374 -    // Directory doesn't exist or is insecure, so cannot create shared
   1.375 -    // memory file.
   1.376 +  int result;
   1.377 +
   1.378 +  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
   1.379 +  if (result == OS_ERR) {
   1.380 +    if (PrintMiscellaneous && Verbose) {
   1.381 +      warning("could not create file %s: %s\n", filename, strerror(errno));
   1.382 +    }
   1.383      return -1;
   1.384    }
   1.385  
   1.386 -  // Open the filename in the current directory.
   1.387 -  // Cannot use O_TRUNC here; truncation of an existing file has to happen
   1.388 -  // after the is_file_secure() check below.
   1.389 -  int result;
   1.390 -  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   1.391 -  if (result == OS_ERR) {
   1.392 -    if (PrintMiscellaneous && Verbose) {
   1.393 -      if (errno == ELOOP) {
   1.394 -        warning("file %s is a symlink and is not secure\n", filename);
   1.395 -      } else {
   1.396 -        warning("could not create file %s: %s\n", filename, strerror(errno));
   1.397 -      }
   1.398 -    }
   1.399 -    // close the directory and reset the current working directory
   1.400 -    close_directory_secure_cwd(dirp, saved_cwd_fd);
   1.401 -
   1.402 -    return -1;
   1.403 -  }
   1.404 -  // close the directory and reset the current working directory
   1.405 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   1.406 -
   1.407    // save the file descriptor
   1.408    int fd = result;
   1.409  
   1.410 -  // check to see if the file is secure
   1.411 -  if (!is_file_secure(fd, filename)) {
   1.412 -    ::close(fd);
   1.413 -    return -1;
   1.414 -  }
   1.415 -
   1.416 -  // truncate the file to get rid of any existing data
   1.417 -  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   1.418 -  if (result == OS_ERR) {
   1.419 -    if (PrintMiscellaneous && Verbose) {
   1.420 -      warning("could not truncate shared memory file: %s\n", strerror(errno));
   1.421 -    }
   1.422 -    ::close(fd);
   1.423 -    return -1;
   1.424 -  }
   1.425    // set the file size
   1.426    RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   1.427    if (result == OS_ERR) {
   1.428 @@ -876,15 +683,8 @@
   1.429        THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
   1.430      }
   1.431    }
   1.432 -  int fd = result;
   1.433  
   1.434 -  // check to see if the file is secure
   1.435 -  if (!is_file_secure(fd, filename)) {
   1.436 -    ::close(fd);
   1.437 -    return -1;
   1.438 -  }
   1.439 -
   1.440 -  return fd;
   1.441 +  return result;
   1.442  }
   1.443  
   1.444  // create a named shared memory region. returns the address of the
   1.445 @@ -916,21 +716,13 @@
   1.446    char* dirname = get_user_tmp_dir(user_name);
   1.447    char* filename = get_sharedmem_filename(dirname, vmid);
   1.448  
   1.449 -  // get the short filename
   1.450 -  char* short_filename = strrchr(filename, '/');
   1.451 -  if (short_filename == NULL) {
   1.452 -    short_filename = filename;
   1.453 -  } else {
   1.454 -    short_filename++;
   1.455 -  }
   1.456 -
   1.457    // cleanup any stale shared memory files
   1.458    cleanup_sharedmem_resources(dirname);
   1.459  
   1.460    assert(((size > 0) && (size % os::vm_page_size() == 0)),
   1.461           "unexpected PerfMemory region size");
   1.462  
   1.463 -  fd = create_sharedmem_resources(dirname, short_filename, size);
   1.464 +  fd = create_sharedmem_resources(dirname, filename, size);
   1.465  
   1.466    FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
   1.467    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
   1.468 @@ -1045,12 +837,12 @@
   1.469    // constructs for the file and the shared memory mapping.
   1.470    if (mode == PerfMemory::PERF_MODE_RO) {
   1.471      mmap_prot = PROT_READ;
   1.472 -    file_flags = O_RDONLY | O_NOFOLLOW;
   1.473 +    file_flags = O_RDONLY;
   1.474    }
   1.475    else if (mode == PerfMemory::PERF_MODE_RW) {
   1.476  #ifdef LATER
   1.477      mmap_prot = PROT_READ | PROT_WRITE;
   1.478 -    file_flags = O_RDWR | O_NOFOLLOW;
   1.479 +    file_flags = O_RDWR;
   1.480  #else
   1.481      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.482                "Unsupported access mode");
     2.1 --- a/src/os/linux/vm/perfMemory_linux.cpp	Thu Nov 06 09:39:49 2014 -0800
     2.2 +++ b/src/os/linux/vm/perfMemory_linux.cpp	Mon Nov 10 09:47:41 2014 -0800
     2.3 @@ -197,38 +197,7 @@
     2.4  }
     2.5  
     2.6  
     2.7 -// Check if the given statbuf is considered a secure directory for
     2.8 -// the backing store files. Returns true if the directory is considered
     2.9 -// a secure location. Returns false if the statbuf is a symbolic link or
    2.10 -// if an error occurred.
    2.11 -//
    2.12 -static bool is_statbuf_secure(struct stat *statp) {
    2.13 -  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
    2.14 -    // The path represents a link or some non-directory file type,
    2.15 -    // which is not what we expected. Declare it insecure.
    2.16 -    //
    2.17 -    return false;
    2.18 -  }
    2.19 -  // We have an existing directory, check if the permissions are safe.
    2.20 -  //
    2.21 -  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
    2.22 -    // The directory is open for writing and could be subjected
    2.23 -    // to a symlink or a hard link attack. Declare it insecure.
    2.24 -    //
    2.25 -    return false;
    2.26 -  }
    2.27 -  // See if the uid of the directory matches the effective uid of the process.
    2.28 -  //
    2.29 -  if (statp->st_uid != geteuid()) {
    2.30 -    // The directory was not created by this user, declare it insecure.
    2.31 -    //
    2.32 -    return false;
    2.33 -  }
    2.34 -  return true;
    2.35 -}
    2.36 -
    2.37 -
    2.38 -// Check if the given path is considered a secure directory for
    2.39 +// check if the given path is considered a secure directory for
    2.40  // the backing store files. Returns true if the directory exists
    2.41  // and is considered a secure location. Returns false if the path
    2.42  // is a symbolic link or if an error occurred.
    2.43 @@ -242,181 +211,22 @@
    2.44      return false;
    2.45    }
    2.46  
    2.47 -  // The path exists, see if it is secure.
    2.48 -  return is_statbuf_secure(&statbuf);
    2.49 -}
    2.50 -
    2.51 -
    2.52 -// Check if the given directory file descriptor is considered a secure
    2.53 -// directory for the backing store files. Returns true if the directory
    2.54 -// exists and is considered a secure location. Returns false if the path
    2.55 -// is a symbolic link or if an error occurred.
    2.56 -//
    2.57 -static bool is_dirfd_secure(int dir_fd) {
    2.58 -  struct stat statbuf;
    2.59 -  int result = 0;
    2.60 -
    2.61 -  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
    2.62 -  if (result == OS_ERR) {
    2.63 +  // the path exists, now check it's mode
    2.64 +  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
    2.65 +    // the path represents a link or some non-directory file type,
    2.66 +    // which is not what we expected. declare it insecure.
    2.67 +    //
    2.68      return false;
    2.69    }
    2.70 -
    2.71 -  // The path exists, now check its mode.
    2.72 -  return is_statbuf_secure(&statbuf);
    2.73 -}
    2.74 -
    2.75 -
    2.76 -// Check to make sure fd1 and fd2 are referencing the same file system object.
    2.77 -//
    2.78 -static bool is_same_fsobject(int fd1, int fd2) {
    2.79 -  struct stat statbuf1;
    2.80 -  struct stat statbuf2;
    2.81 -  int result = 0;
    2.82 -
    2.83 -  RESTARTABLE(::fstat(fd1, &statbuf1), result);
    2.84 -  if (result == OS_ERR) {
    2.85 -    return false;
    2.86 -  }
    2.87 -  RESTARTABLE(::fstat(fd2, &statbuf2), result);
    2.88 -  if (result == OS_ERR) {
    2.89 -    return false;
    2.90 -  }
    2.91 -
    2.92 -  if ((statbuf1.st_ino == statbuf2.st_ino) &&
    2.93 -      (statbuf1.st_dev == statbuf2.st_dev)) {
    2.94 -    return true;
    2.95 -  } else {
    2.96 -    return false;
    2.97 -  }
    2.98 -}
    2.99 -
   2.100 -
   2.101 -// Open the directory of the given path and validate it.
   2.102 -// Return a DIR * of the open directory.
   2.103 -//
   2.104 -static DIR *open_directory_secure(const char* dirname) {
   2.105 -  // Open the directory using open() so that it can be verified
   2.106 -  // to be secure by calling is_dirfd_secure(), opendir() and then check
   2.107 -  // to see if they are the same file system object.  This method does not
   2.108 -  // introduce a window of opportunity for the directory to be attacked that
   2.109 -  // calling opendir() and is_directory_secure() does.
   2.110 -  int result;
   2.111 -  DIR *dirp = NULL;
   2.112 -  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
   2.113 -  if (result == OS_ERR) {
   2.114 -    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
   2.115 -    if (PrintMiscellaneous && Verbose) {
   2.116 -      if (errno == ELOOP) {
   2.117 -        warning("directory %s is a symlink and is not secure\n", dirname);
   2.118 -      } else {
   2.119 -        warning("could not open directory %s: %s\n", dirname, strerror(errno));
   2.120 -      }
   2.121 +  else {
   2.122 +    // we have an existing directory, check if the permissions are safe.
   2.123 +    //
   2.124 +    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
   2.125 +      // the directory is open for writing and could be subjected
   2.126 +      // to a symlnk attack. declare it insecure.
   2.127 +      //
   2.128 +      return false;
   2.129      }
   2.130 -    return dirp;
   2.131 -  }
   2.132 -  int fd = result;
   2.133 -
   2.134 -  // Determine if the open directory is secure.
   2.135 -  if (!is_dirfd_secure(fd)) {
   2.136 -    // The directory is not a secure directory.
   2.137 -    os::close(fd);
   2.138 -    return dirp;
   2.139 -  }
   2.140 -
   2.141 -  // Open the directory.
   2.142 -  dirp = ::opendir(dirname);
   2.143 -  if (dirp == NULL) {
   2.144 -    // The directory doesn't exist, close fd and return.
   2.145 -    os::close(fd);
   2.146 -    return dirp;
   2.147 -  }
   2.148 -
   2.149 -  // Check to make sure fd and dirp are referencing the same file system object.
   2.150 -  if (!is_same_fsobject(fd, dirfd(dirp))) {
   2.151 -    // The directory is not secure.
   2.152 -    os::close(fd);
   2.153 -    os::closedir(dirp);
   2.154 -    dirp = NULL;
   2.155 -    return dirp;
   2.156 -  }
   2.157 -
   2.158 -  // Close initial open now that we know directory is secure
   2.159 -  os::close(fd);
   2.160 -
   2.161 -  return dirp;
   2.162 -}
   2.163 -
   2.164 -// NOTE: The code below uses fchdir(), open() and unlink() because
   2.165 -// fdopendir(), openat() and unlinkat() are not supported on all
   2.166 -// versions.  Once the support for fdopendir(), openat() and unlinkat()
   2.167 -// is available on all supported versions the code can be changed
   2.168 -// to use these functions.
   2.169 -
   2.170 -// Open the directory of the given path, validate it and set the
   2.171 -// current working directory to it.
   2.172 -// Return a DIR * of the open directory and the saved cwd fd.
   2.173 -//
   2.174 -static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
   2.175 -
   2.176 -  // Open the directory.
   2.177 -  DIR* dirp = open_directory_secure(dirname);
   2.178 -  if (dirp == NULL) {
   2.179 -    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
   2.180 -    return dirp;
   2.181 -  }
   2.182 -  int fd = dirfd(dirp);
   2.183 -
   2.184 -  // Open a fd to the cwd and save it off.
   2.185 -  int result;
   2.186 -  RESTARTABLE(::open(".", O_RDONLY), result);
   2.187 -  if (result == OS_ERR) {
   2.188 -    *saved_cwd_fd = -1;
   2.189 -  } else {
   2.190 -    *saved_cwd_fd = result;
   2.191 -  }
   2.192 -
   2.193 -  // Set the current directory to dirname by using the fd of the directory.
   2.194 -  result = fchdir(fd);
   2.195 -
   2.196 -  return dirp;
   2.197 -}
   2.198 -
   2.199 -// Close the directory and restore the current working directory.
   2.200 -//
   2.201 -static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
   2.202 -
   2.203 -  int result;
   2.204 -  // If we have a saved cwd change back to it and close the fd.
   2.205 -  if (saved_cwd_fd != -1) {
   2.206 -    result = fchdir(saved_cwd_fd);
   2.207 -    ::close(saved_cwd_fd);
   2.208 -  }
   2.209 -
   2.210 -  // Close the directory.
   2.211 -  os::closedir(dirp);
   2.212 -}
   2.213 -
   2.214 -// Check if the given file descriptor is considered a secure.
   2.215 -//
   2.216 -static bool is_file_secure(int fd, const char *filename) {
   2.217 -
   2.218 -  int result;
   2.219 -  struct stat statbuf;
   2.220 -
   2.221 -  // Determine if the file is secure.
   2.222 -  RESTARTABLE(::fstat(fd, &statbuf), result);
   2.223 -  if (result == OS_ERR) {
   2.224 -    if (PrintMiscellaneous && Verbose) {
   2.225 -      warning("fstat failed on %s: %s\n", filename, strerror(errno));
   2.226 -    }
   2.227 -    return false;
   2.228 -  }
   2.229 -  if (statbuf.st_nlink > 1) {
   2.230 -    // A file with multiple links is not expected.
   2.231 -    if (PrintMiscellaneous && Verbose) {
   2.232 -      warning("file %s has multiple links\n", filename);
   2.233 -    }
   2.234 -    return false;
   2.235    }
   2.236    return true;
   2.237  }
   2.238 @@ -507,10 +317,9 @@
   2.239  
   2.240    const char* tmpdirname = os::get_temp_directory();
   2.241  
   2.242 -  // open the temp directory
   2.243 -  DIR* tmpdirp = open_directory_secure(tmpdirname);
   2.244 +  DIR* tmpdirp = os::opendir(tmpdirname);
   2.245 +
   2.246    if (tmpdirp == NULL) {
   2.247 -    // Cannot open the directory to get the user name, return.
   2.248      return NULL;
   2.249    }
   2.250  
   2.251 @@ -535,8 +344,7 @@
   2.252      strcat(usrdir_name, "/");
   2.253      strcat(usrdir_name, dentry->d_name);
   2.254  
   2.255 -    // open the user directory
   2.256 -    DIR* subdirp = open_directory_secure(usrdir_name);
   2.257 +    DIR* subdirp = os::opendir(usrdir_name);
   2.258  
   2.259      if (subdirp == NULL) {
   2.260        FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   2.261 @@ -657,6 +465,26 @@
   2.262  }
   2.263  
   2.264  
   2.265 +// remove file
   2.266 +//
   2.267 +// this method removes the file with the given file name in the
   2.268 +// named directory.
   2.269 +//
   2.270 +static void remove_file(const char* dirname, const char* filename) {
   2.271 +
   2.272 +  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
   2.273 +  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   2.274 +
   2.275 +  strcpy(path, dirname);
   2.276 +  strcat(path, "/");
   2.277 +  strcat(path, filename);
   2.278 +
   2.279 +  remove_file(path);
   2.280 +
   2.281 +  FREE_C_HEAP_ARRAY(char, path, mtInternal);
   2.282 +}
   2.283 +
   2.284 +
   2.285  // cleanup stale shared memory resources
   2.286  //
   2.287  // This method attempts to remove all stale shared memory files in
   2.288 @@ -668,11 +496,16 @@
   2.289  //
   2.290  static void cleanup_sharedmem_resources(const char* dirname) {
   2.291  
   2.292 -  int saved_cwd_fd;
   2.293 -  // open the directory
   2.294 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   2.295 +  // open the user temp directory
   2.296 +  DIR* dirp = os::opendir(dirname);
   2.297 +
   2.298    if (dirp == NULL) {
   2.299 -    // directory doesn't exist or is insecure, so there is nothing to cleanup
   2.300 +    // directory doesn't exist, so there is nothing to cleanup
   2.301 +    return;
   2.302 +  }
   2.303 +
   2.304 +  if (!is_directory_secure(dirname)) {
   2.305 +    // the directory is not a secure directory
   2.306      return;
   2.307    }
   2.308  
   2.309 @@ -686,7 +519,6 @@
   2.310    //
   2.311    struct dirent* entry;
   2.312    char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   2.313 -
   2.314    errno = 0;
   2.315    while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
   2.316  
   2.317 @@ -695,8 +527,9 @@
   2.318      if (pid == 0) {
   2.319  
   2.320        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
   2.321 +
   2.322          // attempt to remove all unexpected files, except "." and ".."
   2.323 -        unlink(entry->d_name);
   2.324 +        remove_file(dirname, entry->d_name);
   2.325        }
   2.326  
   2.327        errno = 0;
   2.328 @@ -718,14 +551,12 @@
   2.329      //
   2.330      if ((pid == os::current_process_id()) ||
   2.331          (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
   2.332 -        unlink(entry->d_name);
   2.333 +
   2.334 +        remove_file(dirname, entry->d_name);
   2.335      }
   2.336      errno = 0;
   2.337    }
   2.338 -
   2.339 -  // close the directory and reset the current working directory
   2.340 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   2.341 -
   2.342 +  os::closedir(dirp);
   2.343    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
   2.344  }
   2.345  
   2.346 @@ -782,54 +613,19 @@
   2.347      return -1;
   2.348    }
   2.349  
   2.350 -  int saved_cwd_fd;
   2.351 -  // open the directory and set the current working directory to it
   2.352 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   2.353 -  if (dirp == NULL) {
   2.354 -    // Directory doesn't exist or is insecure, so cannot create shared
   2.355 -    // memory file.
   2.356 +  int result;
   2.357 +
   2.358 +  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
   2.359 +  if (result == OS_ERR) {
   2.360 +    if (PrintMiscellaneous && Verbose) {
   2.361 +      warning("could not create file %s: %s\n", filename, strerror(errno));
   2.362 +    }
   2.363      return -1;
   2.364    }
   2.365  
   2.366 -  // Open the filename in the current directory.
   2.367 -  // Cannot use O_TRUNC here; truncation of an existing file has to happen
   2.368 -  // after the is_file_secure() check below.
   2.369 -  int result;
   2.370 -  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   2.371 -  if (result == OS_ERR) {
   2.372 -    if (PrintMiscellaneous && Verbose) {
   2.373 -      if (errno == ELOOP) {
   2.374 -        warning("file %s is a symlink and is not secure\n", filename);
   2.375 -      } else {
   2.376 -        warning("could not create file %s: %s\n", filename, strerror(errno));
   2.377 -      }
   2.378 -    }
   2.379 -    // close the directory and reset the current working directory
   2.380 -    close_directory_secure_cwd(dirp, saved_cwd_fd);
   2.381 -
   2.382 -    return -1;
   2.383 -  }
   2.384 -  // close the directory and reset the current working directory
   2.385 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   2.386 -
   2.387    // save the file descriptor
   2.388    int fd = result;
   2.389  
   2.390 -  // check to see if the file is secure
   2.391 -  if (!is_file_secure(fd, filename)) {
   2.392 -    ::close(fd);
   2.393 -    return -1;
   2.394 -  }
   2.395 -
   2.396 -  // truncate the file to get rid of any existing data
   2.397 -  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   2.398 -  if (result == OS_ERR) {
   2.399 -    if (PrintMiscellaneous && Verbose) {
   2.400 -      warning("could not truncate shared memory file: %s\n", strerror(errno));
   2.401 -    }
   2.402 -    ::close(fd);
   2.403 -    return -1;
   2.404 -  }
   2.405    // set the file size
   2.406    RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   2.407    if (result == OS_ERR) {
   2.408 @@ -887,15 +683,8 @@
   2.409        THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
   2.410      }
   2.411    }
   2.412 -  int fd = result;
   2.413  
   2.414 -  // check to see if the file is secure
   2.415 -  if (!is_file_secure(fd, filename)) {
   2.416 -    ::close(fd);
   2.417 -    return -1;
   2.418 -  }
   2.419 -
   2.420 -  return fd;
   2.421 +  return result;
   2.422  }
   2.423  
   2.424  // create a named shared memory region. returns the address of the
   2.425 @@ -926,13 +715,6 @@
   2.426  
   2.427    char* dirname = get_user_tmp_dir(user_name);
   2.428    char* filename = get_sharedmem_filename(dirname, vmid);
   2.429 -  // get the short filename
   2.430 -  char* short_filename = strrchr(filename, '/');
   2.431 -  if (short_filename == NULL) {
   2.432 -    short_filename = filename;
   2.433 -  } else {
   2.434 -    short_filename++;
   2.435 -  }
   2.436  
   2.437    // cleanup any stale shared memory files
   2.438    cleanup_sharedmem_resources(dirname);
   2.439 @@ -940,7 +722,7 @@
   2.440    assert(((size > 0) && (size % os::vm_page_size() == 0)),
   2.441           "unexpected PerfMemory region size");
   2.442  
   2.443 -  fd = create_sharedmem_resources(dirname, short_filename, size);
   2.444 +  fd = create_sharedmem_resources(dirname, filename, size);
   2.445  
   2.446    FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
   2.447    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
   2.448 @@ -1055,12 +837,12 @@
   2.449    // constructs for the file and the shared memory mapping.
   2.450    if (mode == PerfMemory::PERF_MODE_RO) {
   2.451      mmap_prot = PROT_READ;
   2.452 -    file_flags = O_RDONLY | O_NOFOLLOW;
   2.453 +    file_flags = O_RDONLY;
   2.454    }
   2.455    else if (mode == PerfMemory::PERF_MODE_RW) {
   2.456  #ifdef LATER
   2.457      mmap_prot = PROT_READ | PROT_WRITE;
   2.458 -    file_flags = O_RDWR | O_NOFOLLOW;
   2.459 +    file_flags = O_RDWR;
   2.460  #else
   2.461      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   2.462                "Unsupported access mode");
     3.1 --- a/src/os/solaris/vm/perfMemory_solaris.cpp	Thu Nov 06 09:39:49 2014 -0800
     3.2 +++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Mon Nov 10 09:47:41 2014 -0800
     3.3 @@ -199,38 +199,7 @@
     3.4  }
     3.5  
     3.6  
     3.7 -// Check if the given statbuf is considered a secure directory for
     3.8 -// the backing store files. Returns true if the directory is considered
     3.9 -// a secure location. Returns false if the statbuf is a symbolic link or
    3.10 -// if an error occurred.
    3.11 -//
    3.12 -static bool is_statbuf_secure(struct stat *statp) {
    3.13 -  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
    3.14 -    // The path represents a link or some non-directory file type,
    3.15 -    // which is not what we expected. Declare it insecure.
    3.16 -    //
    3.17 -    return false;
    3.18 -  }
    3.19 -  // We have an existing directory, check if the permissions are safe.
    3.20 -  //
    3.21 -  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
    3.22 -    // The directory is open for writing and could be subjected
    3.23 -    // to a symlink or a hard link attack. Declare it insecure.
    3.24 -    //
    3.25 -    return false;
    3.26 -  }
    3.27 -  // See if the uid of the directory matches the effective uid of the process.
    3.28 -  //
    3.29 -  if (statp->st_uid != geteuid()) {
    3.30 -    // The directory was not created by this user, declare it insecure.
    3.31 -    //
    3.32 -    return false;
    3.33 -  }
    3.34 -  return true;
    3.35 -}
    3.36 -
    3.37 -
    3.38 -// Check if the given path is considered a secure directory for
    3.39 +// check if the given path is considered a secure directory for
    3.40  // the backing store files. Returns true if the directory exists
    3.41  // and is considered a secure location. Returns false if the path
    3.42  // is a symbolic link or if an error occurred.
    3.43 @@ -244,185 +213,27 @@
    3.44      return false;
    3.45    }
    3.46  
    3.47 -  // The path exists, see if it is secure.
    3.48 -  return is_statbuf_secure(&statbuf);
    3.49 -}
    3.50 -
    3.51 -
    3.52 -// Check if the given directory file descriptor is considered a secure
    3.53 -// directory for the backing store files. Returns true if the directory
    3.54 -// exists and is considered a secure location. Returns false if the path
    3.55 -// is a symbolic link or if an error occurred.
    3.56 -//
    3.57 -static bool is_dirfd_secure(int dir_fd) {
    3.58 -  struct stat statbuf;
    3.59 -  int result = 0;
    3.60 -
    3.61 -  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
    3.62 -  if (result == OS_ERR) {
    3.63 +  // the path exists, now check it's mode
    3.64 +  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
    3.65 +    // the path represents a link or some non-directory file type,
    3.66 +    // which is not what we expected. declare it insecure.
    3.67 +    //
    3.68      return false;
    3.69    }
    3.70 -
    3.71 -  // The path exists, now check its mode.
    3.72 -  return is_statbuf_secure(&statbuf);
    3.73 -}
    3.74 -
    3.75 -
    3.76 -// Check to make sure fd1 and fd2 are referencing the same file system object.
    3.77 -//
    3.78 -static bool is_same_fsobject(int fd1, int fd2) {
    3.79 -  struct stat statbuf1;
    3.80 -  struct stat statbuf2;
    3.81 -  int result = 0;
    3.82 -
    3.83 -  RESTARTABLE(::fstat(fd1, &statbuf1), result);
    3.84 -  if (result == OS_ERR) {
    3.85 -    return false;
    3.86 -  }
    3.87 -  RESTARTABLE(::fstat(fd2, &statbuf2), result);
    3.88 -  if (result == OS_ERR) {
    3.89 -    return false;
    3.90 -  }
    3.91 -
    3.92 -  if ((statbuf1.st_ino == statbuf2.st_ino) &&
    3.93 -      (statbuf1.st_dev == statbuf2.st_dev)) {
    3.94 -    return true;
    3.95 -  } else {
    3.96 -    return false;
    3.97 -  }
    3.98 -}
    3.99 -
   3.100 -
   3.101 -// Open the directory of the given path and validate it.
   3.102 -// Return a DIR * of the open directory.
   3.103 -//
   3.104 -static DIR *open_directory_secure(const char* dirname) {
   3.105 -  // Open the directory using open() so that it can be verified
   3.106 -  // to be secure by calling is_dirfd_secure(), opendir() and then check
   3.107 -  // to see if they are the same file system object.  This method does not
   3.108 -  // introduce a window of opportunity for the directory to be attacked that
   3.109 -  // calling opendir() and is_directory_secure() does.
   3.110 -  int result;
   3.111 -  DIR *dirp = NULL;
   3.112 -  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
   3.113 -  if (result == OS_ERR) {
   3.114 -    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
   3.115 -    if (PrintMiscellaneous && Verbose) {
   3.116 -      if (errno == ELOOP) {
   3.117 -        warning("directory %s is a symlink and is not secure\n", dirname);
   3.118 -      } else {
   3.119 -        warning("could not open directory %s: %s\n", dirname, strerror(errno));
   3.120 -      }
   3.121 +  else {
   3.122 +    // we have an existing directory, check if the permissions are safe.
   3.123 +    //
   3.124 +    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
   3.125 +      // the directory is open for writing and could be subjected
   3.126 +      // to a symlnk attack. declare it insecure.
   3.127 +      //
   3.128 +      return false;
   3.129      }
   3.130 -    return dirp;
   3.131 -  }
   3.132 -  int fd = result;
   3.133 -
   3.134 -  // Determine if the open directory is secure.
   3.135 -  if (!is_dirfd_secure(fd)) {
   3.136 -    // The directory is not a secure directory.
   3.137 -    os::close(fd);
   3.138 -    return dirp;
   3.139 -  }
   3.140 -
   3.141 -  // Open the directory.
   3.142 -  dirp = ::opendir(dirname);
   3.143 -  if (dirp == NULL) {
   3.144 -    // The directory doesn't exist, close fd and return.
   3.145 -    os::close(fd);
   3.146 -    return dirp;
   3.147 -  }
   3.148 -
   3.149 -  // Check to make sure fd and dirp are referencing the same file system object.
   3.150 -  if (!is_same_fsobject(fd, dirp->dd_fd)) {
   3.151 -    // The directory is not secure.
   3.152 -    os::close(fd);
   3.153 -    os::closedir(dirp);
   3.154 -    dirp = NULL;
   3.155 -    return dirp;
   3.156 -  }
   3.157 -
   3.158 -  // Close initial open now that we know directory is secure
   3.159 -  os::close(fd);
   3.160 -
   3.161 -  return dirp;
   3.162 -}
   3.163 -
   3.164 -// NOTE: The code below uses fchdir(), open() and unlink() because
   3.165 -// fdopendir(), openat() and unlinkat() are not supported on all
   3.166 -// versions.  Once the support for fdopendir(), openat() and unlinkat()
   3.167 -// is available on all supported versions the code can be changed
   3.168 -// to use these functions.
   3.169 -
   3.170 -// Open the directory of the given path, validate it and set the
   3.171 -// current working directory to it.
   3.172 -// Return a DIR * of the open directory and the saved cwd fd.
   3.173 -//
   3.174 -static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
   3.175 -
   3.176 -  // Open the directory.
   3.177 -  DIR* dirp = open_directory_secure(dirname);
   3.178 -  if (dirp == NULL) {
   3.179 -    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
   3.180 -    return dirp;
   3.181 -  }
   3.182 -  int fd = dirp->dd_fd;
   3.183 -
   3.184 -  // Open a fd to the cwd and save it off.
   3.185 -  int result;
   3.186 -  RESTARTABLE(::open(".", O_RDONLY), result);
   3.187 -  if (result == OS_ERR) {
   3.188 -    *saved_cwd_fd = -1;
   3.189 -  } else {
   3.190 -    *saved_cwd_fd = result;
   3.191 -  }
   3.192 -
   3.193 -  // Set the current directory to dirname by using the fd of the directory.
   3.194 -  result = fchdir(fd);
   3.195 -
   3.196 -  return dirp;
   3.197 -}
   3.198 -
   3.199 -// Close the directory and restore the current working directory.
   3.200 -//
   3.201 -static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
   3.202 -
   3.203 -  int result;
   3.204 -  // If we have a saved cwd change back to it and close the fd.
   3.205 -  if (saved_cwd_fd != -1) {
   3.206 -    result = fchdir(saved_cwd_fd);
   3.207 -    ::close(saved_cwd_fd);
   3.208 -  }
   3.209 -
   3.210 -  // Close the directory.
   3.211 -  os::closedir(dirp);
   3.212 -}
   3.213 -
   3.214 -// Check if the given file descriptor is considered a secure.
   3.215 -//
   3.216 -static bool is_file_secure(int fd, const char *filename) {
   3.217 -
   3.218 -  int result;
   3.219 -  struct stat statbuf;
   3.220 -
   3.221 -  // Determine if the file is secure.
   3.222 -  RESTARTABLE(::fstat(fd, &statbuf), result);
   3.223 -  if (result == OS_ERR) {
   3.224 -    if (PrintMiscellaneous && Verbose) {
   3.225 -      warning("fstat failed on %s: %s\n", filename, strerror(errno));
   3.226 -    }
   3.227 -    return false;
   3.228 -  }
   3.229 -  if (statbuf.st_nlink > 1) {
   3.230 -    // A file with multiple links is not expected.
   3.231 -    if (PrintMiscellaneous && Verbose) {
   3.232 -      warning("file %s has multiple links\n", filename);
   3.233 -    }
   3.234 -    return false;
   3.235    }
   3.236    return true;
   3.237  }
   3.238  
   3.239 +
   3.240  // return the user name for the given user id
   3.241  //
   3.242  // the caller is expected to free the allocated memory.
   3.243 @@ -497,10 +308,9 @@
   3.244  
   3.245    const char* tmpdirname = os::get_temp_directory();
   3.246  
   3.247 -  // open the temp directory
   3.248 -  DIR* tmpdirp = open_directory_secure(tmpdirname);
   3.249 +  DIR* tmpdirp = os::opendir(tmpdirname);
   3.250 +
   3.251    if (tmpdirp == NULL) {
   3.252 -    // Cannot open the directory to get the user name, return.
   3.253      return NULL;
   3.254    }
   3.255  
   3.256 @@ -525,8 +335,7 @@
   3.257      strcat(usrdir_name, "/");
   3.258      strcat(usrdir_name, dentry->d_name);
   3.259  
   3.260 -    // open the user directory
   3.261 -    DIR* subdirp = open_directory_secure(usrdir_name);
   3.262 +    DIR* subdirp = os::opendir(usrdir_name);
   3.263  
   3.264      if (subdirp == NULL) {
   3.265        FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   3.266 @@ -695,6 +504,26 @@
   3.267  }
   3.268  
   3.269  
   3.270 +// remove file
   3.271 +//
   3.272 +// this method removes the file with the given file name in the
   3.273 +// named directory.
   3.274 +//
   3.275 +static void remove_file(const char* dirname, const char* filename) {
   3.276 +
   3.277 +  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
   3.278 +  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   3.279 +
   3.280 +  strcpy(path, dirname);
   3.281 +  strcat(path, "/");
   3.282 +  strcat(path, filename);
   3.283 +
   3.284 +  remove_file(path);
   3.285 +
   3.286 +  FREE_C_HEAP_ARRAY(char, path, mtInternal);
   3.287 +}
   3.288 +
   3.289 +
   3.290  // cleanup stale shared memory resources
   3.291  //
   3.292  // This method attempts to remove all stale shared memory files in
   3.293 @@ -706,11 +535,16 @@
   3.294  //
   3.295  static void cleanup_sharedmem_resources(const char* dirname) {
   3.296  
   3.297 -  int saved_cwd_fd;
   3.298 -  // open the directory
   3.299 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   3.300 +  // open the user temp directory
   3.301 +  DIR* dirp = os::opendir(dirname);
   3.302 +
   3.303    if (dirp == NULL) {
   3.304 -     // directory doesn't exist or is insecure, so there is nothing to cleanup
   3.305 +    // directory doesn't exist, so there is nothing to cleanup
   3.306 +    return;
   3.307 +  }
   3.308 +
   3.309 +  if (!is_directory_secure(dirname)) {
   3.310 +    // the directory is not a secure directory
   3.311      return;
   3.312    }
   3.313  
   3.314 @@ -724,7 +558,6 @@
   3.315    //
   3.316    struct dirent* entry;
   3.317    char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   3.318 -
   3.319    errno = 0;
   3.320    while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
   3.321  
   3.322 @@ -735,7 +568,7 @@
   3.323        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
   3.324  
   3.325          // attempt to remove all unexpected files, except "." and ".."
   3.326 -        unlink(entry->d_name);
   3.327 +        remove_file(dirname, entry->d_name);
   3.328        }
   3.329  
   3.330        errno = 0;
   3.331 @@ -758,14 +591,11 @@
   3.332      if ((pid == os::current_process_id()) ||
   3.333          (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
   3.334  
   3.335 -        unlink(entry->d_name);
   3.336 +        remove_file(dirname, entry->d_name);
   3.337      }
   3.338      errno = 0;
   3.339    }
   3.340 -
   3.341 -  // close the directory and reset the current working directory
   3.342 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   3.343 -
   3.344 +  os::closedir(dirp);
   3.345    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
   3.346  }
   3.347  
   3.348 @@ -822,54 +652,19 @@
   3.349      return -1;
   3.350    }
   3.351  
   3.352 -  int saved_cwd_fd;
   3.353 -  // open the directory and set the current working directory to it
   3.354 -  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   3.355 -  if (dirp == NULL) {
   3.356 -    // Directory doesn't exist or is insecure, so cannot create shared
   3.357 -    // memory file.
   3.358 +  int result;
   3.359 +
   3.360 +  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
   3.361 +  if (result == OS_ERR) {
   3.362 +    if (PrintMiscellaneous && Verbose) {
   3.363 +      warning("could not create file %s: %s\n", filename, strerror(errno));
   3.364 +    }
   3.365      return -1;
   3.366    }
   3.367  
   3.368 -  // Open the filename in the current directory.
   3.369 -  // Cannot use O_TRUNC here; truncation of an existing file has to happen
   3.370 -  // after the is_file_secure() check below.
   3.371 -  int result;
   3.372 -  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   3.373 -  if (result == OS_ERR) {
   3.374 -    if (PrintMiscellaneous && Verbose) {
   3.375 -      if (errno == ELOOP) {
   3.376 -        warning("file %s is a symlink and is not secure\n", filename);
   3.377 -      } else {
   3.378 -        warning("could not create file %s: %s\n", filename, strerror(errno));
   3.379 -      }
   3.380 -    }
   3.381 -    // close the directory and reset the current working directory
   3.382 -    close_directory_secure_cwd(dirp, saved_cwd_fd);
   3.383 -
   3.384 -    return -1;
   3.385 -  }
   3.386 -  // close the directory and reset the current working directory
   3.387 -  close_directory_secure_cwd(dirp, saved_cwd_fd);
   3.388 -
   3.389    // save the file descriptor
   3.390    int fd = result;
   3.391  
   3.392 -  // check to see if the file is secure
   3.393 -  if (!is_file_secure(fd, filename)) {
   3.394 -    ::close(fd);
   3.395 -    return -1;
   3.396 -  }
   3.397 -
   3.398 -  // truncate the file to get rid of any existing data
   3.399 -  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   3.400 -  if (result == OS_ERR) {
   3.401 -    if (PrintMiscellaneous && Verbose) {
   3.402 -      warning("could not truncate shared memory file: %s\n", strerror(errno));
   3.403 -    }
   3.404 -    ::close(fd);
   3.405 -    return -1;
   3.406 -  }
   3.407    // set the file size
   3.408    RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   3.409    if (result == OS_ERR) {
   3.410 @@ -905,15 +700,8 @@
   3.411        THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
   3.412      }
   3.413    }
   3.414 -  int fd = result;
   3.415  
   3.416 -  // check to see if the file is secure
   3.417 -  if (!is_file_secure(fd, filename)) {
   3.418 -    ::close(fd);
   3.419 -    return -1;
   3.420 -  }
   3.421 -
   3.422 -  return fd;
   3.423 +  return result;
   3.424  }
   3.425  
   3.426  // create a named shared memory region. returns the address of the
   3.427 @@ -945,21 +733,13 @@
   3.428    char* dirname = get_user_tmp_dir(user_name);
   3.429    char* filename = get_sharedmem_filename(dirname, vmid);
   3.430  
   3.431 -  // get the short filename
   3.432 -  char* short_filename = strrchr(filename, '/');
   3.433 -  if (short_filename == NULL) {
   3.434 -    short_filename = filename;
   3.435 -  } else {
   3.436 -    short_filename++;
   3.437 -  }
   3.438 -
   3.439    // cleanup any stale shared memory files
   3.440    cleanup_sharedmem_resources(dirname);
   3.441  
   3.442    assert(((size > 0) && (size % os::vm_page_size() == 0)),
   3.443           "unexpected PerfMemory region size");
   3.444  
   3.445 -  fd = create_sharedmem_resources(dirname, short_filename, size);
   3.446 +  fd = create_sharedmem_resources(dirname, filename, size);
   3.447  
   3.448    FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
   3.449    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
   3.450 @@ -1075,12 +855,12 @@
   3.451    // constructs for the file and the shared memory mapping.
   3.452    if (mode == PerfMemory::PERF_MODE_RO) {
   3.453      mmap_prot = PROT_READ;
   3.454 -    file_flags = O_RDONLY | O_NOFOLLOW;
   3.455 +    file_flags = O_RDONLY;
   3.456    }
   3.457    else if (mode == PerfMemory::PERF_MODE_RW) {
   3.458  #ifdef LATER
   3.459      mmap_prot = PROT_READ | PROT_WRITE;
   3.460 -    file_flags = O_RDWR | O_NOFOLLOW;
   3.461 +    file_flags = O_RDWR;
   3.462  #else
   3.463      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   3.464                "Unsupported access mode");
     4.1 --- a/src/share/vm/utilities/vmError.cpp	Thu Nov 06 09:39:49 2014 -0800
     4.2 +++ b/src/share/vm/utilities/vmError.cpp	Mon Nov 10 09:47:41 2014 -0800
     4.3 @@ -22,7 +22,6 @@
     4.4   *
     4.5   */
     4.6  
     4.7 -#include <fcntl.h>
     4.8  #include "precompiled.hpp"
     4.9  #include "compiler/compileBroker.hpp"
    4.10  #include "gc_interface/collectedHeap.hpp"
    4.11 @@ -842,8 +841,7 @@
    4.12  static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
    4.13    int fd = -1;
    4.14    if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
    4.15 -    // the O_EXCL flag will cause the open to fail if the file exists
    4.16 -    fd = open(buf, O_RDWR | O_CREAT | O_EXCL, 0666);
    4.17 +    fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
    4.18    }
    4.19    return fd;
    4.20  }

mercurial