< prev index next >

src/hotspot/os/solaris/perfMemory_solaris.cpp

Print this page
rev 50955 : [mq]: readdir


 506   // directory search
 507   char* oldest_user = NULL;
 508   time_t oldest_ctime = 0;
 509 
 510   const char* tmpdirname = os::get_temp_directory();
 511 
 512   // open the temp directory
 513   DIR* tmpdirp = os::opendir(tmpdirname);
 514 
 515   if (tmpdirp == NULL) {
 516     // Cannot open the directory to get the user name, return.
 517     return NULL;
 518   }
 519 
 520   // for each entry in the directory that matches the pattern hsperfdata_*,
 521   // open the directory and check if the file for the given vmid exists.
 522   // The file with the expected name and the latest creation date is used
 523   // to determine the user name for the process id.
 524   //
 525   struct dirent* dentry;
 526   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 527   errno = 0;
 528   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != 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);
 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);
 557       os::closedir(subdirp);
 558       continue;
 559     }
 560 
 561     struct dirent* udentry;
 562     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 563     errno = 0;
 564     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 565 
 566       if (filename_to_pid(udentry->d_name) == vmid) {
 567         struct stat statbuf;
 568         int result;
 569 
 570         char* filename = NEW_C_HEAP_ARRAY(char,
 571                  strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 572 
 573         strcpy(filename, usrdir_name);
 574         strcat(filename, "/");
 575         strcat(filename, udentry->d_name);
 576 
 577         // don't follow symbolic links for the file
 578         RESTARTABLE(::lstat(filename, &statbuf), result);
 579         if (result == OS_ERR) {
 580            FREE_C_HEAP_ARRAY(char, filename);
 581            continue;
 582         }
 583 
 584         // skip over files that are not regular files.


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


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




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

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

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


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

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

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


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


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


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


< prev index next >