src/os/windows/vm/perfMemory_windows.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 80060074 Sdiff src/os/windows/vm

src/os/windows/vm/perfMemory_windows.cpp

Print this page




 105       if (nbytes == OS_ERR) {
 106         if (PrintMiscellaneous && Verbose) {
 107           warning("Could not write Perfdata save file: %s: %s\n",
 108                   destfile, strerror(errno));
 109         }
 110         break;
 111       }
 112 
 113       remaining -= (size_t)nbytes;
 114       addr += nbytes;
 115     }
 116 
 117     int result = ::_close(fd);
 118     if (PrintMiscellaneous && Verbose) {
 119       if (result == OS_ERR) {
 120         warning("Could not close %s: %s\n", destfile, strerror(errno));
 121       }
 122     }
 123   }
 124 
 125   FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
 126 }
 127 
 128 // Shared Memory Implementation Details
 129 
 130 // Note: the win32 shared memory implementation uses two objects to represent
 131 // the shared memory: a windows kernel based file mapping object and a backing
 132 // store file. On windows, the name space for shared memory is a kernel
 133 // based name space that is disjoint from other win32 name spaces. Since Java
 134 // is unaware of this name space, a parallel file system based name space is
 135 // maintained, which provides a common file system based shared memory name
 136 // space across the supported platforms and one that Java apps can deal with
 137 // through simple file apis.
 138 //
 139 // For performance and resource cleanup reasons, it is recommended that the
 140 // user specific directory and the backing store file be stored in either a
 141 // RAM based file system or a local disk based file system. Network based
 142 // file systems are not recommended for performance reasons. In addition,
 143 // use of SMB network based file systems may result in unsuccesful cleanup
 144 // of the disk based resource on exit of the VM. The Windows TMP and TEMP
 145 // environement variables, as used by the GetTempPath() Win32 API (see


 318   //
 319   struct dirent* dentry;
 320   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 321   errno = 0;
 322   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 323 
 324     // check if the directory entry is a hsperfdata file
 325     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 326       continue;
 327     }
 328 
 329     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 330         strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 331     strcpy(usrdir_name, tmpdirname);
 332     strcat(usrdir_name, "\\");
 333     strcat(usrdir_name, dentry->d_name);
 334 
 335     DIR* subdirp = os::opendir(usrdir_name);
 336 
 337     if (subdirp == NULL) {
 338       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 339       continue;
 340     }
 341 
 342     // Since we don't create the backing store files in directories
 343     // pointed to by symbolic links, we also don't follow them when
 344     // looking for the files. We check for a symbolic link after the
 345     // call to opendir in order to eliminate a small window where the
 346     // symlink can be exploited.
 347     //
 348     if (!is_directory_secure(usrdir_name)) {
 349       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 350       os::closedir(subdirp);
 351       continue;
 352     }
 353 
 354     struct dirent* udentry;
 355     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 356     errno = 0;
 357     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 358 
 359       if (filename_to_pid(udentry->d_name) == vmid) {
 360         struct stat statbuf;
 361 
 362         char* filename = NEW_C_HEAP_ARRAY(char,
 363            strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 364 
 365         strcpy(filename, usrdir_name);
 366         strcat(filename, "\\");
 367         strcat(filename, udentry->d_name);
 368 
 369         if (::stat(filename, &statbuf) == OS_ERR) {
 370            FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 371            continue;
 372         }
 373 
 374         // skip over files that are not regular files.
 375         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
 376           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 377           continue;
 378         }
 379 
 380         // If we found a matching file with a newer creation time, then
 381         // save the user name. The newer creation time indicates that
 382         // we found a newer incarnation of the process associated with
 383         // vmid. Due to the way that Windows recycles pids and the fact
 384         // that we can't delete the file from the file system namespace
 385         // until last close, it is possible for there to be more than
 386         // one hsperfdata file with a name matching vmid (diff users).
 387         //
 388         // We no longer ignore hsperfdata files where (st_size == 0).
 389         // In this function, all we're trying to do is determine the
 390         // name of the user that owns the process associated with vmid
 391         // so the size doesn't matter. Very rarely, we have observed
 392         // hsperfdata files where (st_size == 0) and the st_size field
 393         // later becomes the expected value.
 394         //
 395         if (statbuf.st_ctime > latest_ctime) {
 396           char* user = strchr(dentry->d_name, '_') + 1;
 397 
 398           if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user, mtInternal);
 399           latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 400 
 401           strcpy(latest_user, user);
 402           latest_ctime = statbuf.st_ctime;
 403         }
 404 
 405         FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 406       }
 407     }
 408     os::closedir(subdirp);
 409     FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
 410     FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 411   }
 412   os::closedir(tmpdirp);
 413   FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 414 
 415   return(latest_user);
 416 }
 417 
 418 // return the name of the user that owns the process identified by vmid.
 419 //
 420 // note: this method should only be used via the Perf native methods.
 421 // There are various costs to this method and limiting its use to the
 422 // Perf native methods limits the impact to monitoring applications only.
 423 //
 424 static char* get_user_name(int vmid) {
 425 
 426   // A fast implementation is not provided at this time. It's possible
 427   // to provide a fast process id to user name mapping function using
 428   // the win32 apis, but the default ACL for the process object only
 429   // allows processes with the same owner SID to acquire the process
 430   // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
 431   // to have the JVM change the ACL for the process object to allow arbitrary
 432   // users to access the process handle and the process security token.
 433   // The security ramifications need to be studied before providing this


 485 // method may be unsuccessful in removing the file.
 486 //
 487 static void remove_file(const char* dirname, const char* filename) {
 488 
 489   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
 490   char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 491 
 492   strcpy(path, dirname);
 493   strcat(path, "\\");
 494   strcat(path, filename);
 495 
 496   if (::unlink(path) == OS_ERR) {
 497     if (PrintMiscellaneous && Verbose) {
 498       if (errno != ENOENT) {
 499         warning("Could not unlink shared memory backing"
 500                 " store file %s : %s\n", path, strerror(errno));
 501       }
 502     }
 503   }
 504 
 505   FREE_C_HEAP_ARRAY(char, path, mtInternal);
 506 }
 507 
 508 // returns true if the process represented by pid is alive, otherwise
 509 // returns false. the validity of the result is only accurate if the
 510 // target process is owned by the same principal that owns this process.
 511 // this method should not be used if to test the status of an otherwise
 512 // arbitrary process unless it is know that this process has the appropriate
 513 // privileges to guarantee a result valid.
 514 //
 515 static bool is_alive(int pid) {
 516 
 517   HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
 518   if (ph == NULL) {
 519     // the process does not exist.
 520     if (PrintMiscellaneous && Verbose) {
 521       DWORD lastError = GetLastError();
 522       if (lastError != ERROR_INVALID_PARAMETER) {
 523         warning("OpenProcess failed: %d\n", GetLastError());
 524       }
 525     }


 666     // process liveness is detected by checking the exit status
 667     // of the process. if the process id is valid and the exit status
 668     // indicates that it is still running, the file file resources
 669     // are not removed. If the process id is invalid, or if we don't
 670     // have permissions to check the process status, or if the process
 671     // id is valid and the process has terminated, the the file resources
 672     // are assumed to be stale and are removed.
 673     //
 674     if (pid == os::current_process_id() || !is_alive(pid)) {
 675 
 676       // we can only remove the file resources. Any mapped views
 677       // of the file can only be unmapped by the processes that
 678       // opened those views and the file mapping object will not
 679       // get removed until all views are unmapped.
 680       //
 681       remove_file(dirname, entry->d_name);
 682     }
 683     errno = 0;
 684   }
 685   os::closedir(dirp);
 686   FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 687 }
 688 
 689 // create a file mapping object with the requested name, and size
 690 // from the file represented by the given Handle object
 691 //
 692 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
 693 
 694   DWORD lowSize = (DWORD)size;
 695   DWORD highSize = 0;
 696   HANDLE fmh = NULL;
 697 
 698   // Create a file mapping object with the given name. This function
 699   // will grow the file to the specified size.
 700   //
 701   fmh = CreateFileMapping(
 702                fh,                 /* HANDLE file handle for backing store */
 703                fsa,                /* LPSECURITY_ATTRIBUTES Not inheritable */
 704                PAGE_READWRITE,     /* DWORD protections */
 705                highSize,           /* DWORD High word of max size */
 706                lowSize,            /* DWORD Low word of max size */


 732 }
 733 
 734 
 735 // method to free the given security descriptor and the contained
 736 // access control list.
 737 //
 738 static void free_security_desc(PSECURITY_DESCRIPTOR pSD) {
 739 
 740   BOOL success, exists, isdefault;
 741   PACL pACL;
 742 
 743   if (pSD != NULL) {
 744 
 745     // get the access control list from the security descriptor
 746     success = GetSecurityDescriptorDacl(pSD, &exists, &pACL, &isdefault);
 747 
 748     // if an ACL existed and it was not a default acl, then it must
 749     // be an ACL we enlisted. free the resources.
 750     //
 751     if (success && exists && pACL != NULL && !isdefault) {
 752       FREE_C_HEAP_ARRAY(char, pACL, mtInternal);
 753     }
 754 
 755     // free the security descriptor
 756     FREE_C_HEAP_ARRAY(char, pSD, mtInternal);
 757   }
 758 }
 759 
 760 // method to free up a security attributes structure and any
 761 // contained security descriptors and ACL
 762 //
 763 static void free_security_attr(LPSECURITY_ATTRIBUTES lpSA) {
 764 
 765   if (lpSA != NULL) {
 766     // free the contained security descriptor and the ACL
 767     free_security_desc(lpSA->lpSecurityDescriptor);
 768     lpSA->lpSecurityDescriptor = NULL;
 769 
 770     // free the security attributes structure
 771     FREE_C_HEAP_ARRAY(char, lpSA, mtInternal);
 772   }
 773 }
 774 
 775 // get the user SID for the process indicated by the process handle
 776 //
 777 static PSID get_user_sid(HANDLE hProcess) {
 778 
 779   HANDLE hAccessToken;
 780   PTOKEN_USER token_buf = NULL;
 781   DWORD rsize = 0;
 782 
 783   if (hProcess == NULL) {
 784     return NULL;
 785   }
 786 
 787   // get the process token
 788   if (!OpenProcessToken(hProcess, TOKEN_READ, &hAccessToken)) {
 789     if (PrintMiscellaneous && Verbose) {
 790       warning("OpenProcessToken failure: lasterror = %d \n", GetLastError());
 791     }


 798   if (!GetTokenInformation(hAccessToken, TokenUser, NULL, rsize, &rsize)) {
 799     DWORD lasterror = GetLastError();
 800     if (lasterror != ERROR_INSUFFICIENT_BUFFER) {
 801       if (PrintMiscellaneous && Verbose) {
 802         warning("GetTokenInformation failure: lasterror = %d,"
 803                 " rsize = %d\n", lasterror, rsize);
 804       }
 805       CloseHandle(hAccessToken);
 806       return NULL;
 807     }
 808   }
 809 
 810   token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize, mtInternal);
 811 
 812   // get the user token information
 813   if (!GetTokenInformation(hAccessToken, TokenUser, token_buf, rsize, &rsize)) {
 814     if (PrintMiscellaneous && Verbose) {
 815       warning("GetTokenInformation failure: lasterror = %d,"
 816               " rsize = %d\n", GetLastError(), rsize);
 817     }
 818     FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
 819     CloseHandle(hAccessToken);
 820     return NULL;
 821   }
 822 
 823   DWORD nbytes = GetLengthSid(token_buf->User.Sid);
 824   PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 825 
 826   if (!CopySid(nbytes, pSID, token_buf->User.Sid)) {
 827     if (PrintMiscellaneous && Verbose) {
 828       warning("GetTokenInformation failure: lasterror = %d,"
 829               " rsize = %d\n", GetLastError(), rsize);
 830     }
 831     FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
 832     FREE_C_HEAP_ARRAY(char, pSID, mtInternal);
 833     CloseHandle(hAccessToken);
 834     return NULL;
 835   }
 836 
 837   // close the access token.
 838   CloseHandle(hAccessToken);
 839   FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
 840 
 841   return pSID;
 842 }
 843 
 844 // structure used to consolidate access control entry information
 845 //
 846 typedef struct ace_data {
 847   PSID pSid;      // SID of the ACE
 848   DWORD mask;     // mask for the ACE
 849 } ace_data_t;
 850 
 851 
 852 // method to add an allow access control entry with the access rights
 853 // indicated in mask for the principal indicated in SID to the given
 854 // security descriptor. Much of the DACL handling was adapted from
 855 // the example provided here:
 856 //      http://support.microsoft.com/kb/102102/EN-US/
 857 //
 858 
 859 static bool add_allow_aces(PSECURITY_DESCRIPTOR pSD,


 903   // compute the size needed for the new ACL
 904   // initial size of ACL is sum of the following:
 905   //   * size of ACL structure.
 906   //   * size of each ACE structure that ACL is to contain minus the sid
 907   //     sidStart member (DWORD) of the ACE.
 908   //   * length of the SID that each ACE is to contain.
 909   DWORD newACLsize = aclinfo.AclBytesInUse +
 910                         (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * ace_count;
 911   for (int i = 0; i < ace_count; i++) {
 912      assert(aces[i].pSid != 0, "pSid should not be 0");
 913      newACLsize += GetLengthSid(aces[i].pSid);
 914   }
 915 
 916   // create the new ACL
 917   newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize, mtInternal);
 918 
 919   if (!InitializeAcl(newACL, newACLsize, ACL_REVISION)) {
 920     if (PrintMiscellaneous && Verbose) {
 921       warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 922     }
 923     FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
 924     return false;
 925   }
 926 
 927   unsigned int ace_index = 0;
 928   // copy any existing ACEs from the old ACL (if any) to the new ACL.
 929   if (aclinfo.AceCount != 0) {
 930     while (ace_index < aclinfo.AceCount) {
 931       LPVOID ace;
 932       if (!GetAce(oldACL, ace_index, &ace)) {
 933         if (PrintMiscellaneous && Verbose) {
 934           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 935         }
 936         FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
 937         return false;
 938       }
 939       if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
 940         // this is an inherited, allowed ACE; break from loop so we can
 941         // add the new access allowed, non-inherited ACE in the correct
 942         // position, immediately following all non-inherited ACEs.
 943         break;
 944       }
 945 
 946       // determine if the SID of this ACE matches any of the SIDs
 947       // for which we plan to set ACEs.
 948       int matches = 0;
 949       for (int i = 0; i < ace_count; i++) {
 950         if (EqualSid(aces[i].pSid, &(((ACCESS_ALLOWED_ACE *)ace)->SidStart))) {
 951           matches++;
 952           break;
 953         }
 954       }
 955 
 956       // if there are no SID matches, then add this existing ACE to the new ACL
 957       if (matches == 0) {
 958         if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
 959                     ((PACE_HEADER)ace)->AceSize)) {
 960           if (PrintMiscellaneous && Verbose) {
 961             warning("AddAce failure: lasterror = %d \n", GetLastError());
 962           }
 963           FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
 964           return false;
 965         }
 966       }
 967       ace_index++;
 968     }
 969   }
 970 
 971   // add the passed-in access control entries to the new ACL
 972   for (int i = 0; i < ace_count; i++) {
 973     if (!AddAccessAllowedAce(newACL, ACL_REVISION,
 974                              aces[i].mask, aces[i].pSid)) {
 975       if (PrintMiscellaneous && Verbose) {
 976         warning("AddAccessAllowedAce failure: lasterror = %d \n",
 977                 GetLastError());
 978       }
 979       FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
 980       return false;
 981     }
 982   }
 983 
 984   // now copy the rest of the inherited ACEs from the old ACL
 985   if (aclinfo.AceCount != 0) {
 986     // picking up at ace_index, where we left off in the
 987     // previous ace_index loop
 988     while (ace_index < aclinfo.AceCount) {
 989       LPVOID ace;
 990       if (!GetAce(oldACL, ace_index, &ace)) {
 991         if (PrintMiscellaneous && Verbose) {
 992           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 993         }
 994         FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
 995         return false;
 996       }
 997       if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
 998                   ((PACE_HEADER)ace)->AceSize)) {
 999         if (PrintMiscellaneous && Verbose) {
1000           warning("AddAce failure: lasterror = %d \n", GetLastError());
1001         }
1002         FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
1003         return false;
1004       }
1005       ace_index++;
1006     }
1007   }
1008 
1009   // add the new ACL to the security descriptor.
1010   if (!SetSecurityDescriptorDacl(pSD, TRUE, newACL, FALSE)) {
1011     if (PrintMiscellaneous && Verbose) {
1012       warning("SetSecurityDescriptorDacl failure:"
1013               " lasterror = %d \n", GetLastError());
1014     }
1015     FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
1016     return false;
1017   }
1018 
1019   // if running on windows 2000 or later, set the automatic inheritance
1020   // control flags.
1021   SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl;
1022   _SetSecurityDescriptorControl = (SetSecurityDescriptorControlFnPtr)
1023        GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
1024                       "SetSecurityDescriptorControl");
1025 
1026   if (_SetSecurityDescriptorControl != NULL) {
1027     // We do not want to further propagate inherited DACLs, so making them
1028     // protected prevents that.
1029     if (!_SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED,
1030                                             SE_DACL_PROTECTED)) {
1031       if (PrintMiscellaneous && Verbose) {
1032         warning("SetSecurityDescriptorControl failure:"
1033                 " lasterror = %d \n", GetLastError());
1034       }
1035       FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
1036       return false;
1037     }
1038   }
1039    // Note, the security descriptor maintains a reference to the newACL, not
1040    // a copy of it. Therefore, the newACL is not freed here. It is freed when
1041    // the security descriptor containing its reference is freed.
1042    //
1043    return true;
1044 }
1045 
1046 // method to create a security attributes structure, which contains a
1047 // security descriptor and an access control list comprised of 0 or more
1048 // access control entries. The method take an array of ace_data structures
1049 // that indicate the ACE to be added to the security descriptor.
1050 //
1051 // the caller must free the resources associated with the security
1052 // attributes structure created by this method by calling the
1053 // free_security_attr() method.
1054 //
1055 static LPSECURITY_ATTRIBUTES make_security_attr(ace_data_t aces[], int count) {


1132   PSID everybodySid = NULL;
1133   SID_IDENTIFIER_AUTHORITY SIDAuthEverybody = SECURITY_WORLD_SID_AUTHORITY;
1134 
1135   if (!AllocateAndInitializeSid( &SIDAuthEverybody, 1, SECURITY_WORLD_RID,
1136            0, 0, 0, 0, 0, 0, 0, &everybodySid)) {
1137 
1138     if (PrintMiscellaneous && Verbose) {
1139       warning("AllocateAndInitializeSid failure: "
1140               "lasterror = %d \n", GetLastError());
1141     }
1142     return NULL;
1143   }
1144 
1145   // initialize the ace data for everybody else.
1146   aces[2].pSid = everybodySid;
1147   aces[2].mask = emask;
1148 
1149   // create a security attributes structure with access control
1150   // entries as initialized above.
1151   LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
1152   FREE_C_HEAP_ARRAY(char, aces[0].pSid, mtInternal);
1153   FreeSid(everybodySid);
1154   FreeSid(administratorsSid);
1155   return(lpSA);
1156 }
1157 
1158 
1159 // method to create the security attributes structure for restricting
1160 // access to the user temporary directory.
1161 //
1162 // the caller must free the resources associated with the security
1163 // attributes structure created by this method by calling the
1164 // free_security_attr() method.
1165 //
1166 static LPSECURITY_ATTRIBUTES make_tmpdir_security_attr() {
1167 
1168   // create full access rights for the user/owner of the directory
1169   // and read-only access rights for everybody else. This is
1170   // effectively equivalent to UNIX 755 permissions on a directory.
1171   //
1172   DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_ALL_ACCESS;


1447   // construct the name of the user specific temporary directory
1448   char* dirname = get_user_tmp_dir(user);
1449 
1450   // check that the file system is secure - i.e. it supports ACLs.
1451   if (!is_filesystem_secure(dirname)) {
1452     return NULL;
1453   }
1454 
1455   // create the names of the backing store files and for the
1456   // share memory object.
1457   //
1458   char* filename = get_sharedmem_filename(dirname, vmid);
1459   char* objectname = get_sharedmem_objectname(user, vmid);
1460 
1461   // cleanup any stale shared memory resources
1462   cleanup_sharedmem_resources(dirname);
1463 
1464   assert(((size != 0) && (size % os::vm_page_size() == 0)),
1465          "unexpected PerfMemry region size");
1466 
1467   FREE_C_HEAP_ARRAY(char, user, mtInternal);
1468 
1469   // create the shared memory resources
1470   sharedmem_fileMapHandle =
1471                create_sharedmem_resources(dirname, filename, objectname, size);
1472 
1473   FREE_C_HEAP_ARRAY(char, filename, mtInternal);
1474   FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
1475   FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
1476 
1477   if (sharedmem_fileMapHandle == NULL) {
1478     return NULL;
1479   }
1480 
1481   // map the file into the address space
1482   mapAddress = MapViewOfFile(
1483                    sharedmem_fileMapHandle, /* HANDLE = file mapping object */
1484                    FILE_MAP_ALL_ACCESS,     /* DWORD access flags */
1485                    0,                       /* DWORD High word of offset */
1486                    0,                       /* DWORD Low word of offset */
1487                    (DWORD)size);            /* DWORD Number of bytes to map */
1488 
1489   if (mapAddress == NULL) {
1490     if (PrintMiscellaneous && Verbose) {
1491       warning("MapViewOfFile failed, lasterror = %d\n", GetLastError());
1492     }
1493     CloseHandle(sharedmem_fileMapHandle);
1494     sharedmem_fileMapHandle = NULL;
1495     return NULL;


1610   // the owner of the target vm.
1611   if (user == NULL || strlen(user) == 0) {
1612     luser = get_user_name(vmid);
1613   }
1614   else {
1615     luser = user;
1616   }
1617 
1618   if (luser == NULL) {
1619     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1620               "Could not map vmid to user name");
1621   }
1622 
1623   // get the names for the resources for the target vm
1624   char* dirname = get_user_tmp_dir(luser);
1625 
1626   // since we don't follow symbolic links when creating the backing
1627   // store file, we also don't following them when attaching
1628   //
1629   if (!is_directory_secure(dirname)) {
1630     FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
1631     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1632               "Process not found");
1633   }
1634 
1635   char* filename = get_sharedmem_filename(dirname, vmid);
1636   char* objectname = get_sharedmem_objectname(luser, vmid);
1637 
1638   // copy heap memory to resource memory. the objectname and
1639   // filename are passed to methods that may throw exceptions.
1640   // using resource arrays for these names prevents the leaks
1641   // that would otherwise occur.
1642   //
1643   char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
1644   char* robjectname = NEW_RESOURCE_ARRAY(char, strlen(objectname) + 1);
1645   strcpy(rfilename, filename);
1646   strcpy(robjectname, objectname);
1647 
1648   // free the c heap resources that are no longer needed
1649   if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
1650   FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
1651   FREE_C_HEAP_ARRAY(char, filename, mtInternal);
1652   FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
1653 
1654   if (*sizep == 0) {
1655     size = sharedmem_filesize(rfilename, CHECK);
1656   } else {
1657     size = *sizep;
1658   }
1659 
1660   assert(size > 0, "unexpected size <= 0");
1661 
1662   // Open the file mapping object with the given name
1663   fmh = open_sharedmem_object(robjectname, ofm_access, CHECK);
1664 
1665   assert(fmh != INVALID_HANDLE_VALUE, "unexpected handle value");
1666 
1667   // map the entire file into the address space
1668   mapAddress = MapViewOfFile(
1669                  fmh,             /* HANDLE Handle of file mapping object */
1670                  mv_access,       /* DWORD access flags */
1671                  0,               /* DWORD High word of offset */
1672                  0,               /* DWORD Low word of offset */




 105       if (nbytes == OS_ERR) {
 106         if (PrintMiscellaneous && Verbose) {
 107           warning("Could not write Perfdata save file: %s: %s\n",
 108                   destfile, strerror(errno));
 109         }
 110         break;
 111       }
 112 
 113       remaining -= (size_t)nbytes;
 114       addr += nbytes;
 115     }
 116 
 117     int result = ::_close(fd);
 118     if (PrintMiscellaneous && Verbose) {
 119       if (result == OS_ERR) {
 120         warning("Could not close %s: %s\n", destfile, strerror(errno));
 121       }
 122     }
 123   }
 124 
 125   FREE_C_HEAP_ARRAY(char, destfile);
 126 }
 127 
 128 // Shared Memory Implementation Details
 129 
 130 // Note: the win32 shared memory implementation uses two objects to represent
 131 // the shared memory: a windows kernel based file mapping object and a backing
 132 // store file. On windows, the name space for shared memory is a kernel
 133 // based name space that is disjoint from other win32 name spaces. Since Java
 134 // is unaware of this name space, a parallel file system based name space is
 135 // maintained, which provides a common file system based shared memory name
 136 // space across the supported platforms and one that Java apps can deal with
 137 // through simple file apis.
 138 //
 139 // For performance and resource cleanup reasons, it is recommended that the
 140 // user specific directory and the backing store file be stored in either a
 141 // RAM based file system or a local disk based file system. Network based
 142 // file systems are not recommended for performance reasons. In addition,
 143 // use of SMB network based file systems may result in unsuccesful cleanup
 144 // of the disk based resource on exit of the VM. The Windows TMP and TEMP
 145 // environement variables, as used by the GetTempPath() Win32 API (see


 318   //
 319   struct dirent* dentry;
 320   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 321   errno = 0;
 322   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 323 
 324     // check if the directory entry is a hsperfdata file
 325     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 326       continue;
 327     }
 328 
 329     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 330         strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 331     strcpy(usrdir_name, tmpdirname);
 332     strcat(usrdir_name, "\\");
 333     strcat(usrdir_name, dentry->d_name);
 334 
 335     DIR* subdirp = os::opendir(usrdir_name);
 336 
 337     if (subdirp == NULL) {
 338       FREE_C_HEAP_ARRAY(char, usrdir_name);
 339       continue;
 340     }
 341 
 342     // Since we don't create the backing store files in directories
 343     // pointed to by symbolic links, we also don't follow them when
 344     // looking for the files. We check for a symbolic link after the
 345     // call to opendir in order to eliminate a small window where the
 346     // symlink can be exploited.
 347     //
 348     if (!is_directory_secure(usrdir_name)) {
 349       FREE_C_HEAP_ARRAY(char, usrdir_name);
 350       os::closedir(subdirp);
 351       continue;
 352     }
 353 
 354     struct dirent* udentry;
 355     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 356     errno = 0;
 357     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 358 
 359       if (filename_to_pid(udentry->d_name) == vmid) {
 360         struct stat statbuf;
 361 
 362         char* filename = NEW_C_HEAP_ARRAY(char,
 363            strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 364 
 365         strcpy(filename, usrdir_name);
 366         strcat(filename, "\\");
 367         strcat(filename, udentry->d_name);
 368 
 369         if (::stat(filename, &statbuf) == OS_ERR) {
 370            FREE_C_HEAP_ARRAY(char, filename);
 371            continue;
 372         }
 373 
 374         // skip over files that are not regular files.
 375         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
 376           FREE_C_HEAP_ARRAY(char, filename);
 377           continue;
 378         }
 379 
 380         // If we found a matching file with a newer creation time, then
 381         // save the user name. The newer creation time indicates that
 382         // we found a newer incarnation of the process associated with
 383         // vmid. Due to the way that Windows recycles pids and the fact
 384         // that we can't delete the file from the file system namespace
 385         // until last close, it is possible for there to be more than
 386         // one hsperfdata file with a name matching vmid (diff users).
 387         //
 388         // We no longer ignore hsperfdata files where (st_size == 0).
 389         // In this function, all we're trying to do is determine the
 390         // name of the user that owns the process associated with vmid
 391         // so the size doesn't matter. Very rarely, we have observed
 392         // hsperfdata files where (st_size == 0) and the st_size field
 393         // later becomes the expected value.
 394         //
 395         if (statbuf.st_ctime > latest_ctime) {
 396           char* user = strchr(dentry->d_name, '_') + 1;
 397 
 398           if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
 399           latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 400 
 401           strcpy(latest_user, user);
 402           latest_ctime = statbuf.st_ctime;
 403         }
 404 
 405         FREE_C_HEAP_ARRAY(char, filename);
 406       }
 407     }
 408     os::closedir(subdirp);
 409     FREE_C_HEAP_ARRAY(char, udbuf);
 410     FREE_C_HEAP_ARRAY(char, usrdir_name);
 411   }
 412   os::closedir(tmpdirp);
 413   FREE_C_HEAP_ARRAY(char, tdbuf);
 414 
 415   return(latest_user);
 416 }
 417 
 418 // return the name of the user that owns the process identified by vmid.
 419 //
 420 // note: this method should only be used via the Perf native methods.
 421 // There are various costs to this method and limiting its use to the
 422 // Perf native methods limits the impact to monitoring applications only.
 423 //
 424 static char* get_user_name(int vmid) {
 425 
 426   // A fast implementation is not provided at this time. It's possible
 427   // to provide a fast process id to user name mapping function using
 428   // the win32 apis, but the default ACL for the process object only
 429   // allows processes with the same owner SID to acquire the process
 430   // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
 431   // to have the JVM change the ACL for the process object to allow arbitrary
 432   // users to access the process handle and the process security token.
 433   // The security ramifications need to be studied before providing this


 485 // method may be unsuccessful in removing the file.
 486 //
 487 static void remove_file(const char* dirname, const char* filename) {
 488 
 489   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
 490   char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 491 
 492   strcpy(path, dirname);
 493   strcat(path, "\\");
 494   strcat(path, filename);
 495 
 496   if (::unlink(path) == OS_ERR) {
 497     if (PrintMiscellaneous && Verbose) {
 498       if (errno != ENOENT) {
 499         warning("Could not unlink shared memory backing"
 500                 " store file %s : %s\n", path, strerror(errno));
 501       }
 502     }
 503   }
 504 
 505   FREE_C_HEAP_ARRAY(char, path);
 506 }
 507 
 508 // returns true if the process represented by pid is alive, otherwise
 509 // returns false. the validity of the result is only accurate if the
 510 // target process is owned by the same principal that owns this process.
 511 // this method should not be used if to test the status of an otherwise
 512 // arbitrary process unless it is know that this process has the appropriate
 513 // privileges to guarantee a result valid.
 514 //
 515 static bool is_alive(int pid) {
 516 
 517   HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
 518   if (ph == NULL) {
 519     // the process does not exist.
 520     if (PrintMiscellaneous && Verbose) {
 521       DWORD lastError = GetLastError();
 522       if (lastError != ERROR_INVALID_PARAMETER) {
 523         warning("OpenProcess failed: %d\n", GetLastError());
 524       }
 525     }


 666     // process liveness is detected by checking the exit status
 667     // of the process. if the process id is valid and the exit status
 668     // indicates that it is still running, the file file resources
 669     // are not removed. If the process id is invalid, or if we don't
 670     // have permissions to check the process status, or if the process
 671     // id is valid and the process has terminated, the the file resources
 672     // are assumed to be stale and are removed.
 673     //
 674     if (pid == os::current_process_id() || !is_alive(pid)) {
 675 
 676       // we can only remove the file resources. Any mapped views
 677       // of the file can only be unmapped by the processes that
 678       // opened those views and the file mapping object will not
 679       // get removed until all views are unmapped.
 680       //
 681       remove_file(dirname, entry->d_name);
 682     }
 683     errno = 0;
 684   }
 685   os::closedir(dirp);
 686   FREE_C_HEAP_ARRAY(char, dbuf);
 687 }
 688 
 689 // create a file mapping object with the requested name, and size
 690 // from the file represented by the given Handle object
 691 //
 692 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
 693 
 694   DWORD lowSize = (DWORD)size;
 695   DWORD highSize = 0;
 696   HANDLE fmh = NULL;
 697 
 698   // Create a file mapping object with the given name. This function
 699   // will grow the file to the specified size.
 700   //
 701   fmh = CreateFileMapping(
 702                fh,                 /* HANDLE file handle for backing store */
 703                fsa,                /* LPSECURITY_ATTRIBUTES Not inheritable */
 704                PAGE_READWRITE,     /* DWORD protections */
 705                highSize,           /* DWORD High word of max size */
 706                lowSize,            /* DWORD Low word of max size */


 732 }
 733 
 734 
 735 // method to free the given security descriptor and the contained
 736 // access control list.
 737 //
 738 static void free_security_desc(PSECURITY_DESCRIPTOR pSD) {
 739 
 740   BOOL success, exists, isdefault;
 741   PACL pACL;
 742 
 743   if (pSD != NULL) {
 744 
 745     // get the access control list from the security descriptor
 746     success = GetSecurityDescriptorDacl(pSD, &exists, &pACL, &isdefault);
 747 
 748     // if an ACL existed and it was not a default acl, then it must
 749     // be an ACL we enlisted. free the resources.
 750     //
 751     if (success && exists && pACL != NULL && !isdefault) {
 752       FREE_C_HEAP_ARRAY(char, pACL);
 753     }
 754 
 755     // free the security descriptor
 756     FREE_C_HEAP_ARRAY(char, pSD);
 757   }
 758 }
 759 
 760 // method to free up a security attributes structure and any
 761 // contained security descriptors and ACL
 762 //
 763 static void free_security_attr(LPSECURITY_ATTRIBUTES lpSA) {
 764 
 765   if (lpSA != NULL) {
 766     // free the contained security descriptor and the ACL
 767     free_security_desc(lpSA->lpSecurityDescriptor);
 768     lpSA->lpSecurityDescriptor = NULL;
 769 
 770     // free the security attributes structure
 771     FREE_C_HEAP_ARRAY(char, lpSA);
 772   }
 773 }
 774 
 775 // get the user SID for the process indicated by the process handle
 776 //
 777 static PSID get_user_sid(HANDLE hProcess) {
 778 
 779   HANDLE hAccessToken;
 780   PTOKEN_USER token_buf = NULL;
 781   DWORD rsize = 0;
 782 
 783   if (hProcess == NULL) {
 784     return NULL;
 785   }
 786 
 787   // get the process token
 788   if (!OpenProcessToken(hProcess, TOKEN_READ, &hAccessToken)) {
 789     if (PrintMiscellaneous && Verbose) {
 790       warning("OpenProcessToken failure: lasterror = %d \n", GetLastError());
 791     }


 798   if (!GetTokenInformation(hAccessToken, TokenUser, NULL, rsize, &rsize)) {
 799     DWORD lasterror = GetLastError();
 800     if (lasterror != ERROR_INSUFFICIENT_BUFFER) {
 801       if (PrintMiscellaneous && Verbose) {
 802         warning("GetTokenInformation failure: lasterror = %d,"
 803                 " rsize = %d\n", lasterror, rsize);
 804       }
 805       CloseHandle(hAccessToken);
 806       return NULL;
 807     }
 808   }
 809 
 810   token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize, mtInternal);
 811 
 812   // get the user token information
 813   if (!GetTokenInformation(hAccessToken, TokenUser, token_buf, rsize, &rsize)) {
 814     if (PrintMiscellaneous && Verbose) {
 815       warning("GetTokenInformation failure: lasterror = %d,"
 816               " rsize = %d\n", GetLastError(), rsize);
 817     }
 818     FREE_C_HEAP_ARRAY(char, token_buf);
 819     CloseHandle(hAccessToken);
 820     return NULL;
 821   }
 822 
 823   DWORD nbytes = GetLengthSid(token_buf->User.Sid);
 824   PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 825 
 826   if (!CopySid(nbytes, pSID, token_buf->User.Sid)) {
 827     if (PrintMiscellaneous && Verbose) {
 828       warning("GetTokenInformation failure: lasterror = %d,"
 829               " rsize = %d\n", GetLastError(), rsize);
 830     }
 831     FREE_C_HEAP_ARRAY(char, token_buf);
 832     FREE_C_HEAP_ARRAY(char, pSID);
 833     CloseHandle(hAccessToken);
 834     return NULL;
 835   }
 836 
 837   // close the access token.
 838   CloseHandle(hAccessToken);
 839   FREE_C_HEAP_ARRAY(char, token_buf);
 840 
 841   return pSID;
 842 }
 843 
 844 // structure used to consolidate access control entry information
 845 //
 846 typedef struct ace_data {
 847   PSID pSid;      // SID of the ACE
 848   DWORD mask;     // mask for the ACE
 849 } ace_data_t;
 850 
 851 
 852 // method to add an allow access control entry with the access rights
 853 // indicated in mask for the principal indicated in SID to the given
 854 // security descriptor. Much of the DACL handling was adapted from
 855 // the example provided here:
 856 //      http://support.microsoft.com/kb/102102/EN-US/
 857 //
 858 
 859 static bool add_allow_aces(PSECURITY_DESCRIPTOR pSD,


 903   // compute the size needed for the new ACL
 904   // initial size of ACL is sum of the following:
 905   //   * size of ACL structure.
 906   //   * size of each ACE structure that ACL is to contain minus the sid
 907   //     sidStart member (DWORD) of the ACE.
 908   //   * length of the SID that each ACE is to contain.
 909   DWORD newACLsize = aclinfo.AclBytesInUse +
 910                         (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * ace_count;
 911   for (int i = 0; i < ace_count; i++) {
 912      assert(aces[i].pSid != 0, "pSid should not be 0");
 913      newACLsize += GetLengthSid(aces[i].pSid);
 914   }
 915 
 916   // create the new ACL
 917   newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize, mtInternal);
 918 
 919   if (!InitializeAcl(newACL, newACLsize, ACL_REVISION)) {
 920     if (PrintMiscellaneous && Verbose) {
 921       warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 922     }
 923     FREE_C_HEAP_ARRAY(char, newACL);
 924     return false;
 925   }
 926 
 927   unsigned int ace_index = 0;
 928   // copy any existing ACEs from the old ACL (if any) to the new ACL.
 929   if (aclinfo.AceCount != 0) {
 930     while (ace_index < aclinfo.AceCount) {
 931       LPVOID ace;
 932       if (!GetAce(oldACL, ace_index, &ace)) {
 933         if (PrintMiscellaneous && Verbose) {
 934           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 935         }
 936         FREE_C_HEAP_ARRAY(char, newACL);
 937         return false;
 938       }
 939       if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
 940         // this is an inherited, allowed ACE; break from loop so we can
 941         // add the new access allowed, non-inherited ACE in the correct
 942         // position, immediately following all non-inherited ACEs.
 943         break;
 944       }
 945 
 946       // determine if the SID of this ACE matches any of the SIDs
 947       // for which we plan to set ACEs.
 948       int matches = 0;
 949       for (int i = 0; i < ace_count; i++) {
 950         if (EqualSid(aces[i].pSid, &(((ACCESS_ALLOWED_ACE *)ace)->SidStart))) {
 951           matches++;
 952           break;
 953         }
 954       }
 955 
 956       // if there are no SID matches, then add this existing ACE to the new ACL
 957       if (matches == 0) {
 958         if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
 959                     ((PACE_HEADER)ace)->AceSize)) {
 960           if (PrintMiscellaneous && Verbose) {
 961             warning("AddAce failure: lasterror = %d \n", GetLastError());
 962           }
 963           FREE_C_HEAP_ARRAY(char, newACL);
 964           return false;
 965         }
 966       }
 967       ace_index++;
 968     }
 969   }
 970 
 971   // add the passed-in access control entries to the new ACL
 972   for (int i = 0; i < ace_count; i++) {
 973     if (!AddAccessAllowedAce(newACL, ACL_REVISION,
 974                              aces[i].mask, aces[i].pSid)) {
 975       if (PrintMiscellaneous && Verbose) {
 976         warning("AddAccessAllowedAce failure: lasterror = %d \n",
 977                 GetLastError());
 978       }
 979       FREE_C_HEAP_ARRAY(char, newACL);
 980       return false;
 981     }
 982   }
 983 
 984   // now copy the rest of the inherited ACEs from the old ACL
 985   if (aclinfo.AceCount != 0) {
 986     // picking up at ace_index, where we left off in the
 987     // previous ace_index loop
 988     while (ace_index < aclinfo.AceCount) {
 989       LPVOID ace;
 990       if (!GetAce(oldACL, ace_index, &ace)) {
 991         if (PrintMiscellaneous && Verbose) {
 992           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
 993         }
 994         FREE_C_HEAP_ARRAY(char, newACL);
 995         return false;
 996       }
 997       if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
 998                   ((PACE_HEADER)ace)->AceSize)) {
 999         if (PrintMiscellaneous && Verbose) {
1000           warning("AddAce failure: lasterror = %d \n", GetLastError());
1001         }
1002         FREE_C_HEAP_ARRAY(char, newACL);
1003         return false;
1004       }
1005       ace_index++;
1006     }
1007   }
1008 
1009   // add the new ACL to the security descriptor.
1010   if (!SetSecurityDescriptorDacl(pSD, TRUE, newACL, FALSE)) {
1011     if (PrintMiscellaneous && Verbose) {
1012       warning("SetSecurityDescriptorDacl failure:"
1013               " lasterror = %d \n", GetLastError());
1014     }
1015     FREE_C_HEAP_ARRAY(char, newACL);
1016     return false;
1017   }
1018 
1019   // if running on windows 2000 or later, set the automatic inheritance
1020   // control flags.
1021   SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl;
1022   _SetSecurityDescriptorControl = (SetSecurityDescriptorControlFnPtr)
1023        GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
1024                       "SetSecurityDescriptorControl");
1025 
1026   if (_SetSecurityDescriptorControl != NULL) {
1027     // We do not want to further propagate inherited DACLs, so making them
1028     // protected prevents that.
1029     if (!_SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED,
1030                                             SE_DACL_PROTECTED)) {
1031       if (PrintMiscellaneous && Verbose) {
1032         warning("SetSecurityDescriptorControl failure:"
1033                 " lasterror = %d \n", GetLastError());
1034       }
1035       FREE_C_HEAP_ARRAY(char, newACL);
1036       return false;
1037     }
1038   }
1039    // Note, the security descriptor maintains a reference to the newACL, not
1040    // a copy of it. Therefore, the newACL is not freed here. It is freed when
1041    // the security descriptor containing its reference is freed.
1042    //
1043    return true;
1044 }
1045 
1046 // method to create a security attributes structure, which contains a
1047 // security descriptor and an access control list comprised of 0 or more
1048 // access control entries. The method take an array of ace_data structures
1049 // that indicate the ACE to be added to the security descriptor.
1050 //
1051 // the caller must free the resources associated with the security
1052 // attributes structure created by this method by calling the
1053 // free_security_attr() method.
1054 //
1055 static LPSECURITY_ATTRIBUTES make_security_attr(ace_data_t aces[], int count) {


1132   PSID everybodySid = NULL;
1133   SID_IDENTIFIER_AUTHORITY SIDAuthEverybody = SECURITY_WORLD_SID_AUTHORITY;
1134 
1135   if (!AllocateAndInitializeSid( &SIDAuthEverybody, 1, SECURITY_WORLD_RID,
1136            0, 0, 0, 0, 0, 0, 0, &everybodySid)) {
1137 
1138     if (PrintMiscellaneous && Verbose) {
1139       warning("AllocateAndInitializeSid failure: "
1140               "lasterror = %d \n", GetLastError());
1141     }
1142     return NULL;
1143   }
1144 
1145   // initialize the ace data for everybody else.
1146   aces[2].pSid = everybodySid;
1147   aces[2].mask = emask;
1148 
1149   // create a security attributes structure with access control
1150   // entries as initialized above.
1151   LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
1152   FREE_C_HEAP_ARRAY(char, aces[0].pSid);
1153   FreeSid(everybodySid);
1154   FreeSid(administratorsSid);
1155   return(lpSA);
1156 }
1157 
1158 
1159 // method to create the security attributes structure for restricting
1160 // access to the user temporary directory.
1161 //
1162 // the caller must free the resources associated with the security
1163 // attributes structure created by this method by calling the
1164 // free_security_attr() method.
1165 //
1166 static LPSECURITY_ATTRIBUTES make_tmpdir_security_attr() {
1167 
1168   // create full access rights for the user/owner of the directory
1169   // and read-only access rights for everybody else. This is
1170   // effectively equivalent to UNIX 755 permissions on a directory.
1171   //
1172   DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_ALL_ACCESS;


1447   // construct the name of the user specific temporary directory
1448   char* dirname = get_user_tmp_dir(user);
1449 
1450   // check that the file system is secure - i.e. it supports ACLs.
1451   if (!is_filesystem_secure(dirname)) {
1452     return NULL;
1453   }
1454 
1455   // create the names of the backing store files and for the
1456   // share memory object.
1457   //
1458   char* filename = get_sharedmem_filename(dirname, vmid);
1459   char* objectname = get_sharedmem_objectname(user, vmid);
1460 
1461   // cleanup any stale shared memory resources
1462   cleanup_sharedmem_resources(dirname);
1463 
1464   assert(((size != 0) && (size % os::vm_page_size() == 0)),
1465          "unexpected PerfMemry region size");
1466 
1467   FREE_C_HEAP_ARRAY(char, user);
1468 
1469   // create the shared memory resources
1470   sharedmem_fileMapHandle =
1471                create_sharedmem_resources(dirname, filename, objectname, size);
1472 
1473   FREE_C_HEAP_ARRAY(char, filename);
1474   FREE_C_HEAP_ARRAY(char, objectname);
1475   FREE_C_HEAP_ARRAY(char, dirname);
1476 
1477   if (sharedmem_fileMapHandle == NULL) {
1478     return NULL;
1479   }
1480 
1481   // map the file into the address space
1482   mapAddress = MapViewOfFile(
1483                    sharedmem_fileMapHandle, /* HANDLE = file mapping object */
1484                    FILE_MAP_ALL_ACCESS,     /* DWORD access flags */
1485                    0,                       /* DWORD High word of offset */
1486                    0,                       /* DWORD Low word of offset */
1487                    (DWORD)size);            /* DWORD Number of bytes to map */
1488 
1489   if (mapAddress == NULL) {
1490     if (PrintMiscellaneous && Verbose) {
1491       warning("MapViewOfFile failed, lasterror = %d\n", GetLastError());
1492     }
1493     CloseHandle(sharedmem_fileMapHandle);
1494     sharedmem_fileMapHandle = NULL;
1495     return NULL;


1610   // the owner of the target vm.
1611   if (user == NULL || strlen(user) == 0) {
1612     luser = get_user_name(vmid);
1613   }
1614   else {
1615     luser = user;
1616   }
1617 
1618   if (luser == NULL) {
1619     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1620               "Could not map vmid to user name");
1621   }
1622 
1623   // get the names for the resources for the target vm
1624   char* dirname = get_user_tmp_dir(luser);
1625 
1626   // since we don't follow symbolic links when creating the backing
1627   // store file, we also don't following them when attaching
1628   //
1629   if (!is_directory_secure(dirname)) {
1630     FREE_C_HEAP_ARRAY(char, dirname);
1631     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1632               "Process not found");
1633   }
1634 
1635   char* filename = get_sharedmem_filename(dirname, vmid);
1636   char* objectname = get_sharedmem_objectname(luser, vmid);
1637 
1638   // copy heap memory to resource memory. the objectname and
1639   // filename are passed to methods that may throw exceptions.
1640   // using resource arrays for these names prevents the leaks
1641   // that would otherwise occur.
1642   //
1643   char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
1644   char* robjectname = NEW_RESOURCE_ARRAY(char, strlen(objectname) + 1);
1645   strcpy(rfilename, filename);
1646   strcpy(robjectname, objectname);
1647 
1648   // free the c heap resources that are no longer needed
1649   if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
1650   FREE_C_HEAP_ARRAY(char, dirname);
1651   FREE_C_HEAP_ARRAY(char, filename);
1652   FREE_C_HEAP_ARRAY(char, objectname);
1653 
1654   if (*sizep == 0) {
1655     size = sharedmem_filesize(rfilename, CHECK);
1656   } else {
1657     size = *sizep;
1658   }
1659 
1660   assert(size > 0, "unexpected size <= 0");
1661 
1662   // Open the file mapping object with the given name
1663   fmh = open_sharedmem_object(robjectname, ofm_access, CHECK);
1664 
1665   assert(fmh != INVALID_HANDLE_VALUE, "unexpected handle value");
1666 
1667   // map the entire file into the address space
1668   mapAddress = MapViewOfFile(
1669                  fmh,             /* HANDLE Handle of file mapping object */
1670                  mv_access,       /* DWORD access flags */
1671                  0,               /* DWORD High word of offset */
1672                  0,               /* DWORD Low word of offset */


src/os/windows/vm/perfMemory_windows.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File