< prev index next >

src/os/solaris/vm/perfMemory_solaris.cpp

Print this page




 507   // directory search
 508   char* oldest_user = NULL;
 509   time_t oldest_ctime = 0;
 510 
 511   const char* tmpdirname = os::get_temp_directory();
 512 
 513   // open the temp directory
 514   DIR* tmpdirp = os::opendir(tmpdirname);
 515 
 516   if (tmpdirp == NULL) {
 517     // Cannot open the directory to get the user name, return.
 518     return NULL;
 519   }
 520 
 521   // for each entry in the directory that matches the pattern hsperfdata_*,
 522   // open the directory and check if the file for the given vmid exists.
 523   // The file with the expected name and the latest creation date is used
 524   // to determine the user name for the process id.
 525   //
 526   struct dirent* dentry;
 527   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 528   errno = 0;
 529   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 530 
 531     // check if the directory entry is a hsperfdata file
 532     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 533       continue;
 534     }
 535 
 536     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 537                   strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 538     strcpy(usrdir_name, tmpdirname);
 539     strcat(usrdir_name, "/");
 540     strcat(usrdir_name, dentry->d_name);
 541 
 542     // open the user directory
 543     DIR* subdirp = open_directory_secure(usrdir_name);
 544 
 545     if (subdirp == NULL) {
 546       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 547       continue;
 548     }
 549 
 550     // Since we don't create the backing store files in directories
 551     // pointed to by symbolic links, we also don't follow them when
 552     // looking for the files. We check for a symbolic link after the
 553     // call to opendir in order to eliminate a small window where the
 554     // symlink can be exploited.
 555     //
 556     if (!is_directory_secure(usrdir_name)) {
 557       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 558       os::closedir(subdirp);
 559       continue;
 560     }
 561 
 562     struct dirent* udentry;
 563     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 564     errno = 0;
 565     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 566 
 567       if (filename_to_pid(udentry->d_name) == vmid) {
 568         struct stat statbuf;
 569         int result;
 570 
 571         char* filename = NEW_C_HEAP_ARRAY(char,
 572                  strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 573 
 574         strcpy(filename, usrdir_name);
 575         strcat(filename, "/");
 576         strcat(filename, udentry->d_name);
 577 
 578         // don't follow symbolic links for the file
 579         RESTARTABLE(::lstat(filename, &statbuf), result);
 580         if (result == OS_ERR) {
 581            FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 582            continue;
 583         }
 584 
 585         // skip over files that are not regular files.


 589         }
 590 
 591         // compare and save filename with latest creation time
 592         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 593 
 594           if (statbuf.st_ctime > oldest_ctime) {
 595             char* user = strchr(dentry->d_name, '_') + 1;
 596 
 597             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
 598             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 599 
 600             strcpy(oldest_user, user);
 601             oldest_ctime = statbuf.st_ctime;
 602           }
 603         }
 604 
 605         FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 606       }
 607     }
 608     os::closedir(subdirp);
 609     FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
 610     FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 611   }
 612   os::closedir(tmpdirp);
 613   FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 614 
 615   return(oldest_user);
 616 }
 617 
 618 // return the name of the user that owns the JVM indicated by the given vmid.
 619 //
 620 static char* get_user_name(int vmid, TRAPS) {
 621 
 622   char psinfo_name[PATH_MAX];
 623   int result;
 624 
 625   snprintf(psinfo_name, PATH_MAX, "/proc/%d/psinfo", vmid);
 626 
 627   RESTARTABLE(::open(psinfo_name, O_RDONLY), result);
 628 
 629   if (result != OS_ERR) {
 630     int fd = result;
 631 
 632     psinfo_t psinfo;
 633     char* addr = (char*)&psinfo;


 720 //
 721 static void cleanup_sharedmem_resources(const char* dirname) {
 722 
 723   int saved_cwd_fd;
 724   // open the directory
 725   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 726   if (dirp == NULL) {
 727      // directory doesn't exist or is insecure, so there is nothing to cleanup
 728     return;
 729   }
 730 
 731   // for each entry in the directory that matches the expected file
 732   // name pattern, determine if the file resources are stale and if
 733   // so, remove the file resources. Note, instrumented HotSpot processes
 734   // for this user may start and/or terminate during this search and
 735   // remove or create new files in this directory. The behavior of this
 736   // loop under these conditions is dependent upon the implementation of
 737   // opendir/readdir.
 738   //
 739   struct dirent* entry;
 740   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
 741 
 742   errno = 0;
 743   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 744 
 745     pid_t pid = filename_to_pid(entry->d_name);
 746 
 747     if (pid == 0) {
 748 
 749       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 750 
 751         // attempt to remove all unexpected files, except "." and ".."
 752         unlink(entry->d_name);
 753       }
 754 
 755       errno = 0;
 756       continue;
 757     }
 758 
 759     // we now have a file name that converts to a valid integer
 760     // that could represent a process id . if this process id
 761     // matches the current process id or the process is not running,
 762     // then remove the stale file resources.
 763     //
 764     // process liveness is detected by sending signal number 0 to
 765     // the process id (see kill(2)). if kill determines that the
 766     // process does not exist, then the file resources are removed.
 767     // if kill determines that that we don't have permission to
 768     // signal the process, then the file resources are assumed to
 769     // be stale and are removed because the resources for such a
 770     // process should be in a different user specific directory.
 771     //
 772     if ((pid == os::current_process_id()) ||
 773         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 774 
 775         unlink(entry->d_name);
 776     }
 777     errno = 0;
 778   }
 779 
 780   // close the directory and reset the current working directory
 781   close_directory_secure_cwd(dirp, saved_cwd_fd);
 782 
 783   FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 784 }
 785 
 786 // make the user specific temporary directory. Returns true if
 787 // the directory exists and is secure upon return. Returns false
 788 // if the directory exists but is either a symlink, is otherwise
 789 // insecure, or if an error occurred.
 790 //
 791 static bool make_user_tmp_dir(const char* dirname) {
 792 
 793   // create the directory with 0755 permissions. note that the directory
 794   // will be owned by euid::egid, which may not be the same as uid::gid.
 795   //
 796   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 797     if (errno == EEXIST) {
 798       // The directory already exists and was probably created by another
 799       // JVM instance. However, this could also be the result of a
 800       // deliberate symlink. Verify that the existing directory is safe.
 801       //
 802       if (!is_directory_secure(dirname)) {
 803         // directory is not secure




 507   // directory search
 508   char* oldest_user = NULL;
 509   time_t oldest_ctime = 0;
 510 
 511   const char* tmpdirname = os::get_temp_directory();
 512 
 513   // open the temp directory
 514   DIR* tmpdirp = os::opendir(tmpdirname);
 515 
 516   if (tmpdirp == NULL) {
 517     // Cannot open the directory to get the user name, return.
 518     return NULL;
 519   }
 520 
 521   // for each entry in the directory that matches the pattern hsperfdata_*,
 522   // open the directory and check if the file for the given vmid exists.
 523   // The file with the expected name and the latest creation date is used
 524   // to determine the user name for the process id.
 525   //
 526   struct dirent* dentry;

 527   errno = 0;
 528   while ((dentry = os::readdir(tmpdirp)) != NULL) {
 529 
 530     // check if the directory entry is a hsperfdata file
 531     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 532       continue;
 533     }
 534 
 535     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 536                   strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 537     strcpy(usrdir_name, tmpdirname);
 538     strcat(usrdir_name, "/");
 539     strcat(usrdir_name, dentry->d_name);
 540 
 541     // open the user directory
 542     DIR* subdirp = open_directory_secure(usrdir_name);
 543 
 544     if (subdirp == NULL) {
 545       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 546       continue;
 547     }
 548 
 549     // Since we don't create the backing store files in directories
 550     // pointed to by symbolic links, we also don't follow them when
 551     // looking for the files. We check for a symbolic link after the
 552     // call to opendir in order to eliminate a small window where the
 553     // symlink can be exploited.
 554     //
 555     if (!is_directory_secure(usrdir_name)) {
 556       FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 557       os::closedir(subdirp);
 558       continue;
 559     }
 560 
 561     struct dirent* udentry;

 562     errno = 0;
 563     while ((udentry = os::readdir(subdirp)) != NULL) {
 564 
 565       if (filename_to_pid(udentry->d_name) == vmid) {
 566         struct stat statbuf;
 567         int result;
 568 
 569         char* filename = NEW_C_HEAP_ARRAY(char,
 570                  strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 571 
 572         strcpy(filename, usrdir_name);
 573         strcat(filename, "/");
 574         strcat(filename, udentry->d_name);
 575 
 576         // don't follow symbolic links for the file
 577         RESTARTABLE(::lstat(filename, &statbuf), result);
 578         if (result == OS_ERR) {
 579            FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 580            continue;
 581         }
 582 
 583         // skip over files that are not regular files.


 587         }
 588 
 589         // compare and save filename with latest creation time
 590         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 591 
 592           if (statbuf.st_ctime > oldest_ctime) {
 593             char* user = strchr(dentry->d_name, '_') + 1;
 594 
 595             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
 596             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 597 
 598             strcpy(oldest_user, user);
 599             oldest_ctime = statbuf.st_ctime;
 600           }
 601         }
 602 
 603         FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 604       }
 605     }
 606     os::closedir(subdirp);

 607     FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
 608   }
 609   os::closedir(tmpdirp);

 610 
 611   return(oldest_user);
 612 }
 613 
 614 // return the name of the user that owns the JVM indicated by the given vmid.
 615 //
 616 static char* get_user_name(int vmid, TRAPS) {
 617 
 618   char psinfo_name[PATH_MAX];
 619   int result;
 620 
 621   snprintf(psinfo_name, PATH_MAX, "/proc/%d/psinfo", vmid);
 622 
 623   RESTARTABLE(::open(psinfo_name, O_RDONLY), result);
 624 
 625   if (result != OS_ERR) {
 626     int fd = result;
 627 
 628     psinfo_t psinfo;
 629     char* addr = (char*)&psinfo;


 716 //
 717 static void cleanup_sharedmem_resources(const char* dirname) {
 718 
 719   int saved_cwd_fd;
 720   // open the directory
 721   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 722   if (dirp == NULL) {
 723      // directory doesn't exist or is insecure, so there is nothing to cleanup
 724     return;
 725   }
 726 
 727   // for each entry in the directory that matches the expected file
 728   // name pattern, determine if the file resources are stale and if
 729   // so, remove the file resources. Note, instrumented HotSpot processes
 730   // for this user may start and/or terminate during this search and
 731   // remove or create new files in this directory. The behavior of this
 732   // loop under these conditions is dependent upon the implementation of
 733   // opendir/readdir.
 734   //
 735   struct dirent* entry;


 736   errno = 0;
 737   while ((entry = os::readdir(dirp)) != NULL) {
 738 
 739     pid_t pid = filename_to_pid(entry->d_name);
 740 
 741     if (pid == 0) {
 742 
 743       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 744 
 745         // attempt to remove all unexpected files, except "." and ".."
 746         unlink(entry->d_name);
 747       }
 748 
 749       errno = 0;
 750       continue;
 751     }
 752 
 753     // we now have a file name that converts to a valid integer
 754     // that could represent a process id . if this process id
 755     // matches the current process id or the process is not running,
 756     // then remove the stale file resources.
 757     //
 758     // process liveness is detected by sending signal number 0 to
 759     // the process id (see kill(2)). if kill determines that the
 760     // process does not exist, then the file resources are removed.
 761     // if kill determines that that we don't have permission to
 762     // signal the process, then the file resources are assumed to
 763     // be stale and are removed because the resources for such a
 764     // process should be in a different user specific directory.
 765     //
 766     if ((pid == os::current_process_id()) ||
 767         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 768 
 769         unlink(entry->d_name);
 770     }
 771     errno = 0;
 772   }
 773 
 774   // close the directory and reset the current working directory
 775   close_directory_secure_cwd(dirp, saved_cwd_fd);


 776 }
 777 
 778 // make the user specific temporary directory. Returns true if
 779 // the directory exists and is secure upon return. Returns false
 780 // if the directory exists but is either a symlink, is otherwise
 781 // insecure, or if an error occurred.
 782 //
 783 static bool make_user_tmp_dir(const char* dirname) {
 784 
 785   // create the directory with 0755 permissions. note that the directory
 786   // will be owned by euid::egid, which may not be the same as uid::gid.
 787   //
 788   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 789     if (errno == EEXIST) {
 790       // The directory already exists and was probably created by another
 791       // JVM instance. However, this could also be the result of a
 792       // deliberate symlink. Verify that the existing directory is safe.
 793       //
 794       if (!is_directory_secure(dirname)) {
 795         // directory is not secure


< prev index next >