1 /* 2 * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 # include "incls/_precompiled.incl" 26 # include "incls/_perfMemory_windows.cpp.incl" 27 28 #include <windows.h> 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <errno.h> 32 #include <lmcons.h> 33 34 typedef BOOL (WINAPI *SetSecurityDescriptorControlFnPtr)( 35 IN PSECURITY_DESCRIPTOR pSecurityDescriptor, 36 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, 37 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet); 38 39 // Standard Memory Implementation Details 40 41 // create the PerfData memory region in standard memory. 42 // 43 static char* create_standard_memory(size_t size) { 44 45 // allocate an aligned chuck of memory 46 char* mapAddress = os::reserve_memory(size); 47 48 if (mapAddress == NULL) { 49 return NULL; 50 } 51 52 // commit memory 53 if (!os::commit_memory(mapAddress, size)) { 54 if (PrintMiscellaneous && Verbose) { 55 warning("Could not commit PerfData memory\n"); 56 } 57 os::release_memory(mapAddress, size); 58 return NULL; 59 } 60 61 return mapAddress; 62 } 63 64 // delete the PerfData memory region 65 // 66 static void delete_standard_memory(char* addr, size_t size) { 67 68 // there are no persistent external resources to cleanup for standard 69 // memory. since DestroyJavaVM does not support unloading of the JVM, 70 // cleanup of the memory resource is not performed. The memory will be 71 // reclaimed by the OS upon termination of the process. 72 // 73 return; 74 75 } 76 77 // save the specified memory region to the given file 78 // 79 static void save_memory_to_file(char* addr, size_t size) { 80 81 const char* destfile = PerfMemory::get_perfdata_file_path(); 82 assert(destfile[0] != '\0', "invalid Perfdata file path"); 83 84 int fd = ::_open(destfile, _O_BINARY|_O_CREAT|_O_WRONLY|_O_TRUNC, 85 _S_IREAD|_S_IWRITE); 86 87 if (fd == OS_ERR) { 88 if (PrintMiscellaneous && Verbose) { 89 warning("Could not create Perfdata save file: %s: %s\n", 90 destfile, strerror(errno)); 91 } 92 } else { 93 for (size_t remaining = size; remaining > 0;) { 94 95 int nbytes = ::_write(fd, addr, (unsigned int)remaining); 96 if (nbytes == OS_ERR) { 97 if (PrintMiscellaneous && Verbose) { 98 warning("Could not write Perfdata save file: %s: %s\n", 99 destfile, strerror(errno)); 100 } 101 break; 102 } 103 104 remaining -= (size_t)nbytes; 105 addr += nbytes; 106 } 107 108 int result = ::_close(fd); 109 if (PrintMiscellaneous && Verbose) { 110 if (result == OS_ERR) { 111 warning("Could not close %s: %s\n", destfile, strerror(errno)); 112 } 113 } 114 } 115 116 FREE_C_HEAP_ARRAY(char, destfile); 117 } 118 119 // Shared Memory Implementation Details 120 121 // Note: the win32 shared memory implementation uses two objects to represent 122 // the shared memory: a windows kernel based file mapping object and a backing 123 // store file. On windows, the name space for shared memory is a kernel 124 // based name space that is disjoint from other win32 name spaces. Since Java 125 // is unaware of this name space, a parallel file system based name space is 126 // maintained, which provides a common file system based shared memory name 127 // space across the supported platforms and one that Java apps can deal with 128 // through simple file apis. 129 // 130 // For performance and resource cleanup reasons, it is recommended that the 131 // user specific directory and the backing store file be stored in either a 132 // RAM based file system or a local disk based file system. Network based 133 // file systems are not recommended for performance reasons. In addition, 134 // use of SMB network based file systems may result in unsuccesful cleanup 135 // of the disk based resource on exit of the VM. The Windows TMP and TEMP 136 // environement variables, as used by the GetTempPath() Win32 API (see 137 // os::get_temp_directory() in os_win32.cpp), control the location of the 138 // user specific directory and the shared memory backing store file. 139 140 static HANDLE sharedmem_fileMapHandle = NULL; 141 static HANDLE sharedmem_fileHandle = INVALID_HANDLE_VALUE; 142 static char* sharedmem_fileName = NULL; 143 144 // return the user specific temporary directory name. 145 // 146 // the caller is expected to free the allocated memory. 147 // 148 static char* get_user_tmp_dir(const char* user) { 149 150 const char* tmpdir = os::get_temp_directory(); 151 const char* perfdir = PERFDATA_NAME; 152 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; 153 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); 154 155 // construct the path name to user specific tmp directory 156 _snprintf(dirname, nbytes, "%s\\%s_%s", tmpdir, perfdir, user); 157 158 return dirname; 159 } 160 161 // convert the given file name into a process id. if the file 162 // does not meet the file naming constraints, return 0. 163 // 164 static int filename_to_pid(const char* filename) { 165 166 // a filename that doesn't begin with a digit is not a 167 // candidate for conversion. 168 // 169 if (!isdigit(*filename)) { 170 return 0; 171 } 172 173 // check if file name can be converted to an integer without 174 // any leftover characters. 175 // 176 char* remainder = NULL; 177 errno = 0; 178 int pid = (int)strtol(filename, &remainder, 10); 179 180 if (errno != 0) { 181 return 0; 182 } 183 184 // check for left over characters. If any, then the filename is 185 // not a candidate for conversion. 186 // 187 if (remainder != NULL && *remainder != '\0') { 188 return 0; 189 } 190 191 // successful conversion, return the pid 192 return pid; 193 } 194 195 // check if the given path is considered a secure directory for 196 // the backing store files. Returns true if the directory exists 197 // and is considered a secure location. Returns false if the path 198 // is a symbolic link or if an error occurred. 199 // 200 static bool is_directory_secure(const char* path) { 201 202 DWORD fa; 203 204 fa = GetFileAttributes(path); 205 if (fa == 0xFFFFFFFF) { 206 DWORD lasterror = GetLastError(); 207 if (lasterror == ERROR_FILE_NOT_FOUND) { 208 return false; 209 } 210 else { 211 // unexpected error, declare the path insecure 212 if (PrintMiscellaneous && Verbose) { 213 warning("could not get attributes for file %s: ", 214 " lasterror = %d\n", path, lasterror); 215 } 216 return false; 217 } 218 } 219 220 if (fa & FILE_ATTRIBUTE_REPARSE_POINT) { 221 // we don't accept any redirection for the user specific directory 222 // so declare the path insecure. This may be too conservative, 223 // as some types of reparse points might be acceptable, but it 224 // is probably more secure to avoid these conditions. 225 // 226 if (PrintMiscellaneous && Verbose) { 227 warning("%s is a reparse point\n", path); 228 } 229 return false; 230 } 231 232 if (fa & FILE_ATTRIBUTE_DIRECTORY) { 233 // this is the expected case. Since windows supports symbolic 234 // links to directories only, not to files, there is no need 235 // to check for open write permissions on the directory. If the 236 // directory has open write permissions, any files deposited that 237 // are not expected will be removed by the cleanup code. 238 // 239 return true; 240 } 241 else { 242 // this is either a regular file or some other type of file, 243 // any of which are unexpected and therefore insecure. 244 // 245 if (PrintMiscellaneous && Verbose) { 246 warning("%s is not a directory, file attributes = " 247 INTPTR_FORMAT "\n", path, fa); 248 } 249 return false; 250 } 251 } 252 253 // return the user name for the owner of this process 254 // 255 // the caller is expected to free the allocated memory. 256 // 257 static char* get_user_name() { 258 259 /* get the user name. This code is adapted from code found in 260 * the jdk in src/windows/native/java/lang/java_props_md.c 261 * java_props_md.c 1.29 02/02/06. According to the original 262 * source, the call to GetUserName is avoided because of a resulting 263 * increase in footprint of 100K. 264 */ 265 char* user = getenv("USERNAME"); 266 char buf[UNLEN+1]; 267 DWORD buflen = sizeof(buf); 268 if (user == NULL || strlen(user) == 0) { 269 if (GetUserName(buf, &buflen)) { 270 user = buf; 271 } 272 else { 273 return NULL; 274 } 275 } 276 277 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1); 278 strcpy(user_name, user); 279 280 return user_name; 281 } 282 283 // return the name of the user that owns the process identified by vmid. 284 // 285 // This method uses a slow directory search algorithm to find the backing 286 // store file for the specified vmid and returns the user name, as determined 287 // by the user name suffix of the hsperfdata_<username> directory name. 288 // 289 // the caller is expected to free the allocated memory. 290 // 291 static char* get_user_name_slow(int vmid) { 292 293 // directory search 294 char* oldest_user = NULL; 295 time_t oldest_ctime = 0; 296 297 const char* tmpdirname = os::get_temp_directory(); 298 299 DIR* tmpdirp = os::opendir(tmpdirname); 300 301 if (tmpdirp == NULL) { 302 return NULL; 303 } 304 305 // for each entry in the directory that matches the pattern hsperfdata_*, 306 // open the directory and check if the file for the given vmid exists. 307 // The file with the expected name and the latest creation date is used 308 // to determine the user name for the process id. 309 // 310 struct dirent* dentry; 311 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); 312 errno = 0; 313 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { 314 315 // check if the directory entry is a hsperfdata file 316 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { 317 continue; 318 } 319 320 char* usrdir_name = NEW_C_HEAP_ARRAY(char, 321 strlen(tmpdirname) + strlen(dentry->d_name) + 2); 322 strcpy(usrdir_name, tmpdirname); 323 strcat(usrdir_name, "\\"); 324 strcat(usrdir_name, dentry->d_name); 325 326 DIR* subdirp = os::opendir(usrdir_name); 327 328 if (subdirp == NULL) { 329 FREE_C_HEAP_ARRAY(char, usrdir_name); 330 continue; 331 } 332 333 // Since we don't create the backing store files in directories 334 // pointed to by symbolic links, we also don't follow them when 335 // looking for the files. We check for a symbolic link after the 336 // call to opendir in order to eliminate a small window where the 337 // symlink can be exploited. 338 // 339 if (!is_directory_secure(usrdir_name)) { 340 FREE_C_HEAP_ARRAY(char, usrdir_name); 341 os::closedir(subdirp); 342 continue; 343 } 344 345 struct dirent* udentry; 346 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); 347 errno = 0; 348 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { 349 350 if (filename_to_pid(udentry->d_name) == vmid) { 351 struct stat statbuf; 352 353 char* filename = NEW_C_HEAP_ARRAY(char, 354 strlen(usrdir_name) + strlen(udentry->d_name) + 2); 355 356 strcpy(filename, usrdir_name); 357 strcat(filename, "\\"); 358 strcat(filename, udentry->d_name); 359 360 if (::stat(filename, &statbuf) == OS_ERR) { 361 FREE_C_HEAP_ARRAY(char, filename); 362 continue; 363 } 364 365 // skip over files that are not regular files. 366 if ((statbuf.st_mode & S_IFMT) != S_IFREG) { 367 FREE_C_HEAP_ARRAY(char, filename); 368 continue; 369 } 370 371 // compare and save filename with latest creation time 372 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { 373 374 if (statbuf.st_ctime > oldest_ctime) { 375 char* user = strchr(dentry->d_name, '_') + 1; 376 377 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); 378 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); 379 380 strcpy(oldest_user, user); 381 oldest_ctime = statbuf.st_ctime; 382 } 383 } 384 385 FREE_C_HEAP_ARRAY(char, filename); 386 } 387 } 388 os::closedir(subdirp); 389 FREE_C_HEAP_ARRAY(char, udbuf); 390 FREE_C_HEAP_ARRAY(char, usrdir_name); 391 } 392 os::closedir(tmpdirp); 393 FREE_C_HEAP_ARRAY(char, tdbuf); 394 395 return(oldest_user); 396 } 397 398 // return the name of the user that owns the process identified by vmid. 399 // 400 // note: this method should only be used via the Perf native methods. 401 // There are various costs to this method and limiting its use to the 402 // Perf native methods limits the impact to monitoring applications only. 403 // 404 static char* get_user_name(int vmid) { 405 406 // A fast implementation is not provided at this time. It's possible 407 // to provide a fast process id to user name mapping function using 408 // the win32 apis, but the default ACL for the process object only 409 // allows processes with the same owner SID to acquire the process 410 // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible 411 // to have the JVM change the ACL for the process object to allow arbitrary 412 // users to access the process handle and the process security token. 413 // The security ramifications need to be studied before providing this 414 // mechanism. 415 // 416 return get_user_name_slow(vmid); 417 } 418 419 // return the name of the shared memory file mapping object for the 420 // named shared memory region for the given user name and vmid. 421 // 422 // The file mapping object's name is not the file name. It is a name 423 // in a separate name space. 424 // 425 // the caller is expected to free the allocated memory. 426 // 427 static char *get_sharedmem_objectname(const char* user, int vmid) { 428 429 // construct file mapping object's name, add 3 for two '_' and a 430 // null terminator. 431 int nbytes = (int)strlen(PERFDATA_NAME) + (int)strlen(user) + 3; 432 433 // the id is converted to an unsigned value here because win32 allows 434 // negative process ids. However, OpenFileMapping API complains 435 // about a name containing a '-' characters. 436 // 437 nbytes += UINT_CHARS; 438 char* name = NEW_C_HEAP_ARRAY(char, nbytes); 439 _snprintf(name, nbytes, "%s_%s_%u", PERFDATA_NAME, user, vmid); 440 441 return name; 442 } 443 444 // return the file name of the backing store file for the named 445 // shared memory region for the given user name and vmid. 446 // 447 // the caller is expected to free the allocated memory. 448 // 449 static char* get_sharedmem_filename(const char* dirname, int vmid) { 450 451 // add 2 for the file separator and a null terminator. 452 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; 453 454 char* name = NEW_C_HEAP_ARRAY(char, nbytes); 455 _snprintf(name, nbytes, "%s\\%d", dirname, vmid); 456 457 return name; 458 } 459 460 // remove file 461 // 462 // this method removes the file with the given file name. 463 // 464 // Note: if the indicated file is on an SMB network file system, this 465 // method may be unsuccessful in removing the file. 466 // 467 static void remove_file(const char* dirname, const char* filename) { 468 469 size_t nbytes = strlen(dirname) + strlen(filename) + 2; 470 char* path = NEW_C_HEAP_ARRAY(char, nbytes); 471 472 strcpy(path, dirname); 473 strcat(path, "\\"); 474 strcat(path, filename); 475 476 if (::unlink(path) == OS_ERR) { 477 if (PrintMiscellaneous && Verbose) { 478 if (errno != ENOENT) { 479 warning("Could not unlink shared memory backing" 480 " store file %s : %s\n", path, strerror(errno)); 481 } 482 } 483 } 484 485 FREE_C_HEAP_ARRAY(char, path); 486 } 487 488 // returns true if the process represented by pid is alive, otherwise 489 // returns false. the validity of the result is only accurate if the 490 // target process is owned by the same principal that owns this process. 491 // this method should not be used if to test the status of an otherwise 492 // arbitrary process unless it is know that this process has the appropriate 493 // privileges to guarantee a result valid. 494 // 495 static bool is_alive(int pid) { 496 497 HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); 498 if (ph == NULL) { 499 // the process does not exist. 500 if (PrintMiscellaneous && Verbose) { 501 DWORD lastError = GetLastError(); 502 if (lastError != ERROR_INVALID_PARAMETER) { 503 warning("OpenProcess failed: %d\n", GetLastError()); 504 } 505 } 506 return false; 507 } 508 509 DWORD exit_status; 510 if (!GetExitCodeProcess(ph, &exit_status)) { 511 if (PrintMiscellaneous && Verbose) { 512 warning("GetExitCodeProcess failed: %d\n", GetLastError()); 513 } 514 CloseHandle(ph); 515 return false; 516 } 517 518 CloseHandle(ph); 519 return (exit_status == STILL_ACTIVE) ? true : false; 520 } 521 522 // check if the file system is considered secure for the backing store files 523 // 524 static bool is_filesystem_secure(const char* path) { 525 526 char root_path[MAX_PATH]; 527 char fs_type[MAX_PATH]; 528 529 if (PerfBypassFileSystemCheck) { 530 if (PrintMiscellaneous && Verbose) { 531 warning("bypassing file system criteria checks for %s\n", path); 532 } 533 return true; 534 } 535 536 char* first_colon = strchr((char *)path, ':'); 537 if (first_colon == NULL) { 538 if (PrintMiscellaneous && Verbose) { 539 warning("expected device specifier in path: %s\n", path); 540 } 541 return false; 542 } 543 544 size_t len = (size_t)(first_colon - path); 545 assert(len + 2 <= MAX_PATH, "unexpected device specifier length"); 546 strncpy(root_path, path, len + 1); 547 root_path[len + 1] = '\\'; 548 root_path[len + 2] = '\0'; 549 550 // check that we have something like "C:\" or "AA:\" 551 assert(strlen(root_path) >= 3, "device specifier too short"); 552 assert(strchr(root_path, ':') != NULL, "bad device specifier format"); 553 assert(strchr(root_path, '\\') != NULL, "bad device specifier format"); 554 555 DWORD maxpath; 556 DWORD flags; 557 558 if (!GetVolumeInformation(root_path, NULL, 0, NULL, &maxpath, 559 &flags, fs_type, MAX_PATH)) { 560 // we can't get information about the volume, so assume unsafe. 561 if (PrintMiscellaneous && Verbose) { 562 warning("could not get device information for %s: " 563 " path = %s: lasterror = %d\n", 564 root_path, path, GetLastError()); 565 } 566 return false; 567 } 568 569 if ((flags & FS_PERSISTENT_ACLS) == 0) { 570 // file system doesn't support ACLs, declare file system unsafe 571 if (PrintMiscellaneous && Verbose) { 572 warning("file system type %s on device %s does not support" 573 " ACLs\n", fs_type, root_path); 574 } 575 return false; 576 } 577 578 if ((flags & FS_VOL_IS_COMPRESSED) != 0) { 579 // file system is compressed, declare file system unsafe 580 if (PrintMiscellaneous && Verbose) { 581 warning("file system type %s on device %s is compressed\n", 582 fs_type, root_path); 583 } 584 return false; 585 } 586 587 return true; 588 } 589 590 // cleanup stale shared memory resources 591 // 592 // This method attempts to remove all stale shared memory files in 593 // the named user temporary directory. It scans the named directory 594 // for files matching the pattern ^$[0-9]*$. For each file found, the 595 // process id is extracted from the file name and a test is run to 596 // determine if the process is alive. If the process is not alive, 597 // any stale file resources are removed. 598 // 599 static void cleanup_sharedmem_resources(const char* dirname) { 600 601 // open the user temp directory 602 DIR* dirp = os::opendir(dirname); 603 604 if (dirp == NULL) { 605 // directory doesn't exist, so there is nothing to cleanup 606 return; 607 } 608 609 if (!is_directory_secure(dirname)) { 610 // the directory is not secure, don't attempt any cleanup 611 return; 612 } 613 614 // for each entry in the directory that matches the expected file 615 // name pattern, determine if the file resources are stale and if 616 // so, remove the file resources. Note, instrumented HotSpot processes 617 // for this user may start and/or terminate during this search and 618 // remove or create new files in this directory. The behavior of this 619 // loop under these conditions is dependent upon the implementation of 620 // opendir/readdir. 621 // 622 struct dirent* entry; 623 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); 624 errno = 0; 625 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { 626 627 int pid = filename_to_pid(entry->d_name); 628 629 if (pid == 0) { 630 631 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 632 633 // attempt to remove all unexpected files, except "." and ".." 634 remove_file(dirname, entry->d_name); 635 } 636 637 errno = 0; 638 continue; 639 } 640 641 // we now have a file name that converts to a valid integer 642 // that could represent a process id . if this process id 643 // matches the current process id or the process is not running, 644 // then remove the stale file resources. 645 // 646 // process liveness is detected by checking the exit status 647 // of the process. if the process id is valid and the exit status 648 // indicates that it is still running, the file file resources 649 // are not removed. If the process id is invalid, or if we don't 650 // have permissions to check the process status, or if the process 651 // id is valid and the process has terminated, the the file resources 652 // are assumed to be stale and are removed. 653 // 654 if (pid == os::current_process_id() || !is_alive(pid)) { 655 656 // we can only remove the file resources. Any mapped views 657 // of the file can only be unmapped by the processes that 658 // opened those views and the file mapping object will not 659 // get removed until all views are unmapped. 660 // 661 remove_file(dirname, entry->d_name); 662 } 663 errno = 0; 664 } 665 os::closedir(dirp); 666 FREE_C_HEAP_ARRAY(char, dbuf); 667 } 668 669 // create a file mapping object with the requested name, and size 670 // from the file represented by the given Handle object 671 // 672 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) { 673 674 DWORD lowSize = (DWORD)size; 675 DWORD highSize = 0; 676 HANDLE fmh = NULL; 677 678 // Create a file mapping object with the given name. This function 679 // will grow the file to the specified size. 680 // 681 fmh = CreateFileMapping( 682 fh, /* HANDLE file handle for backing store */ 683 fsa, /* LPSECURITY_ATTRIBUTES Not inheritable */ 684 PAGE_READWRITE, /* DWORD protections */ 685 highSize, /* DWORD High word of max size */ 686 lowSize, /* DWORD Low word of max size */ 687 name); /* LPCTSTR name for object */ 688 689 if (fmh == NULL) { 690 if (PrintMiscellaneous && Verbose) { 691 warning("CreateFileMapping failed, lasterror = %d\n", GetLastError()); 692 } 693 return NULL; 694 } 695 696 if (GetLastError() == ERROR_ALREADY_EXISTS) { 697 698 // a stale file mapping object was encountered. This object may be 699 // owned by this or some other user and cannot be removed until 700 // the other processes either exit or close their mapping objects 701 // and/or mapped views of this mapping object. 702 // 703 if (PrintMiscellaneous && Verbose) { 704 warning("file mapping already exists, lasterror = %d\n", GetLastError()); 705 } 706 707 CloseHandle(fmh); 708 return NULL; 709 } 710 711 return fmh; 712 } 713 714 715 // method to free the given security descriptor and the contained 716 // access control list. 717 // 718 static void free_security_desc(PSECURITY_DESCRIPTOR pSD) { 719 720 BOOL success, exists, isdefault; 721 PACL pACL; 722 723 if (pSD != NULL) { 724 725 // get the access control list from the security descriptor 726 success = GetSecurityDescriptorDacl(pSD, &exists, &pACL, &isdefault); 727 728 // if an ACL existed and it was not a default acl, then it must 729 // be an ACL we enlisted. free the resources. 730 // 731 if (success && exists && pACL != NULL && !isdefault) { 732 FREE_C_HEAP_ARRAY(char, pACL); 733 } 734 735 // free the security descriptor 736 FREE_C_HEAP_ARRAY(char, pSD); 737 } 738 } 739 740 // method to free up a security attributes structure and any 741 // contained security descriptors and ACL 742 // 743 static void free_security_attr(LPSECURITY_ATTRIBUTES lpSA) { 744 745 if (lpSA != NULL) { 746 // free the contained security descriptor and the ACL 747 free_security_desc(lpSA->lpSecurityDescriptor); 748 lpSA->lpSecurityDescriptor = NULL; 749 750 // free the security attributes structure 751 FREE_C_HEAP_ARRAY(char, lpSA); 752 } 753 } 754 755 // get the user SID for the process indicated by the process handle 756 // 757 static PSID get_user_sid(HANDLE hProcess) { 758 759 HANDLE hAccessToken; 760 PTOKEN_USER token_buf = NULL; 761 DWORD rsize = 0; 762 763 if (hProcess == NULL) { 764 return NULL; 765 } 766 767 // get the process token 768 if (!OpenProcessToken(hProcess, TOKEN_READ, &hAccessToken)) { 769 if (PrintMiscellaneous && Verbose) { 770 warning("OpenProcessToken failure: lasterror = %d \n", GetLastError()); 771 } 772 return NULL; 773 } 774 775 // determine the size of the token structured needed to retrieve 776 // the user token information from the access token. 777 // 778 if (!GetTokenInformation(hAccessToken, TokenUser, NULL, rsize, &rsize)) { 779 DWORD lasterror = GetLastError(); 780 if (lasterror != ERROR_INSUFFICIENT_BUFFER) { 781 if (PrintMiscellaneous && Verbose) { 782 warning("GetTokenInformation failure: lasterror = %d," 783 " rsize = %d\n", lasterror, rsize); 784 } 785 CloseHandle(hAccessToken); 786 return NULL; 787 } 788 } 789 790 token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize); 791 792 // get the user token information 793 if (!GetTokenInformation(hAccessToken, TokenUser, token_buf, rsize, &rsize)) { 794 if (PrintMiscellaneous && Verbose) { 795 warning("GetTokenInformation failure: lasterror = %d," 796 " rsize = %d\n", GetLastError(), rsize); 797 } 798 FREE_C_HEAP_ARRAY(char, token_buf); 799 CloseHandle(hAccessToken); 800 return NULL; 801 } 802 803 DWORD nbytes = GetLengthSid(token_buf->User.Sid); 804 PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes); 805 806 if (!CopySid(nbytes, pSID, token_buf->User.Sid)) { 807 if (PrintMiscellaneous && Verbose) { 808 warning("GetTokenInformation failure: lasterror = %d," 809 " rsize = %d\n", GetLastError(), rsize); 810 } 811 FREE_C_HEAP_ARRAY(char, token_buf); 812 FREE_C_HEAP_ARRAY(char, pSID); 813 CloseHandle(hAccessToken); 814 return NULL; 815 } 816 817 // close the access token. 818 CloseHandle(hAccessToken); 819 FREE_C_HEAP_ARRAY(char, token_buf); 820 821 return pSID; 822 } 823 824 // structure used to consolidate access control entry information 825 // 826 typedef struct ace_data { 827 PSID pSid; // SID of the ACE 828 DWORD mask; // mask for the ACE 829 } ace_data_t; 830 831 832 // method to add an allow access control entry with the access rights 833 // indicated in mask for the principal indicated in SID to the given 834 // security descriptor. Much of the DACL handling was adapted from 835 // the example provided here: 836 // http://support.microsoft.com/kb/102102/EN-US/ 837 // 838 839 static bool add_allow_aces(PSECURITY_DESCRIPTOR pSD, 840 ace_data_t aces[], int ace_count) { 841 PACL newACL = NULL; 842 PACL oldACL = NULL; 843 844 if (pSD == NULL) { 845 return false; 846 } 847 848 BOOL exists, isdefault; 849 850 // retrieve any existing access control list. 851 if (!GetSecurityDescriptorDacl(pSD, &exists, &oldACL, &isdefault)) { 852 if (PrintMiscellaneous && Verbose) { 853 warning("GetSecurityDescriptor failure: lasterror = %d \n", 854 GetLastError()); 855 } 856 return false; 857 } 858 859 // get the size of the DACL 860 ACL_SIZE_INFORMATION aclinfo; 861 862 // GetSecurityDescriptorDacl may return true value for exists (lpbDaclPresent) 863 // while oldACL is NULL for some case. 864 if (oldACL == NULL) { 865 exists = FALSE; 866 } 867 868 if (exists) { 869 if (!GetAclInformation(oldACL, &aclinfo, 870 sizeof(ACL_SIZE_INFORMATION), 871 AclSizeInformation)) { 872 if (PrintMiscellaneous && Verbose) { 873 warning("GetAclInformation failure: lasterror = %d \n", GetLastError()); 874 return false; 875 } 876 } 877 } else { 878 aclinfo.AceCount = 0; // assume NULL DACL 879 aclinfo.AclBytesFree = 0; 880 aclinfo.AclBytesInUse = sizeof(ACL); 881 } 882 883 // compute the size needed for the new ACL 884 // initial size of ACL is sum of the following: 885 // * size of ACL structure. 886 // * size of each ACE structure that ACL is to contain minus the sid 887 // sidStart member (DWORD) of the ACE. 888 // * length of the SID that each ACE is to contain. 889 DWORD newACLsize = aclinfo.AclBytesInUse + 890 (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * ace_count; 891 for (int i = 0; i < ace_count; i++) { 892 newACLsize += GetLengthSid(aces[i].pSid); 893 } 894 895 // create the new ACL 896 newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize); 897 898 if (!InitializeAcl(newACL, newACLsize, ACL_REVISION)) { 899 if (PrintMiscellaneous && Verbose) { 900 warning("InitializeAcl failure: lasterror = %d \n", GetLastError()); 901 } 902 FREE_C_HEAP_ARRAY(char, newACL); 903 return false; 904 } 905 906 unsigned int ace_index = 0; 907 // copy any existing ACEs from the old ACL (if any) to the new ACL. 908 if (aclinfo.AceCount != 0) { 909 while (ace_index < aclinfo.AceCount) { 910 LPVOID ace; 911 if (!GetAce(oldACL, ace_index, &ace)) { 912 if (PrintMiscellaneous && Verbose) { 913 warning("InitializeAcl failure: lasterror = %d \n", GetLastError()); 914 } 915 FREE_C_HEAP_ARRAY(char, newACL); 916 return false; 917 } 918 if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) { 919 // this is an inherited, allowed ACE; break from loop so we can 920 // add the new access allowed, non-inherited ACE in the correct 921 // position, immediately following all non-inherited ACEs. 922 break; 923 } 924 925 // determine if the SID of this ACE matches any of the SIDs 926 // for which we plan to set ACEs. 927 int matches = 0; 928 for (int i = 0; i < ace_count; i++) { 929 if (EqualSid(aces[i].pSid, &(((ACCESS_ALLOWED_ACE *)ace)->SidStart))) { 930 matches++; 931 break; 932 } 933 } 934 935 // if there are no SID matches, then add this existing ACE to the new ACL 936 if (matches == 0) { 937 if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace, 938 ((PACE_HEADER)ace)->AceSize)) { 939 if (PrintMiscellaneous && Verbose) { 940 warning("AddAce failure: lasterror = %d \n", GetLastError()); 941 } 942 FREE_C_HEAP_ARRAY(char, newACL); 943 return false; 944 } 945 } 946 ace_index++; 947 } 948 } 949 950 // add the passed-in access control entries to the new ACL 951 for (int i = 0; i < ace_count; i++) { 952 if (!AddAccessAllowedAce(newACL, ACL_REVISION, 953 aces[i].mask, aces[i].pSid)) { 954 if (PrintMiscellaneous && Verbose) { 955 warning("AddAccessAllowedAce failure: lasterror = %d \n", 956 GetLastError()); 957 } 958 FREE_C_HEAP_ARRAY(char, newACL); 959 return false; 960 } 961 } 962 963 // now copy the rest of the inherited ACEs from the old ACL 964 if (aclinfo.AceCount != 0) { 965 // picking up at ace_index, where we left off in the 966 // previous ace_index loop 967 while (ace_index < aclinfo.AceCount) { 968 LPVOID ace; 969 if (!GetAce(oldACL, ace_index, &ace)) { 970 if (PrintMiscellaneous && Verbose) { 971 warning("InitializeAcl failure: lasterror = %d \n", GetLastError()); 972 } 973 FREE_C_HEAP_ARRAY(char, newACL); 974 return false; 975 } 976 if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace, 977 ((PACE_HEADER)ace)->AceSize)) { 978 if (PrintMiscellaneous && Verbose) { 979 warning("AddAce failure: lasterror = %d \n", GetLastError()); 980 } 981 FREE_C_HEAP_ARRAY(char, newACL); 982 return false; 983 } 984 ace_index++; 985 } 986 } 987 988 // add the new ACL to the security descriptor. 989 if (!SetSecurityDescriptorDacl(pSD, TRUE, newACL, FALSE)) { 990 if (PrintMiscellaneous && Verbose) { 991 warning("SetSecurityDescriptorDacl failure:" 992 " lasterror = %d \n", GetLastError()); 993 } 994 FREE_C_HEAP_ARRAY(char, newACL); 995 return false; 996 } 997 998 // if running on windows 2000 or later, set the automatic inheritance 999 // control flags. 1000 SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl; 1001 _SetSecurityDescriptorControl = (SetSecurityDescriptorControlFnPtr) 1002 GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")), 1003 "SetSecurityDescriptorControl"); 1004 1005 if (_SetSecurityDescriptorControl != NULL) { 1006 // We do not want to further propagate inherited DACLs, so making them 1007 // protected prevents that. 1008 if (!_SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED, 1009 SE_DACL_PROTECTED)) { 1010 if (PrintMiscellaneous && Verbose) { 1011 warning("SetSecurityDescriptorControl failure:" 1012 " lasterror = %d \n", GetLastError()); 1013 } 1014 FREE_C_HEAP_ARRAY(char, newACL); 1015 return false; 1016 } 1017 } 1018 // Note, the security descriptor maintains a reference to the newACL, not 1019 // a copy of it. Therefore, the newACL is not freed here. It is freed when 1020 // the security descriptor containing its reference is freed. 1021 // 1022 return true; 1023 } 1024 1025 // method to create a security attributes structure, which contains a 1026 // security descriptor and an access control list comprised of 0 or more 1027 // access control entries. The method take an array of ace_data structures 1028 // that indicate the ACE to be added to the security descriptor. 1029 // 1030 // the caller must free the resources associated with the security 1031 // attributes structure created by this method by calling the 1032 // free_security_attr() method. 1033 // 1034 static LPSECURITY_ATTRIBUTES make_security_attr(ace_data_t aces[], int count) { 1035 1036 // allocate space for a security descriptor 1037 PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) 1038 NEW_C_HEAP_ARRAY(char, SECURITY_DESCRIPTOR_MIN_LENGTH); 1039 1040 // initialize the security descriptor 1041 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { 1042 if (PrintMiscellaneous && Verbose) { 1043 warning("InitializeSecurityDescriptor failure: " 1044 "lasterror = %d \n", GetLastError()); 1045 } 1046 free_security_desc(pSD); 1047 return NULL; 1048 } 1049 1050 // add the access control entries 1051 if (!add_allow_aces(pSD, aces, count)) { 1052 free_security_desc(pSD); 1053 return NULL; 1054 } 1055 1056 // allocate and initialize the security attributes structure and 1057 // return it to the caller. 1058 // 1059 LPSECURITY_ATTRIBUTES lpSA = (LPSECURITY_ATTRIBUTES) 1060 NEW_C_HEAP_ARRAY(char, sizeof(SECURITY_ATTRIBUTES)); 1061 lpSA->nLength = sizeof(SECURITY_ATTRIBUTES); 1062 lpSA->lpSecurityDescriptor = pSD; 1063 lpSA->bInheritHandle = FALSE; 1064 1065 return(lpSA); 1066 } 1067 1068 // method to create a security attributes structure with a restrictive 1069 // access control list that creates a set access rights for the user/owner 1070 // of the securable object and a separate set access rights for everyone else. 1071 // also provides for full access rights for the administrator group. 1072 // 1073 // the caller must free the resources associated with the security 1074 // attributes structure created by this method by calling the 1075 // free_security_attr() method. 1076 // 1077 1078 static LPSECURITY_ATTRIBUTES make_user_everybody_admin_security_attr( 1079 DWORD umask, DWORD emask, DWORD amask) { 1080 1081 ace_data_t aces[3]; 1082 1083 // initialize the user ace data 1084 aces[0].pSid = get_user_sid(GetCurrentProcess()); 1085 aces[0].mask = umask; 1086 1087 // get the well known SID for BUILTIN\Administrators 1088 PSID administratorsSid = NULL; 1089 SID_IDENTIFIER_AUTHORITY SIDAuthAdministrators = SECURITY_NT_AUTHORITY; 1090 1091 if (!AllocateAndInitializeSid( &SIDAuthAdministrators, 2, 1092 SECURITY_BUILTIN_DOMAIN_RID, 1093 DOMAIN_ALIAS_RID_ADMINS, 1094 0, 0, 0, 0, 0, 0, &administratorsSid)) { 1095 1096 if (PrintMiscellaneous && Verbose) { 1097 warning("AllocateAndInitializeSid failure: " 1098 "lasterror = %d \n", GetLastError()); 1099 } 1100 return NULL; 1101 } 1102 1103 // initialize the ace data for administrator group 1104 aces[1].pSid = administratorsSid; 1105 aces[1].mask = amask; 1106 1107 // get the well known SID for the universal Everybody 1108 PSID everybodySid = NULL; 1109 SID_IDENTIFIER_AUTHORITY SIDAuthEverybody = SECURITY_WORLD_SID_AUTHORITY; 1110 1111 if (!AllocateAndInitializeSid( &SIDAuthEverybody, 1, SECURITY_WORLD_RID, 1112 0, 0, 0, 0, 0, 0, 0, &everybodySid)) { 1113 1114 if (PrintMiscellaneous && Verbose) { 1115 warning("AllocateAndInitializeSid failure: " 1116 "lasterror = %d \n", GetLastError()); 1117 } 1118 return NULL; 1119 } 1120 1121 // initialize the ace data for everybody else. 1122 aces[2].pSid = everybodySid; 1123 aces[2].mask = emask; 1124 1125 // create a security attributes structure with access control 1126 // entries as initialized above. 1127 LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3); 1128 FREE_C_HEAP_ARRAY(char, aces[0].pSid); 1129 FreeSid(everybodySid); 1130 FreeSid(administratorsSid); 1131 return(lpSA); 1132 } 1133 1134 1135 // method to create the security attributes structure for restricting 1136 // access to the user temporary directory. 1137 // 1138 // the caller must free the resources associated with the security 1139 // attributes structure created by this method by calling the 1140 // free_security_attr() method. 1141 // 1142 static LPSECURITY_ATTRIBUTES make_tmpdir_security_attr() { 1143 1144 // create full access rights for the user/owner of the directory 1145 // and read-only access rights for everybody else. This is 1146 // effectively equivalent to UNIX 755 permissions on a directory. 1147 // 1148 DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_ALL_ACCESS; 1149 DWORD emask = GENERIC_READ | FILE_LIST_DIRECTORY | FILE_TRAVERSE; 1150 DWORD amask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS; 1151 1152 return make_user_everybody_admin_security_attr(umask, emask, amask); 1153 } 1154 1155 // method to create the security attributes structure for restricting 1156 // access to the shared memory backing store file. 1157 // 1158 // the caller must free the resources associated with the security 1159 // attributes structure created by this method by calling the 1160 // free_security_attr() method. 1161 // 1162 static LPSECURITY_ATTRIBUTES make_file_security_attr() { 1163 1164 // create extensive access rights for the user/owner of the file 1165 // and attribute read-only access rights for everybody else. This 1166 // is effectively equivalent to UNIX 600 permissions on a file. 1167 // 1168 DWORD umask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS; 1169 DWORD emask = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | 1170 FILE_READ_EA | FILE_LIST_DIRECTORY | FILE_TRAVERSE; 1171 DWORD amask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS; 1172 1173 return make_user_everybody_admin_security_attr(umask, emask, amask); 1174 } 1175 1176 // method to create the security attributes structure for restricting 1177 // access to the name shared memory file mapping object. 1178 // 1179 // the caller must free the resources associated with the security 1180 // attributes structure created by this method by calling the 1181 // free_security_attr() method. 1182 // 1183 static LPSECURITY_ATTRIBUTES make_smo_security_attr() { 1184 1185 // create extensive access rights for the user/owner of the shared 1186 // memory object and attribute read-only access rights for everybody 1187 // else. This is effectively equivalent to UNIX 600 permissions on 1188 // on the shared memory object. 1189 // 1190 DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_MAP_ALL_ACCESS; 1191 DWORD emask = STANDARD_RIGHTS_READ; // attributes only 1192 DWORD amask = STANDARD_RIGHTS_ALL | FILE_MAP_ALL_ACCESS; 1193 1194 return make_user_everybody_admin_security_attr(umask, emask, amask); 1195 } 1196 1197 // make the user specific temporary directory 1198 // 1199 static bool make_user_tmp_dir(const char* dirname) { 1200 1201 1202 LPSECURITY_ATTRIBUTES pDirSA = make_tmpdir_security_attr(); 1203 if (pDirSA == NULL) { 1204 return false; 1205 } 1206 1207 1208 // create the directory with the given security attributes 1209 if (!CreateDirectory(dirname, pDirSA)) { 1210 DWORD lasterror = GetLastError(); 1211 if (lasterror == ERROR_ALREADY_EXISTS) { 1212 // The directory already exists and was probably created by another 1213 // JVM instance. However, this could also be the result of a 1214 // deliberate symlink. Verify that the existing directory is safe. 1215 // 1216 if (!is_directory_secure(dirname)) { 1217 // directory is not secure 1218 if (PrintMiscellaneous && Verbose) { 1219 warning("%s directory is insecure\n", dirname); 1220 } 1221 return false; 1222 } 1223 // The administrator should be able to delete this directory. 1224 // But the directory created by previous version of JVM may not 1225 // have permission for administrators to delete this directory. 1226 // So add full permission to the administrator. Also setting new 1227 // DACLs might fix the corrupted the DACLs. 1228 SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION; 1229 if (!SetFileSecurity(dirname, secInfo, pDirSA->lpSecurityDescriptor)) { 1230 if (PrintMiscellaneous && Verbose) { 1231 lasterror = GetLastError(); 1232 warning("SetFileSecurity failed for %s directory. lasterror %d \n", 1233 dirname, lasterror); 1234 } 1235 } 1236 } 1237 else { 1238 if (PrintMiscellaneous && Verbose) { 1239 warning("CreateDirectory failed: %d\n", GetLastError()); 1240 } 1241 return false; 1242 } 1243 } 1244 1245 // free the security attributes structure 1246 free_security_attr(pDirSA); 1247 1248 return true; 1249 } 1250 1251 // create the shared memory resources 1252 // 1253 // This function creates the shared memory resources. This includes 1254 // the backing store file and the file mapping shared memory object. 1255 // 1256 static HANDLE create_sharedmem_resources(const char* dirname, const char* filename, const char* objectname, size_t size) { 1257 1258 HANDLE fh = INVALID_HANDLE_VALUE; 1259 HANDLE fmh = NULL; 1260 1261 1262 // create the security attributes for the backing store file 1263 LPSECURITY_ATTRIBUTES lpFileSA = make_file_security_attr(); 1264 if (lpFileSA == NULL) { 1265 return NULL; 1266 } 1267 1268 // create the security attributes for the shared memory object 1269 LPSECURITY_ATTRIBUTES lpSmoSA = make_smo_security_attr(); 1270 if (lpSmoSA == NULL) { 1271 free_security_attr(lpFileSA); 1272 return NULL; 1273 } 1274 1275 // create the user temporary directory 1276 if (!make_user_tmp_dir(dirname)) { 1277 // could not make/find the directory or the found directory 1278 // was not secure 1279 return NULL; 1280 } 1281 1282 // Create the file - the FILE_FLAG_DELETE_ON_CLOSE flag allows the 1283 // file to be deleted by the last process that closes its handle to 1284 // the file. This is important as the apis do not allow a terminating 1285 // JVM being monitored by another process to remove the file name. 1286 // 1287 // the FILE_SHARE_DELETE share mode is valid only in winnt 1288 // 1289 fh = CreateFile( 1290 filename, /* LPCTSTR file name */ 1291 1292 GENERIC_READ|GENERIC_WRITE, /* DWORD desired access */ 1293 1294 (os::win32::is_nt() ? FILE_SHARE_DELETE : 0)| 1295 FILE_SHARE_READ, /* DWORD share mode, future READONLY 1296 * open operations allowed 1297 */ 1298 lpFileSA, /* LPSECURITY security attributes */ 1299 CREATE_ALWAYS, /* DWORD creation disposition 1300 * create file, if it already 1301 * exists, overwrite it. 1302 */ 1303 FILE_FLAG_DELETE_ON_CLOSE, /* DWORD flags and attributes */ 1304 1305 NULL); /* HANDLE template file access */ 1306 1307 free_security_attr(lpFileSA); 1308 1309 if (fh == INVALID_HANDLE_VALUE) { 1310 DWORD lasterror = GetLastError(); 1311 if (PrintMiscellaneous && Verbose) { 1312 warning("could not create file %s: %d\n", filename, lasterror); 1313 } 1314 return NULL; 1315 } 1316 1317 // try to create the file mapping 1318 fmh = create_file_mapping(objectname, fh, lpSmoSA, size); 1319 1320 free_security_attr(lpSmoSA); 1321 1322 if (fmh == NULL) { 1323 // closing the file handle here will decrement the reference count 1324 // on the file. When all processes accessing the file close their 1325 // handle to it, the reference count will decrement to 0 and the 1326 // OS will delete the file. These semantics are requested by the 1327 // FILE_FLAG_DELETE_ON_CLOSE flag in CreateFile call above. 1328 CloseHandle(fh); 1329 fh = NULL; 1330 return NULL; 1331 } 1332 1333 // the file has been successfully created and the file mapping 1334 // object has been created. 1335 sharedmem_fileHandle = fh; 1336 sharedmem_fileName = strdup(filename); 1337 1338 return fmh; 1339 } 1340 1341 // open the shared memory object for the given vmid. 1342 // 1343 static HANDLE open_sharedmem_object(const char* objectname, DWORD ofm_access, TRAPS) { 1344 1345 HANDLE fmh; 1346 1347 // open the file mapping with the requested mode 1348 fmh = OpenFileMapping( 1349 ofm_access, /* DWORD access mode */ 1350 FALSE, /* BOOL inherit flag - Do not allow inherit */ 1351 objectname); /* name for object */ 1352 1353 if (fmh == NULL) { 1354 if (PrintMiscellaneous && Verbose) { 1355 warning("OpenFileMapping failed for shared memory object %s:" 1356 " lasterror = %d\n", objectname, GetLastError()); 1357 } 1358 THROW_MSG_(vmSymbols::java_lang_Exception(), 1359 "Could not open PerfMemory", INVALID_HANDLE_VALUE); 1360 } 1361 1362 return fmh;; 1363 } 1364 1365 // create a named shared memory region 1366 // 1367 // On Win32, a named shared memory object has a name space that 1368 // is independent of the file system name space. Shared memory object, 1369 // or more precisely, file mapping objects, provide no mechanism to 1370 // inquire the size of the memory region. There is also no api to 1371 // enumerate the memory regions for various processes. 1372 // 1373 // This implementation utilizes the shared memory name space in parallel 1374 // with the file system name space. This allows us to determine the 1375 // size of the shared memory region from the size of the file and it 1376 // allows us to provide a common, file system based name space for 1377 // shared memory across platforms. 1378 // 1379 static char* mapping_create_shared(size_t size) { 1380 1381 void *mapAddress; 1382 int vmid = os::current_process_id(); 1383 1384 // get the name of the user associated with this process 1385 char* user = get_user_name(); 1386 1387 if (user == NULL) { 1388 return NULL; 1389 } 1390 1391 // construct the name of the user specific temporary directory 1392 char* dirname = get_user_tmp_dir(user); 1393 1394 // check that the file system is secure - i.e. it supports ACLs. 1395 if (!is_filesystem_secure(dirname)) { 1396 return NULL; 1397 } 1398 1399 // create the names of the backing store files and for the 1400 // share memory object. 1401 // 1402 char* filename = get_sharedmem_filename(dirname, vmid); 1403 char* objectname = get_sharedmem_objectname(user, vmid); 1404 1405 // cleanup any stale shared memory resources 1406 cleanup_sharedmem_resources(dirname); 1407 1408 assert(((size != 0) && (size % os::vm_page_size() == 0)), 1409 "unexpected PerfMemry region size"); 1410 1411 FREE_C_HEAP_ARRAY(char, user); 1412 1413 // create the shared memory resources 1414 sharedmem_fileMapHandle = 1415 create_sharedmem_resources(dirname, filename, objectname, size); 1416 1417 FREE_C_HEAP_ARRAY(char, filename); 1418 FREE_C_HEAP_ARRAY(char, objectname); 1419 FREE_C_HEAP_ARRAY(char, dirname); 1420 1421 if (sharedmem_fileMapHandle == NULL) { 1422 return NULL; 1423 } 1424 1425 // map the file into the address space 1426 mapAddress = MapViewOfFile( 1427 sharedmem_fileMapHandle, /* HANDLE = file mapping object */ 1428 FILE_MAP_ALL_ACCESS, /* DWORD access flags */ 1429 0, /* DWORD High word of offset */ 1430 0, /* DWORD Low word of offset */ 1431 (DWORD)size); /* DWORD Number of bytes to map */ 1432 1433 if (mapAddress == NULL) { 1434 if (PrintMiscellaneous && Verbose) { 1435 warning("MapViewOfFile failed, lasterror = %d\n", GetLastError()); 1436 } 1437 CloseHandle(sharedmem_fileMapHandle); 1438 sharedmem_fileMapHandle = NULL; 1439 return NULL; 1440 } 1441 1442 // clear the shared memory region 1443 (void)memset(mapAddress, '\0', size); 1444 1445 return (char*) mapAddress; 1446 } 1447 1448 // this method deletes the file mapping object. 1449 // 1450 static void delete_file_mapping(char* addr, size_t size) { 1451 1452 // cleanup the persistent shared memory resources. since DestroyJavaVM does 1453 // not support unloading of the JVM, unmapping of the memory resource is not 1454 // performed. The memory will be reclaimed by the OS upon termination of all 1455 // processes mapping the resource. The file mapping handle and the file 1456 // handle are closed here to expedite the remove of the file by the OS. The 1457 // file is not removed directly because it was created with 1458 // FILE_FLAG_DELETE_ON_CLOSE semantics and any attempt to remove it would 1459 // be unsuccessful. 1460 1461 // close the fileMapHandle. the file mapping will still be retained 1462 // by the OS as long as any other JVM processes has an open file mapping 1463 // handle or a mapped view of the file. 1464 // 1465 if (sharedmem_fileMapHandle != NULL) { 1466 CloseHandle(sharedmem_fileMapHandle); 1467 sharedmem_fileMapHandle = NULL; 1468 } 1469 1470 // close the file handle. This will decrement the reference count on the 1471 // backing store file. When the reference count decrements to 0, the OS 1472 // will delete the file. These semantics apply because the file was 1473 // created with the FILE_FLAG_DELETE_ON_CLOSE flag. 1474 // 1475 if (sharedmem_fileHandle != INVALID_HANDLE_VALUE) { 1476 CloseHandle(sharedmem_fileHandle); 1477 sharedmem_fileHandle = INVALID_HANDLE_VALUE; 1478 } 1479 } 1480 1481 // this method determines the size of the shared memory file 1482 // 1483 static size_t sharedmem_filesize(const char* filename, TRAPS) { 1484 1485 struct stat statbuf; 1486 1487 // get the file size 1488 // 1489 // on win95/98/me, _stat returns a file size of 0 bytes, but on 1490 // winnt/2k the appropriate file size is returned. support for 1491 // the sharable aspects of performance counters was abandonded 1492 // on the non-nt win32 platforms due to this and other api 1493 // inconsistencies 1494 // 1495 if (::stat(filename, &statbuf) == OS_ERR) { 1496 if (PrintMiscellaneous && Verbose) { 1497 warning("stat %s failed: %s\n", filename, strerror(errno)); 1498 } 1499 THROW_MSG_0(vmSymbols::java_io_IOException(), 1500 "Could not determine PerfMemory size"); 1501 } 1502 1503 if ((statbuf.st_size == 0) || (statbuf.st_size % os::vm_page_size() != 0)) { 1504 if (PrintMiscellaneous && Verbose) { 1505 warning("unexpected file size: size = " SIZE_FORMAT "\n", 1506 statbuf.st_size); 1507 } 1508 THROW_MSG_0(vmSymbols::java_lang_Exception(), 1509 "Invalid PerfMemory size"); 1510 } 1511 1512 return statbuf.st_size; 1513 } 1514 1515 // this method opens a file mapping object and maps the object 1516 // into the address space of the process 1517 // 1518 static void open_file_mapping(const char* user, int vmid, 1519 PerfMemory::PerfMemoryMode mode, 1520 char** addrp, size_t* sizep, TRAPS) { 1521 1522 ResourceMark rm; 1523 1524 void *mapAddress = 0; 1525 size_t size; 1526 HANDLE fmh; 1527 DWORD ofm_access; 1528 DWORD mv_access; 1529 const char* luser = NULL; 1530 1531 if (mode == PerfMemory::PERF_MODE_RO) { 1532 ofm_access = FILE_MAP_READ; 1533 mv_access = FILE_MAP_READ; 1534 } 1535 else if (mode == PerfMemory::PERF_MODE_RW) { 1536 #ifdef LATER 1537 ofm_access = FILE_MAP_READ | FILE_MAP_WRITE; 1538 mv_access = FILE_MAP_READ | FILE_MAP_WRITE; 1539 #else 1540 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1541 "Unsupported access mode"); 1542 #endif 1543 } 1544 else { 1545 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1546 "Illegal access mode"); 1547 } 1548 1549 // if a user name wasn't specified, then find the user name for 1550 // the owner of the target vm. 1551 if (user == NULL || strlen(user) == 0) { 1552 luser = get_user_name(vmid); 1553 } 1554 else { 1555 luser = user; 1556 } 1557 1558 if (luser == NULL) { 1559 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1560 "Could not map vmid to user name"); 1561 } 1562 1563 // get the names for the resources for the target vm 1564 char* dirname = get_user_tmp_dir(luser); 1565 1566 // since we don't follow symbolic links when creating the backing 1567 // store file, we also don't following them when attaching 1568 // 1569 if (!is_directory_secure(dirname)) { 1570 FREE_C_HEAP_ARRAY(char, dirname); 1571 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1572 "Process not found"); 1573 } 1574 1575 char* filename = get_sharedmem_filename(dirname, vmid); 1576 char* objectname = get_sharedmem_objectname(luser, vmid); 1577 1578 // copy heap memory to resource memory. the objectname and 1579 // filename are passed to methods that may throw exceptions. 1580 // using resource arrays for these names prevents the leaks 1581 // that would otherwise occur. 1582 // 1583 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); 1584 char* robjectname = NEW_RESOURCE_ARRAY(char, strlen(objectname) + 1); 1585 strcpy(rfilename, filename); 1586 strcpy(robjectname, objectname); 1587 1588 // free the c heap resources that are no longer needed 1589 if (luser != user) FREE_C_HEAP_ARRAY(char, luser); 1590 FREE_C_HEAP_ARRAY(char, dirname); 1591 FREE_C_HEAP_ARRAY(char, filename); 1592 FREE_C_HEAP_ARRAY(char, objectname); 1593 1594 if (*sizep == 0) { 1595 size = sharedmem_filesize(rfilename, CHECK); 1596 assert(size != 0, "unexpected size"); 1597 } 1598 1599 // Open the file mapping object with the given name 1600 fmh = open_sharedmem_object(robjectname, ofm_access, CHECK); 1601 1602 assert(fmh != INVALID_HANDLE_VALUE, "unexpected handle value"); 1603 1604 // map the entire file into the address space 1605 mapAddress = MapViewOfFile( 1606 fmh, /* HANDLE Handle of file mapping object */ 1607 mv_access, /* DWORD access flags */ 1608 0, /* DWORD High word of offset */ 1609 0, /* DWORD Low word of offset */ 1610 size); /* DWORD Number of bytes to map */ 1611 1612 if (mapAddress == NULL) { 1613 if (PrintMiscellaneous && Verbose) { 1614 warning("MapViewOfFile failed, lasterror = %d\n", GetLastError()); 1615 } 1616 CloseHandle(fmh); 1617 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), 1618 "Could not map PerfMemory"); 1619 } 1620 1621 *addrp = (char*)mapAddress; 1622 *sizep = size; 1623 1624 // File mapping object can be closed at this time without 1625 // invalidating the mapped view of the file 1626 CloseHandle(fmh); 1627 1628 if (PerfTraceMemOps) { 1629 tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " 1630 INTPTR_FORMAT "\n", size, vmid, mapAddress); 1631 } 1632 } 1633 1634 // this method unmaps the the mapped view of the the 1635 // file mapping object. 1636 // 1637 static void remove_file_mapping(char* addr) { 1638 1639 // the file mapping object was closed in open_file_mapping() 1640 // after the file map view was created. We only need to 1641 // unmap the file view here. 1642 UnmapViewOfFile(addr); 1643 } 1644 1645 // create the PerfData memory region in shared memory. 1646 static char* create_shared_memory(size_t size) { 1647 1648 return mapping_create_shared(size); 1649 } 1650 1651 // release a named, shared memory region 1652 // 1653 void delete_shared_memory(char* addr, size_t size) { 1654 1655 delete_file_mapping(addr, size); 1656 } 1657 1658 1659 1660 1661 // create the PerfData memory region 1662 // 1663 // This method creates the memory region used to store performance 1664 // data for the JVM. The memory may be created in standard or 1665 // shared memory. 1666 // 1667 void PerfMemory::create_memory_region(size_t size) { 1668 1669 if (PerfDisableSharedMem || !os::win32::is_nt()) { 1670 // do not share the memory for the performance data. 1671 PerfDisableSharedMem = true; 1672 _start = create_standard_memory(size); 1673 } 1674 else { 1675 _start = create_shared_memory(size); 1676 if (_start == NULL) { 1677 1678 // creation of the shared memory region failed, attempt 1679 // to create a contiguous, non-shared memory region instead. 1680 // 1681 if (PrintMiscellaneous && Verbose) { 1682 warning("Reverting to non-shared PerfMemory region.\n"); 1683 } 1684 PerfDisableSharedMem = true; 1685 _start = create_standard_memory(size); 1686 } 1687 } 1688 1689 if (_start != NULL) _capacity = size; 1690 1691 } 1692 1693 // delete the PerfData memory region 1694 // 1695 // This method deletes the memory region used to store performance 1696 // data for the JVM. The memory region indicated by the <address, size> 1697 // tuple will be inaccessible after a call to this method. 1698 // 1699 void PerfMemory::delete_memory_region() { 1700 1701 assert((start() != NULL && capacity() > 0), "verify proper state"); 1702 1703 // If user specifies PerfDataSaveFile, it will save the performance data 1704 // to the specified file name no matter whether PerfDataSaveToFile is specified 1705 // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag 1706 // -XX:+PerfDataSaveToFile. 1707 if (PerfDataSaveToFile || PerfDataSaveFile != NULL) { 1708 save_memory_to_file(start(), capacity()); 1709 } 1710 1711 if (PerfDisableSharedMem) { 1712 delete_standard_memory(start(), capacity()); 1713 } 1714 else { 1715 delete_shared_memory(start(), capacity()); 1716 } 1717 } 1718 1719 // attach to the PerfData memory region for another JVM 1720 // 1721 // This method returns an <address, size> tuple that points to 1722 // a memory buffer that is kept reasonably synchronized with 1723 // the PerfData memory region for the indicated JVM. This 1724 // buffer may be kept in synchronization via shared memory 1725 // or some other mechanism that keeps the buffer updated. 1726 // 1727 // If the JVM chooses not to support the attachability feature, 1728 // this method should throw an UnsupportedOperation exception. 1729 // 1730 // This implementation utilizes named shared memory to map 1731 // the indicated process's PerfData memory region into this JVMs 1732 // address space. 1733 // 1734 void PerfMemory::attach(const char* user, int vmid, PerfMemoryMode mode, 1735 char** addrp, size_t* sizep, TRAPS) { 1736 1737 if (vmid == 0 || vmid == os::current_process_id()) { 1738 *addrp = start(); 1739 *sizep = capacity(); 1740 return; 1741 } 1742 1743 open_file_mapping(user, vmid, mode, addrp, sizep, CHECK); 1744 } 1745 1746 // detach from the PerfData memory region of another JVM 1747 // 1748 // This method detaches the PerfData memory region of another 1749 // JVM, specified as an <address, size> tuple of a buffer 1750 // in this process's address space. This method may perform 1751 // arbitrary actions to accomplish the detachment. The memory 1752 // region specified by <address, size> will be inaccessible after 1753 // a call to this method. 1754 // 1755 // If the JVM chooses not to support the attachability feature, 1756 // this method should throw an UnsupportedOperation exception. 1757 // 1758 // This implementation utilizes named shared memory to detach 1759 // the indicated process's PerfData memory region from this 1760 // process's address space. 1761 // 1762 void PerfMemory::detach(char* addr, size_t bytes, TRAPS) { 1763 1764 assert(addr != 0, "address sanity check"); 1765 assert(bytes > 0, "capacity sanity check"); 1766 1767 if (PerfMemory::contains(addr) || PerfMemory::contains(addr + bytes - 1)) { 1768 // prevent accidental detachment of this process's PerfMemory region 1769 return; 1770 } 1771 1772 remove_file_mapping(addr); 1773 } 1774 1775 char* PerfMemory::backing_store_filename() { 1776 return sharedmem_fileName; 1777 }