< prev index next >

src/hotspot/os/aix/perfMemory_aix.cpp

Print this page
rev 50955 : [mq]: readdir


 600   }
 601 
 602   // directory search
 603   char* oldest_user = NULL;
 604   time_t oldest_ctime = 0;
 605 
 606   const char* tmpdirname = os::get_temp_directory();
 607 
 608   DIR* tmpdirp = os::opendir(tmpdirname);
 609 
 610   if (tmpdirp == NULL) {
 611     return NULL;
 612   }
 613 
 614   // for each entry in the directory that matches the pattern hsperfdata_*,
 615   // open the directory and check if the file for the given vmid exists.
 616   // The file with the expected name and the latest creation date is used
 617   // to determine the user name for the process id.
 618   //
 619   struct dirent* dentry;
 620   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 621   errno = 0;
 622   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 623 
 624     // check if the directory entry is a hsperfdata file
 625     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 626       continue;
 627     }
 628 
 629     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 630                               strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 631     strcpy(usrdir_name, tmpdirname);
 632     strcat(usrdir_name, "/");
 633     strcat(usrdir_name, dentry->d_name);
 634 
 635     // Open the user directory.
 636     DIR* subdirp = open_directory_secure(usrdir_name);
 637 
 638     if (subdirp == NULL) {
 639       FREE_C_HEAP_ARRAY(char, usrdir_name);
 640       continue;
 641     }
 642 
 643     // Since we don't create the backing store files in directories
 644     // pointed to by symbolic links, we also don't follow them when
 645     // looking for the files. We check for a symbolic link after the
 646     // call to opendir in order to eliminate a small window where the
 647     // symlink can be exploited.
 648     //
 649     if (!is_directory_secure(usrdir_name)) {
 650       FREE_C_HEAP_ARRAY(char, usrdir_name);
 651       os::closedir(subdirp);
 652       continue;
 653     }
 654 
 655     struct dirent* udentry;
 656     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 657     errno = 0;
 658     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 659 
 660       if (filename_to_pid(udentry->d_name) == vmid) {
 661         struct stat statbuf;
 662         int result;
 663 
 664         char* filename = NEW_C_HEAP_ARRAY(char,
 665                             strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 666 
 667         strcpy(filename, usrdir_name);
 668         strcat(filename, "/");
 669         strcat(filename, udentry->d_name);
 670 
 671         // don't follow symbolic links for the file
 672         RESTARTABLE(::lstat(filename, &statbuf), result);
 673         if (result == OS_ERR) {
 674            FREE_C_HEAP_ARRAY(char, filename);
 675            continue;
 676         }
 677 
 678         // skip over files that are not regular files.


 682         }
 683 
 684         // compare and save filename with latest creation time
 685         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 686 
 687           if (statbuf.st_ctime > oldest_ctime) {
 688             char* user = strchr(dentry->d_name, '_') + 1;
 689 
 690             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 691             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 692 
 693             strcpy(oldest_user, user);
 694             oldest_ctime = statbuf.st_ctime;
 695           }
 696         }
 697 
 698         FREE_C_HEAP_ARRAY(char, filename);
 699       }
 700     }
 701     os::closedir(subdirp);
 702     FREE_C_HEAP_ARRAY(char, udbuf);
 703     FREE_C_HEAP_ARRAY(char, usrdir_name);
 704   }
 705   os::closedir(tmpdirp);
 706   FREE_C_HEAP_ARRAY(char, tdbuf);
 707 
 708   return(oldest_user);
 709 }
 710 
 711 // return the name of the user that owns the JVM indicated by the given vmid.
 712 //
 713 static char* get_user_name(int vmid, TRAPS) {
 714   return get_user_name_slow(vmid, THREAD);
 715 }
 716 
 717 // return the file name of the backing store file for the named
 718 // shared memory region for the given user name and vmid.
 719 //
 720 // the caller is expected to free the allocated memory.
 721 //
 722 static char* get_sharedmem_filename(const char* dirname, int vmid) {
 723 
 724   // add 2 for the file separator and a null terminator.
 725   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 726 


 762 // determine if the process is alive. If the process is not alive,
 763 // any stale file resources are removed.
 764 static void cleanup_sharedmem_resources(const char* dirname) {
 765 
 766   int saved_cwd_fd;
 767   // Open the directory.
 768   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 769   if (dirp == NULL) {
 770      // Directory doesn't exist or is insecure, so there is nothing to cleanup.
 771     return;
 772   }
 773 
 774   // For each entry in the directory that matches the expected file
 775   // name pattern, determine if the file resources are stale and if
 776   // so, remove the file resources. Note, instrumented HotSpot processes
 777   // for this user may start and/or terminate during this search and
 778   // remove or create new files in this directory. The behavior of this
 779   // loop under these conditions is dependent upon the implementation of
 780   // opendir/readdir.
 781   struct dirent* entry;
 782   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
 783 
 784   errno = 0;
 785   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 786 
 787     pid_t pid = filename_to_pid(entry->d_name);
 788 
 789     if (pid == 0) {
 790 
 791       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 792 
 793         // Attempt to remove all unexpected files, except "." and "..".
 794         unlink(entry->d_name);
 795       }
 796 
 797       errno = 0;
 798       continue;
 799     }
 800 
 801     // We now have a file name that converts to a valid integer
 802     // that could represent a process id . if this process id
 803     // matches the current process id or the process is not running,
 804     // then remove the stale file resources.
 805     //
 806     // Process liveness is detected by sending signal number 0 to
 807     // the process id (see kill(2)). if kill determines that the
 808     // process does not exist, then the file resources are removed.
 809     // if kill determines that that we don't have permission to
 810     // signal the process, then the file resources are assumed to
 811     // be stale and are removed because the resources for such a
 812     // process should be in a different user specific directory.
 813     if ((pid == os::current_process_id()) ||
 814         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 815 
 816         unlink(entry->d_name);
 817     }
 818     errno = 0;
 819   }
 820 
 821   // Close the directory and reset the current working directory.
 822   close_directory_secure_cwd(dirp, saved_cwd_fd);
 823 
 824   FREE_C_HEAP_ARRAY(char, dbuf);
 825 }
 826 
 827 // Make the user specific temporary directory. Returns true if
 828 // the directory exists and is secure upon return. Returns false
 829 // if the directory exists but is either a symlink, is otherwise
 830 // insecure, or if an error occurred.
 831 static bool make_user_tmp_dir(const char* dirname) {
 832 
 833   // Create the directory with 0755 permissions. note that the directory
 834   // will be owned by euid::egid, which may not be the same as uid::gid.
 835   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 836     if (errno == EEXIST) {
 837       // The directory already exists and was probably created by another
 838       // JVM instance. However, this could also be the result of a
 839       // deliberate symlink. Verify that the existing directory is safe.
 840       if (!is_directory_secure(dirname)) {
 841         // Directory is not secure.
 842         if (PrintMiscellaneous && Verbose) {
 843           warning("%s directory is insecure\n", dirname);
 844         }




 600   }
 601 
 602   // directory search
 603   char* oldest_user = NULL;
 604   time_t oldest_ctime = 0;
 605 
 606   const char* tmpdirname = os::get_temp_directory();
 607 
 608   DIR* tmpdirp = os::opendir(tmpdirname);
 609 
 610   if (tmpdirp == NULL) {
 611     return NULL;
 612   }
 613 
 614   // for each entry in the directory that matches the pattern hsperfdata_*,
 615   // open the directory and check if the file for the given vmid exists.
 616   // The file with the expected name and the latest creation date is used
 617   // to determine the user name for the process id.
 618   //
 619   struct dirent* dentry;

 620   errno = 0;
 621   while ((dentry = os::readdir(tmpdirp)) != NULL) {
 622 
 623     // check if the directory entry is a hsperfdata file
 624     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 625       continue;
 626     }
 627 
 628     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 629                               strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 630     strcpy(usrdir_name, tmpdirname);
 631     strcat(usrdir_name, "/");
 632     strcat(usrdir_name, dentry->d_name);
 633 
 634     // Open the user directory.
 635     DIR* subdirp = open_directory_secure(usrdir_name);
 636 
 637     if (subdirp == NULL) {
 638       FREE_C_HEAP_ARRAY(char, usrdir_name);
 639       continue;
 640     }
 641 
 642     // Since we don't create the backing store files in directories
 643     // pointed to by symbolic links, we also don't follow them when
 644     // looking for the files. We check for a symbolic link after the
 645     // call to opendir in order to eliminate a small window where the
 646     // symlink can be exploited.
 647     //
 648     if (!is_directory_secure(usrdir_name)) {
 649       FREE_C_HEAP_ARRAY(char, usrdir_name);
 650       os::closedir(subdirp);
 651       continue;
 652     }
 653 
 654     struct dirent* udentry;

 655     errno = 0;
 656     while ((udentry = os::readdir(subdirp)) != NULL) {
 657 
 658       if (filename_to_pid(udentry->d_name) == vmid) {
 659         struct stat statbuf;
 660         int result;
 661 
 662         char* filename = NEW_C_HEAP_ARRAY(char,
 663                             strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 664 
 665         strcpy(filename, usrdir_name);
 666         strcat(filename, "/");
 667         strcat(filename, udentry->d_name);
 668 
 669         // don't follow symbolic links for the file
 670         RESTARTABLE(::lstat(filename, &statbuf), result);
 671         if (result == OS_ERR) {
 672            FREE_C_HEAP_ARRAY(char, filename);
 673            continue;
 674         }
 675 
 676         // skip over files that are not regular files.


 680         }
 681 
 682         // compare and save filename with latest creation time
 683         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 684 
 685           if (statbuf.st_ctime > oldest_ctime) {
 686             char* user = strchr(dentry->d_name, '_') + 1;
 687 
 688             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 689             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 690 
 691             strcpy(oldest_user, user);
 692             oldest_ctime = statbuf.st_ctime;
 693           }
 694         }
 695 
 696         FREE_C_HEAP_ARRAY(char, filename);
 697       }
 698     }
 699     os::closedir(subdirp);

 700     FREE_C_HEAP_ARRAY(char, usrdir_name);
 701   }
 702   os::closedir(tmpdirp);

 703 
 704   return(oldest_user);
 705 }
 706 
 707 // return the name of the user that owns the JVM indicated by the given vmid.
 708 //
 709 static char* get_user_name(int vmid, TRAPS) {
 710   return get_user_name_slow(vmid, THREAD);
 711 }
 712 
 713 // return the file name of the backing store file for the named
 714 // shared memory region for the given user name and vmid.
 715 //
 716 // the caller is expected to free the allocated memory.
 717 //
 718 static char* get_sharedmem_filename(const char* dirname, int vmid) {
 719 
 720   // add 2 for the file separator and a null terminator.
 721   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 722 


 758 // determine if the process is alive. If the process is not alive,
 759 // any stale file resources are removed.
 760 static void cleanup_sharedmem_resources(const char* dirname) {
 761 
 762   int saved_cwd_fd;
 763   // Open the directory.
 764   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 765   if (dirp == NULL) {
 766      // Directory doesn't exist or is insecure, so there is nothing to cleanup.
 767     return;
 768   }
 769 
 770   // For each entry in the directory that matches the expected file
 771   // name pattern, determine if the file resources are stale and if
 772   // so, remove the file resources. Note, instrumented HotSpot processes
 773   // for this user may start and/or terminate during this search and
 774   // remove or create new files in this directory. The behavior of this
 775   // loop under these conditions is dependent upon the implementation of
 776   // opendir/readdir.
 777   struct dirent* entry;


 778   errno = 0;
 779   while ((entry = os::readdir(dirp)) != NULL) {
 780 
 781     pid_t pid = filename_to_pid(entry->d_name);
 782 
 783     if (pid == 0) {
 784 
 785       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 786 
 787         // Attempt to remove all unexpected files, except "." and "..".
 788         unlink(entry->d_name);
 789       }
 790 
 791       errno = 0;
 792       continue;
 793     }
 794 
 795     // We now have a file name that converts to a valid integer
 796     // that could represent a process id . if this process id
 797     // matches the current process id or the process is not running,
 798     // then remove the stale file resources.
 799     //
 800     // Process liveness is detected by sending signal number 0 to
 801     // the process id (see kill(2)). if kill determines that the
 802     // process does not exist, then the file resources are removed.
 803     // if kill determines that that we don't have permission to
 804     // signal the process, then the file resources are assumed to
 805     // be stale and are removed because the resources for such a
 806     // process should be in a different user specific directory.
 807     if ((pid == os::current_process_id()) ||
 808         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 809 
 810         unlink(entry->d_name);
 811     }
 812     errno = 0;
 813   }
 814 
 815   // Close the directory and reset the current working directory.
 816   close_directory_secure_cwd(dirp, saved_cwd_fd);


 817 }
 818 
 819 // Make the user specific temporary directory. Returns true if
 820 // the directory exists and is secure upon return. Returns false
 821 // if the directory exists but is either a symlink, is otherwise
 822 // insecure, or if an error occurred.
 823 static bool make_user_tmp_dir(const char* dirname) {
 824 
 825   // Create the directory with 0755 permissions. note that the directory
 826   // will be owned by euid::egid, which may not be the same as uid::gid.
 827   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 828     if (errno == EEXIST) {
 829       // The directory already exists and was probably created by another
 830       // JVM instance. However, this could also be the result of a
 831       // deliberate symlink. Verify that the existing directory is safe.
 832       if (!is_directory_secure(dirname)) {
 833         // Directory is not secure.
 834         if (PrintMiscellaneous && Verbose) {
 835           warning("%s directory is insecure\n", dirname);
 836         }


< prev index next >