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