annotate src/os/windows/vm/perfMemory_windows.cpp @ 17716:cdb71841f4bc

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