Tue, 13 Jan 2015 16:09:52 +0100
8069590: AIX port of "8050807: Better performing performance data handling"
Reviewed-by: simonis, goetz
Contributed-by: matthias.baesken@sap.com, martin.doerr@sap.com
make/aix/makefiles/xlc.make | file | annotate | diff | comparison | revisions | |
src/os/aix/vm/perfMemory_aix.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/make/aix/makefiles/xlc.make Wed Jan 21 12:19:39 2015 -0800 1.2 +++ b/make/aix/makefiles/xlc.make Tue Jan 13 16:09:52 2015 +0100 1.3 @@ -74,6 +74,12 @@ 1.4 # no xlc counterpart for -fcheck-new 1.5 # CFLAGS += -fcheck-new 1.6 1.7 +# We need to define this on the command line if we want to use the the 1.8 +# predefined format specifiers from "inttypes.h". Otherwise system headrs 1.9 +# can indirectly include inttypes.h before we define __STDC_FORMAT_MACROS 1.10 +# in globalDefinitions.hpp 1.11 +CFLAGS += -D__STDC_FORMAT_MACROS 1.12 + 1.13 ARCHFLAG = -q64 1.14 1.15 CFLAGS += $(ARCHFLAG)
2.1 --- a/src/os/aix/vm/perfMemory_aix.cpp Wed Jan 21 12:19:39 2015 -0800 2.2 +++ b/src/os/aix/vm/perfMemory_aix.cpp Tue Jan 13 16:09:52 2015 +0100 2.3 @@ -31,6 +31,7 @@ 2.4 #include "os_aix.inline.hpp" 2.5 #include "runtime/handles.inline.hpp" 2.6 #include "runtime/perfMemory.hpp" 2.7 +#include "services/memTracker.hpp" 2.8 #include "utilities/exceptions.hpp" 2.9 2.10 // put OS-includes here 2.11 @@ -196,12 +197,37 @@ 2.12 return pid; 2.13 } 2.14 2.15 +// Check if the given statbuf is considered a secure directory for 2.16 +// the backing store files. Returns true if the directory is considered 2.17 +// a secure location. Returns false if the statbuf is a symbolic link or 2.18 +// if an error occurred. 2.19 +static bool is_statbuf_secure(struct stat *statp) { 2.20 + if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) { 2.21 + // The path represents a link or some non-directory file type, 2.22 + // which is not what we expected. Declare it insecure. 2.23 + // 2.24 + return false; 2.25 + } 2.26 + // We have an existing directory, check if the permissions are safe. 2.27 + if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) { 2.28 + // The directory is open for writing and could be subjected 2.29 + // to a symlink or a hard link attack. Declare it insecure. 2.30 + return false; 2.31 + } 2.32 + // See if the uid of the directory matches the effective uid of the process. 2.33 + // 2.34 + if (statp->st_uid != geteuid()) { 2.35 + // The directory was not created by this user, declare it insecure. 2.36 + return false; 2.37 + } 2.38 + return true; 2.39 +} 2.40 2.41 -// check if the given path is considered a secure directory for 2.42 + 2.43 +// Check if the given path is considered a secure directory for 2.44 // the backing store files. Returns true if the directory exists 2.45 // and is considered a secure location. Returns false if the path 2.46 // is a symbolic link or if an error occurred. 2.47 -// 2.48 static bool is_directory_secure(const char* path) { 2.49 struct stat statbuf; 2.50 int result = 0; 2.51 @@ -211,38 +237,276 @@ 2.52 return false; 2.53 } 2.54 2.55 - // the path exists, now check it's mode 2.56 - if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) { 2.57 - // the path represents a link or some non-directory file type, 2.58 - // which is not what we expected. declare it insecure. 2.59 - // 2.60 + // The path exists, see if it is secure. 2.61 + return is_statbuf_secure(&statbuf); 2.62 +} 2.63 + 2.64 +// (Taken over from Solaris to support the O_NOFOLLOW case on AIX.) 2.65 +// Check if the given directory file descriptor is considered a secure 2.66 +// directory for the backing store files. Returns true if the directory 2.67 +// exists and is considered a secure location. Returns false if the path 2.68 +// is a symbolic link or if an error occurred. 2.69 +static bool is_dirfd_secure(int dir_fd) { 2.70 + struct stat statbuf; 2.71 + int result = 0; 2.72 + 2.73 + RESTARTABLE(::fstat(dir_fd, &statbuf), result); 2.74 + if (result == OS_ERR) { 2.75 return false; 2.76 } 2.77 - else { 2.78 - // we have an existing directory, check if the permissions are safe. 2.79 - // 2.80 - if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) { 2.81 - // the directory is open for writing and could be subjected 2.82 - // to a symlnk attack. declare it insecure. 2.83 - // 2.84 - return false; 2.85 + 2.86 + // The path exists, now check its mode. 2.87 + return is_statbuf_secure(&statbuf); 2.88 +} 2.89 + 2.90 + 2.91 +// Check to make sure fd1 and fd2 are referencing the same file system object. 2.92 +static bool is_same_fsobject(int fd1, int fd2) { 2.93 + struct stat statbuf1; 2.94 + struct stat statbuf2; 2.95 + int result = 0; 2.96 + 2.97 + RESTARTABLE(::fstat(fd1, &statbuf1), result); 2.98 + if (result == OS_ERR) { 2.99 + return false; 2.100 + } 2.101 + RESTARTABLE(::fstat(fd2, &statbuf2), result); 2.102 + if (result == OS_ERR) { 2.103 + return false; 2.104 + } 2.105 + 2.106 + if ((statbuf1.st_ino == statbuf2.st_ino) && 2.107 + (statbuf1.st_dev == statbuf2.st_dev)) { 2.108 + return true; 2.109 + } else { 2.110 + return false; 2.111 + } 2.112 +} 2.113 + 2.114 +// Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1. 2.115 +// We use the jdk6 implementation here. 2.116 +#ifndef O_NOFOLLOW 2.117 +// The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour 2.118 +// was done in jdk 5/6 hotspot by Oracle this way 2.119 +static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) { 2.120 + struct stat orig_st; 2.121 + struct stat new_st; 2.122 + bool create; 2.123 + int error; 2.124 + int fd; 2.125 + 2.126 + create = false; 2.127 + 2.128 + if (lstat(path, &orig_st) != 0) { 2.129 + if (errno == ENOENT && (oflag & O_CREAT) != 0) { 2.130 + // File doesn't exist, but_we want to create it, add O_EXCL flag 2.131 + // to make sure no-one creates it (or a symlink) before us 2.132 + // This works as we expect with symlinks, from posix man page: 2.133 + // 'If O_EXCL and O_CREAT are set, and path names a symbolic 2.134 + // link, open() shall fail and set errno to [EEXIST]'. 2.135 + oflag |= O_EXCL; 2.136 + create = true; 2.137 + } else { 2.138 + // File doesn't exist, and we are not creating it. 2.139 + return OS_ERR; 2.140 } 2.141 + } else { 2.142 + // Lstat success, check if existing file is a link. 2.143 + if ((orig_st.st_mode & S_IFMT) == S_IFLNK) { 2.144 + // File is a symlink. 2.145 + errno = ELOOP; 2.146 + return OS_ERR; 2.147 + } 2.148 + } 2.149 + 2.150 + if (use_mode == true) { 2.151 + fd = open(path, oflag, mode); 2.152 + } else { 2.153 + fd = open(path, oflag); 2.154 + } 2.155 + 2.156 + if (fd == OS_ERR) { 2.157 + return fd; 2.158 + } 2.159 + 2.160 + // Can't do inode checks on before/after if we created the file. 2.161 + if (create == false) { 2.162 + if (fstat(fd, &new_st) != 0) { 2.163 + // Keep errno from fstat, in case close also fails. 2.164 + error = errno; 2.165 + ::close(fd); 2.166 + errno = error; 2.167 + return OS_ERR; 2.168 + } 2.169 + 2.170 + if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) { 2.171 + // File was tampered with during race window. 2.172 + ::close(fd); 2.173 + errno = EEXIST; 2.174 + if (PrintMiscellaneous && Verbose) { 2.175 + warning("possible file tampering attempt detected when opening %s", path); 2.176 + } 2.177 + return OS_ERR; 2.178 + } 2.179 + } 2.180 + 2.181 + return fd; 2.182 +} 2.183 + 2.184 +static int open_o_nofollow(const char* path, int oflag, mode_t mode) { 2.185 + return open_o_nofollow_impl(path, oflag, mode, true); 2.186 +} 2.187 + 2.188 +static int open_o_nofollow(const char* path, int oflag) { 2.189 + return open_o_nofollow_impl(path, oflag, 0, false); 2.190 +} 2.191 +#endif 2.192 + 2.193 +// Open the directory of the given path and validate it. 2.194 +// Return a DIR * of the open directory. 2.195 +static DIR *open_directory_secure(const char* dirname) { 2.196 + // Open the directory using open() so that it can be verified 2.197 + // to be secure by calling is_dirfd_secure(), opendir() and then check 2.198 + // to see if they are the same file system object. This method does not 2.199 + // introduce a window of opportunity for the directory to be attacked that 2.200 + // calling opendir() and is_directory_secure() does. 2.201 + int result; 2.202 + DIR *dirp = NULL; 2.203 + 2.204 + // No O_NOFOLLOW defined at buildtime, and it is not documented for open; 2.205 + // so provide a workaround in this case. 2.206 +#ifdef O_NOFOLLOW 2.207 + RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result); 2.208 +#else 2.209 + // workaround (jdk6 coding) 2.210 + RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result); 2.211 +#endif 2.212 + 2.213 + if (result == OS_ERR) { 2.214 + // Directory doesn't exist or is a symlink, so there is nothing to cleanup. 2.215 + if (PrintMiscellaneous && Verbose) { 2.216 + if (errno == ELOOP) { 2.217 + warning("directory %s is a symlink and is not secure\n", dirname); 2.218 + } else { 2.219 + warning("could not open directory %s: %s\n", dirname, strerror(errno)); 2.220 + } 2.221 + } 2.222 + return dirp; 2.223 + } 2.224 + int fd = result; 2.225 + 2.226 + // Determine if the open directory is secure. 2.227 + if (!is_dirfd_secure(fd)) { 2.228 + // The directory is not a secure directory. 2.229 + os::close(fd); 2.230 + return dirp; 2.231 + } 2.232 + 2.233 + // Open the directory. 2.234 + dirp = ::opendir(dirname); 2.235 + if (dirp == NULL) { 2.236 + // The directory doesn't exist, close fd and return. 2.237 + os::close(fd); 2.238 + return dirp; 2.239 + } 2.240 + 2.241 + // Check to make sure fd and dirp are referencing the same file system object. 2.242 + if (!is_same_fsobject(fd, dirp->dd_fd)) { 2.243 + // The directory is not secure. 2.244 + os::close(fd); 2.245 + os::closedir(dirp); 2.246 + dirp = NULL; 2.247 + return dirp; 2.248 + } 2.249 + 2.250 + // Close initial open now that we know directory is secure 2.251 + os::close(fd); 2.252 + 2.253 + return dirp; 2.254 +} 2.255 + 2.256 +// NOTE: The code below uses fchdir(), open() and unlink() because 2.257 +// fdopendir(), openat() and unlinkat() are not supported on all 2.258 +// versions. Once the support for fdopendir(), openat() and unlinkat() 2.259 +// is available on all supported versions the code can be changed 2.260 +// to use these functions. 2.261 + 2.262 +// Open the directory of the given path, validate it and set the 2.263 +// current working directory to it. 2.264 +// Return a DIR * of the open directory and the saved cwd fd. 2.265 +// 2.266 +static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) { 2.267 + 2.268 + // Open the directory. 2.269 + DIR* dirp = open_directory_secure(dirname); 2.270 + if (dirp == NULL) { 2.271 + // Directory doesn't exist or is insecure, so there is nothing to cleanup. 2.272 + return dirp; 2.273 + } 2.274 + int fd = dirp->dd_fd; 2.275 + 2.276 + // Open a fd to the cwd and save it off. 2.277 + int result; 2.278 + RESTARTABLE(::open(".", O_RDONLY), result); 2.279 + if (result == OS_ERR) { 2.280 + *saved_cwd_fd = -1; 2.281 + } else { 2.282 + *saved_cwd_fd = result; 2.283 + } 2.284 + 2.285 + // Set the current directory to dirname by using the fd of the directory. 2.286 + result = fchdir(fd); 2.287 + 2.288 + return dirp; 2.289 +} 2.290 + 2.291 +// Close the directory and restore the current working directory. 2.292 +static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) { 2.293 + 2.294 + int result; 2.295 + // If we have a saved cwd change back to it and close the fd. 2.296 + if (saved_cwd_fd != -1) { 2.297 + result = fchdir(saved_cwd_fd); 2.298 + ::close(saved_cwd_fd); 2.299 + } 2.300 + 2.301 + // Close the directory. 2.302 + os::closedir(dirp); 2.303 +} 2.304 + 2.305 +// Check if the given file descriptor is considered a secure. 2.306 +static bool is_file_secure(int fd, const char *filename) { 2.307 + 2.308 + int result; 2.309 + struct stat statbuf; 2.310 + 2.311 + // Determine if the file is secure. 2.312 + RESTARTABLE(::fstat(fd, &statbuf), result); 2.313 + if (result == OS_ERR) { 2.314 + if (PrintMiscellaneous && Verbose) { 2.315 + warning("fstat failed on %s: %s\n", filename, strerror(errno)); 2.316 + } 2.317 + return false; 2.318 + } 2.319 + if (statbuf.st_nlink > 1) { 2.320 + // A file with multiple links is not expected. 2.321 + if (PrintMiscellaneous && Verbose) { 2.322 + warning("file %s has multiple links\n", filename); 2.323 + } 2.324 + return false; 2.325 } 2.326 return true; 2.327 } 2.328 2.329 - 2.330 -// return the user name for the given user id 2.331 +// Return the user name for the given user id. 2.332 // 2.333 -// the caller is expected to free the allocated memory. 2.334 -// 2.335 +// The caller is expected to free the allocated memory. 2.336 static char* get_user_name(uid_t uid) { 2.337 2.338 struct passwd pwent; 2.339 2.340 - // determine the max pwbuf size from sysconf, and hardcode 2.341 + // Determine the max pwbuf size from sysconf, and hardcode 2.342 // a default if this not available through sysconf. 2.343 - // 2.344 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); 2.345 if (bufsize == -1) 2.346 bufsize = 1024; 2.347 @@ -344,7 +608,8 @@ 2.348 strcat(usrdir_name, "/"); 2.349 strcat(usrdir_name, dentry->d_name); 2.350 2.351 - DIR* subdirp = os::opendir(usrdir_name); 2.352 + // Open the user directory. 2.353 + DIR* subdirp = open_directory_secure(usrdir_name); 2.354 2.355 if (subdirp == NULL) { 2.356 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); 2.357 @@ -464,28 +729,7 @@ 2.358 } 2.359 } 2.360 2.361 - 2.362 -// remove file 2.363 -// 2.364 -// this method removes the file with the given file name in the 2.365 -// named directory. 2.366 -// 2.367 -static void remove_file(const char* dirname, const char* filename) { 2.368 - 2.369 - size_t nbytes = strlen(dirname) + strlen(filename) + 2; 2.370 - char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); 2.371 - 2.372 - strcpy(path, dirname); 2.373 - strcat(path, "/"); 2.374 - strcat(path, filename); 2.375 - 2.376 - remove_file(path); 2.377 - 2.378 - FREE_C_HEAP_ARRAY(char, path, mtInternal); 2.379 -} 2.380 - 2.381 - 2.382 -// cleanup stale shared memory resources 2.383 +// Cleanup stale shared memory resources 2.384 // 2.385 // This method attempts to remove all stale shared memory files in 2.386 // the named user temporary directory. It scans the named directory 2.387 @@ -493,32 +737,26 @@ 2.388 // process id is extracted from the file name and a test is run to 2.389 // determine if the process is alive. If the process is not alive, 2.390 // any stale file resources are removed. 2.391 -// 2.392 static void cleanup_sharedmem_resources(const char* dirname) { 2.393 2.394 - // open the user temp directory 2.395 - DIR* dirp = os::opendir(dirname); 2.396 - 2.397 + int saved_cwd_fd; 2.398 + // Open the directory. 2.399 + DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd); 2.400 if (dirp == NULL) { 2.401 - // directory doesn't exist, so there is nothing to cleanup 2.402 + // Directory doesn't exist or is insecure, so there is nothing to cleanup. 2.403 return; 2.404 } 2.405 2.406 - if (!is_directory_secure(dirname)) { 2.407 - // the directory is not a secure directory 2.408 - return; 2.409 - } 2.410 - 2.411 - // for each entry in the directory that matches the expected file 2.412 + // For each entry in the directory that matches the expected file 2.413 // name pattern, determine if the file resources are stale and if 2.414 // so, remove the file resources. Note, instrumented HotSpot processes 2.415 // for this user may start and/or terminate during this search and 2.416 // remove or create new files in this directory. The behavior of this 2.417 // loop under these conditions is dependent upon the implementation of 2.418 // opendir/readdir. 2.419 - // 2.420 struct dirent* entry; 2.421 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); 2.422 + 2.423 errno = 0; 2.424 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { 2.425 2.426 @@ -528,56 +766,55 @@ 2.427 2.428 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 2.429 2.430 - // attempt to remove all unexpected files, except "." and ".." 2.431 - remove_file(dirname, entry->d_name); 2.432 + // Attempt to remove all unexpected files, except "." and "..". 2.433 + unlink(entry->d_name); 2.434 } 2.435 2.436 errno = 0; 2.437 continue; 2.438 } 2.439 2.440 - // we now have a file name that converts to a valid integer 2.441 + // We now have a file name that converts to a valid integer 2.442 // that could represent a process id . if this process id 2.443 // matches the current process id or the process is not running, 2.444 // then remove the stale file resources. 2.445 // 2.446 - // process liveness is detected by sending signal number 0 to 2.447 + // Process liveness is detected by sending signal number 0 to 2.448 // the process id (see kill(2)). if kill determines that the 2.449 // process does not exist, then the file resources are removed. 2.450 // if kill determines that that we don't have permission to 2.451 // signal the process, then the file resources are assumed to 2.452 // be stale and are removed because the resources for such a 2.453 // process should be in a different user specific directory. 2.454 - // 2.455 if ((pid == os::current_process_id()) || 2.456 (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) { 2.457 2.458 - remove_file(dirname, entry->d_name); 2.459 + unlink(entry->d_name); 2.460 } 2.461 errno = 0; 2.462 } 2.463 - os::closedir(dirp); 2.464 + 2.465 + // Close the directory and reset the current working directory. 2.466 + close_directory_secure_cwd(dirp, saved_cwd_fd); 2.467 + 2.468 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); 2.469 } 2.470 2.471 -// make the user specific temporary directory. Returns true if 2.472 +// Make the user specific temporary directory. Returns true if 2.473 // the directory exists and is secure upon return. Returns false 2.474 // if the directory exists but is either a symlink, is otherwise 2.475 // insecure, or if an error occurred. 2.476 -// 2.477 static bool make_user_tmp_dir(const char* dirname) { 2.478 2.479 - // create the directory with 0755 permissions. note that the directory 2.480 + // Create the directory with 0755 permissions. note that the directory 2.481 // will be owned by euid::egid, which may not be the same as uid::gid. 2.482 - // 2.483 if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) { 2.484 if (errno == EEXIST) { 2.485 // The directory already exists and was probably created by another 2.486 // JVM instance. However, this could also be the result of a 2.487 // deliberate symlink. Verify that the existing directory is safe. 2.488 - // 2.489 if (!is_directory_secure(dirname)) { 2.490 - // directory is not secure 2.491 + // Directory is not secure. 2.492 if (PrintMiscellaneous && Verbose) { 2.493 warning("%s directory is insecure\n", dirname); 2.494 } 2.495 @@ -613,19 +850,63 @@ 2.496 return -1; 2.497 } 2.498 2.499 + int saved_cwd_fd; 2.500 + // Open the directory and set the current working directory to it. 2.501 + DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd); 2.502 + if (dirp == NULL) { 2.503 + // Directory doesn't exist or is insecure, so cannot create shared 2.504 + // memory file. 2.505 + return -1; 2.506 + } 2.507 + 2.508 + // Open the filename in the current directory. 2.509 + // Cannot use O_TRUNC here; truncation of an existing file has to happen 2.510 + // after the is_file_secure() check below. 2.511 int result; 2.512 2.513 - RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result); 2.514 + // No O_NOFOLLOW defined at buildtime, and it is not documented for open; 2.515 + // so provide a workaround in this case. 2.516 +#ifdef O_NOFOLLOW 2.517 + RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result); 2.518 +#else 2.519 + // workaround function (jdk6 code) 2.520 + RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result); 2.521 +#endif 2.522 + 2.523 if (result == OS_ERR) { 2.524 if (PrintMiscellaneous && Verbose) { 2.525 - warning("could not create file %s: %s\n", filename, strerror(errno)); 2.526 + if (errno == ELOOP) { 2.527 + warning("file %s is a symlink and is not secure\n", filename); 2.528 + } else { 2.529 + warning("could not create file %s: %s\n", filename, strerror(errno)); 2.530 + } 2.531 } 2.532 + // Close the directory and reset the current working directory. 2.533 + close_directory_secure_cwd(dirp, saved_cwd_fd); 2.534 + 2.535 return -1; 2.536 } 2.537 + // Close the directory and reset the current working directory. 2.538 + close_directory_secure_cwd(dirp, saved_cwd_fd); 2.539 2.540 // save the file descriptor 2.541 int fd = result; 2.542 2.543 + // Check to see if the file is secure. 2.544 + if (!is_file_secure(fd, filename)) { 2.545 + ::close(fd); 2.546 + return -1; 2.547 + } 2.548 + 2.549 + // Truncate the file to get rid of any existing data. 2.550 + RESTARTABLE(::ftruncate(fd, (off_t)0), result); 2.551 + if (result == OS_ERR) { 2.552 + if (PrintMiscellaneous && Verbose) { 2.553 + warning("could not truncate shared memory file: %s\n", strerror(errno)); 2.554 + } 2.555 + ::close(fd); 2.556 + return -1; 2.557 + } 2.558 // set the file size 2.559 RESTARTABLE(::ftruncate(fd, (off_t)size), result); 2.560 if (result == OS_ERR) { 2.561 @@ -647,7 +928,14 @@ 2.562 2.563 // open the file 2.564 int result; 2.565 + // No O_NOFOLLOW defined at buildtime, and it is not documented for open; 2.566 + // so provide a workaround in this case 2.567 +#ifdef O_NOFOLLOW 2.568 RESTARTABLE(::open(filename, oflags), result); 2.569 +#else 2.570 + RESTARTABLE(::open_o_nofollow(filename, oflags), result); 2.571 +#endif 2.572 + 2.573 if (result == OS_ERR) { 2.574 if (errno == ENOENT) { 2.575 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 2.576 @@ -661,8 +949,15 @@ 2.577 THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno)); 2.578 } 2.579 } 2.580 + int fd = result; 2.581 2.582 - return result; 2.583 + // Check to see if the file is secure. 2.584 + if (!is_file_secure(fd, filename)) { 2.585 + ::close(fd); 2.586 + return -1; 2.587 + } 2.588 + 2.589 + return fd; 2.590 } 2.591 2.592 // create a named shared memory region. returns the address of the 2.593 @@ -694,13 +989,21 @@ 2.594 char* dirname = get_user_tmp_dir(user_name); 2.595 char* filename = get_sharedmem_filename(dirname, vmid); 2.596 2.597 + // Get the short filename. 2.598 + char* short_filename = strrchr(filename, '/'); 2.599 + if (short_filename == NULL) { 2.600 + short_filename = filename; 2.601 + } else { 2.602 + short_filename++; 2.603 + } 2.604 + 2.605 // cleanup any stale shared memory files 2.606 cleanup_sharedmem_resources(dirname); 2.607 2.608 assert(((size > 0) && (size % os::vm_page_size() == 0)), 2.609 "unexpected PerfMemory region size"); 2.610 2.611 - fd = create_sharedmem_resources(dirname, filename, size); 2.612 + fd = create_sharedmem_resources(dirname, short_filename, size); 2.613 2.614 FREE_C_HEAP_ARRAY(char, user_name, mtInternal); 2.615 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); 2.616 @@ -732,6 +1035,9 @@ 2.617 // clear the shared memory region 2.618 (void)::memset((void*) mapAddress, 0, size); 2.619 2.620 + // It does not go through os api, the operation has to record from here. 2.621 + MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal); 2.622 + 2.623 return mapAddress; 2.624 } 2.625 2.626 @@ -806,7 +1112,7 @@ 2.627 char* mapAddress; 2.628 int result; 2.629 int fd; 2.630 - size_t size; 2.631 + size_t size = 0; 2.632 const char* luser = NULL; 2.633 2.634 int mmap_prot; 2.635 @@ -818,12 +1124,18 @@ 2.636 // constructs for the file and the shared memory mapping. 2.637 if (mode == PerfMemory::PERF_MODE_RO) { 2.638 mmap_prot = PROT_READ; 2.639 + 2.640 + // No O_NOFOLLOW defined at buildtime, and it is not documented for open. 2.641 +#ifdef O_NOFOLLOW 2.642 + file_flags = O_RDONLY | O_NOFOLLOW; 2.643 +#else 2.644 file_flags = O_RDONLY; 2.645 +#endif 2.646 } 2.647 else if (mode == PerfMemory::PERF_MODE_RW) { 2.648 #ifdef LATER 2.649 mmap_prot = PROT_READ | PROT_WRITE; 2.650 - file_flags = O_RDWR; 2.651 + file_flags = O_RDWR | O_NOFOLLOW; 2.652 #else 2.653 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 2.654 "Unsupported access mode"); 2.655 @@ -853,6 +1165,9 @@ 2.656 // 2.657 if (!is_directory_secure(dirname)) { 2.658 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); 2.659 + if (luser != user) { 2.660 + FREE_C_HEAP_ARRAY(char, luser, mtInternal); 2.661 + } 2.662 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 2.663 "Process not found"); 2.664 } 2.665 @@ -897,6 +1212,9 @@ 2.666 "Could not map PerfMemory"); 2.667 } 2.668 2.669 + // It does not go through os api, the operation has to record from here. 2.670 + MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal); 2.671 + 2.672 *addr = mapAddress; 2.673 *sizep = size; 2.674