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