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 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
320 errno = 0;
321 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
322
323 // check if the directory entry is a hsperfdata file
324 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
325 continue;
326 }
327
328 char* usrdir_name = NEW_C_HEAP_ARRAY(char,
329 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
330 strcpy(usrdir_name, tmpdirname);
331 strcat(usrdir_name, "\\");
332 strcat(usrdir_name, dentry->d_name);
333
334 DIR* subdirp = os::opendir(usrdir_name);
335
336 if (subdirp == NULL) {
337 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
338 continue;
339 }
340
341 // Since we don't create the backing store files in directories
342 // pointed to by symbolic links, we also don't follow them when
343 // looking for the files. We check for a symbolic link after the
344 // call to opendir in order to eliminate a small window where the
345 // symlink can be exploited.
346 //
347 if (!is_directory_secure(usrdir_name)) {
348 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
349 os::closedir(subdirp);
350 continue;
351 }
352
353 struct dirent* udentry;
354 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
355 errno = 0;
356 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
357
358 if (filename_to_pid(udentry->d_name) == vmid) {
359 struct stat statbuf;
360
361 char* filename = NEW_C_HEAP_ARRAY(char,
362 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
363
364 strcpy(filename, usrdir_name);
365 strcat(filename, "\\");
366 strcat(filename, udentry->d_name);
367
368 if (::stat(filename, &statbuf) == OS_ERR) {
369 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
370 continue;
371 }
372
373 // skip over files that are not regular files.
374 if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
375 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
376 continue;
388 // In this function, all we're trying to do is determine the
389 // name of the user that owns the process associated with vmid
390 // so the size doesn't matter. Very rarely, we have observed
391 // hsperfdata files where (st_size == 0) and the st_size field
392 // later becomes the expected value.
393 //
394 if (statbuf.st_ctime > latest_ctime) {
395 char* user = strchr(dentry->d_name, '_') + 1;
396
397 if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user, mtInternal);
398 latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
399
400 strcpy(latest_user, user);
401 latest_ctime = statbuf.st_ctime;
402 }
403
404 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
405 }
406 }
407 os::closedir(subdirp);
408 FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
409 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
410 }
411 os::closedir(tmpdirp);
412 FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
413
414 return(latest_user);
415 }
416
417 // return the name of the user that owns the process identified by vmid.
418 //
419 // note: this method should only be used via the Perf native methods.
420 // There are various costs to this method and limiting its use to the
421 // Perf native methods limits the impact to monitoring applications only.
422 //
423 static char* get_user_name(int vmid) {
424
425 // A fast implementation is not provided at this time. It's possible
426 // to provide a fast process id to user name mapping function using
427 // the win32 apis, but the default ACL for the process object only
428 // allows processes with the same owner SID to acquire the process
429 // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
430 // to have the JVM change the ACL for the process object to allow arbitrary
431 // users to access the process handle and the process security token.
432 // The security ramifications need to be studied before providing this
622
623 if (dirp == NULL) {
624 // directory doesn't exist, so there is nothing to cleanup
625 return;
626 }
627
628 if (!is_directory_secure(dirname)) {
629 // the directory is not secure, don't attempt any cleanup
630 return;
631 }
632
633 // for each entry in the directory that matches the expected file
634 // name pattern, determine if the file resources are stale and if
635 // so, remove the file resources. Note, instrumented HotSpot processes
636 // for this user may start and/or terminate during this search and
637 // remove or create new files in this directory. The behavior of this
638 // loop under these conditions is dependent upon the implementation of
639 // opendir/readdir.
640 //
641 struct dirent* entry;
642 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
643 errno = 0;
644 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
645
646 int pid = filename_to_pid(entry->d_name);
647
648 if (pid == 0) {
649
650 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
651
652 // attempt to remove all unexpected files, except "." and ".."
653 remove_file(dirname, entry->d_name);
654 }
655
656 errno = 0;
657 continue;
658 }
659
660 // we now have a file name that converts to a valid integer
661 // that could represent a process id . if this process id
662 // matches the current process id or the process is not running,
663 // then remove the stale file resources.
664 //
665 // process liveness is detected by checking the exit status
666 // of the process. if the process id is valid and the exit status
667 // indicates that it is still running, the file file resources
668 // are not removed. If the process id is invalid, or if we don't
669 // have permissions to check the process status, or if the process
670 // id is valid and the process has terminated, the the file resources
671 // are assumed to be stale and are removed.
672 //
673 if (pid == os::current_process_id() || !is_alive(pid)) {
674
675 // we can only remove the file resources. Any mapped views
676 // of the file can only be unmapped by the processes that
677 // opened those views and the file mapping object will not
678 // get removed until all views are unmapped.
679 //
680 remove_file(dirname, entry->d_name);
681 }
682 errno = 0;
683 }
684 os::closedir(dirp);
685 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
686 }
687
688 // create a file mapping object with the requested name, and size
689 // from the file represented by the given Handle object
690 //
691 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
692
693 DWORD lowSize = (DWORD)size;
694 DWORD highSize = 0;
695 HANDLE fmh = NULL;
696
697 // Create a file mapping object with the given name. This function
698 // will grow the file to the specified size.
699 //
700 fmh = CreateFileMapping(
701 fh, /* HANDLE file handle for backing store */
702 fsa, /* LPSECURITY_ATTRIBUTES Not inheritable */
703 PAGE_READWRITE, /* DWORD protections */
704 highSize, /* DWORD High word of max size */
705 lowSize, /* DWORD Low word of max size */
|
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;
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
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 */
|