< prev index next >

src/hotspot/os/linux/perfMemory_linux.cpp

Print this page
rev 50955 : [mq]: readdir


 545   else {
 546     jio_snprintf(buffer, MAXPATHLEN, "/proc/%d/root%s", vmid, tmpdirname);
 547     tmpdirname = buffer;
 548     searchpid = nspid;
 549   }
 550 
 551   // open the temp directory
 552   DIR* tmpdirp = os::opendir(tmpdirname);
 553 
 554   if (tmpdirp == NULL) {
 555     // Cannot open the directory to get the user name, return.
 556     return NULL;
 557   }
 558 
 559   // for each entry in the directory that matches the pattern hsperfdata_*,
 560   // open the directory and check if the file for the given vmid or nspid exists.
 561   // The file with the expected name and the latest creation date is used
 562   // to determine the user name for the process id.
 563   //
 564   struct dirent* dentry;
 565   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 566   errno = 0;
 567   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 568 
 569     // check if the directory entry is a hsperfdata file
 570     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 571       continue;
 572     }
 573 
 574     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 575                      strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 576     strcpy(usrdir_name, tmpdirname);
 577     strcat(usrdir_name, "/");
 578     strcat(usrdir_name, dentry->d_name);
 579 
 580     // open the user directory
 581     DIR* subdirp = open_directory_secure(usrdir_name);
 582 
 583     if (subdirp == NULL) {
 584       FREE_C_HEAP_ARRAY(char, usrdir_name);
 585       continue;
 586     }
 587 
 588     // Since we don't create the backing store files in directories
 589     // pointed to by symbolic links, we also don't follow them when
 590     // looking for the files. We check for a symbolic link after the
 591     // call to opendir in order to eliminate a small window where the
 592     // symlink can be exploited.
 593     //
 594     if (!is_directory_secure(usrdir_name)) {
 595       FREE_C_HEAP_ARRAY(char, usrdir_name);
 596       os::closedir(subdirp);
 597       continue;
 598     }
 599 
 600     struct dirent* udentry;
 601     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 602     errno = 0;
 603     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 604 
 605       if (filename_to_pid(udentry->d_name) == searchpid) {
 606         struct stat statbuf;
 607         int result;
 608 
 609         char* filename = NEW_C_HEAP_ARRAY(char,
 610                    strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 611 
 612         strcpy(filename, usrdir_name);
 613         strcat(filename, "/");
 614         strcat(filename, udentry->d_name);
 615 
 616         // don't follow symbolic links for the file
 617         RESTARTABLE(::lstat(filename, &statbuf), result);
 618         if (result == OS_ERR) {
 619            FREE_C_HEAP_ARRAY(char, filename);
 620            continue;
 621         }
 622 
 623         // skip over files that are not regular files.


 627         }
 628 
 629         // compare and save filename with latest creation time
 630         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 631 
 632           if (statbuf.st_ctime > oldest_ctime) {
 633             char* user = strchr(dentry->d_name, '_') + 1;
 634 
 635             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 636             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 637 
 638             strcpy(oldest_user, user);
 639             oldest_ctime = statbuf.st_ctime;
 640           }
 641         }
 642 
 643         FREE_C_HEAP_ARRAY(char, filename);
 644       }
 645     }
 646     os::closedir(subdirp);
 647     FREE_C_HEAP_ARRAY(char, udbuf);
 648     FREE_C_HEAP_ARRAY(char, usrdir_name);
 649   }
 650   os::closedir(tmpdirp);
 651   FREE_C_HEAP_ARRAY(char, tdbuf);
 652 
 653   return(oldest_user);
 654 }
 655 
 656 // Determine if the vmid is the parent pid
 657 // for a child in a PID namespace.
 658 // return the namespace pid if so, otherwise -1
 659 static int get_namespace_pid(int vmid) {
 660   char fname[24];
 661   int retpid = -1;
 662 
 663   snprintf(fname, sizeof(fname), "/proc/%d/status", vmid);
 664   FILE *fp = fopen(fname, "r");
 665 
 666   if (fp) {
 667     int pid, nspid;
 668     int ret;
 669     while (!feof(fp)) {
 670       ret = fscanf(fp, "NSpid: %d %d", &pid, &nspid);
 671       if (ret == 1) {


 753 //
 754 static void cleanup_sharedmem_resources(const char* dirname) {
 755 
 756   int saved_cwd_fd;
 757   // open the directory
 758   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 759   if (dirp == NULL) {
 760     // directory doesn't exist or is insecure, so there is nothing to cleanup
 761     return;
 762   }
 763 
 764   // for each entry in the directory that matches the expected file
 765   // name pattern, determine if the file resources are stale and if
 766   // so, remove the file resources. Note, instrumented HotSpot processes
 767   // for this user may start and/or terminate during this search and
 768   // remove or create new files in this directory. The behavior of this
 769   // loop under these conditions is dependent upon the implementation of
 770   // opendir/readdir.
 771   //
 772   struct dirent* entry;
 773   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
 774 
 775   errno = 0;
 776   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 777 
 778     pid_t pid = filename_to_pid(entry->d_name);
 779 
 780     if (pid == 0) {
 781 
 782       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 783         // attempt to remove all unexpected files, except "." and ".."
 784         unlink(entry->d_name);
 785       }
 786 
 787       errno = 0;
 788       continue;
 789     }
 790 
 791     // we now have a file name that converts to a valid integer
 792     // that could represent a process id . if this process id
 793     // matches the current process id or the process is not running,
 794     // then remove the stale file resources.
 795     //
 796     // process liveness is detected by sending signal number 0 to
 797     // the process id (see kill(2)). if kill determines that the
 798     // process does not exist, then the file resources are removed.
 799     // if kill determines that that we don't have permission to
 800     // signal the process, then the file resources are assumed to
 801     // be stale and are removed because the resources for such a
 802     // process should be in a different user specific directory.
 803     //
 804     if ((pid == os::current_process_id()) ||
 805         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 806         unlink(entry->d_name);
 807     }
 808     errno = 0;
 809   }
 810 
 811   // close the directory and reset the current working directory
 812   close_directory_secure_cwd(dirp, saved_cwd_fd);
 813 
 814   FREE_C_HEAP_ARRAY(char, dbuf);
 815 }
 816 
 817 // make the user specific temporary directory. Returns true if
 818 // the directory exists and is secure upon return. Returns false
 819 // if the directory exists but is either a symlink, is otherwise
 820 // insecure, or if an error occurred.
 821 //
 822 static bool make_user_tmp_dir(const char* dirname) {
 823 
 824   // create the directory with 0755 permissions. note that the directory
 825   // will be owned by euid::egid, which may not be the same as uid::gid.
 826   //
 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       //
 833       if (!is_directory_secure(dirname)) {
 834         // directory is not secure




 545   else {
 546     jio_snprintf(buffer, MAXPATHLEN, "/proc/%d/root%s", vmid, tmpdirname);
 547     tmpdirname = buffer;
 548     searchpid = nspid;
 549   }
 550 
 551   // open the temp directory
 552   DIR* tmpdirp = os::opendir(tmpdirname);
 553 
 554   if (tmpdirp == NULL) {
 555     // Cannot open the directory to get the user name, return.
 556     return NULL;
 557   }
 558 
 559   // for each entry in the directory that matches the pattern hsperfdata_*,
 560   // open the directory and check if the file for the given vmid or nspid exists.
 561   // The file with the expected name and the latest creation date is used
 562   // to determine the user name for the process id.
 563   //
 564   struct dirent* dentry;

 565   errno = 0;
 566   while ((dentry = os::readdir(tmpdirp)) != NULL) {
 567 
 568     // check if the directory entry is a hsperfdata file
 569     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 570       continue;
 571     }
 572 
 573     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 574                      strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 575     strcpy(usrdir_name, tmpdirname);
 576     strcat(usrdir_name, "/");
 577     strcat(usrdir_name, dentry->d_name);
 578 
 579     // open the user directory
 580     DIR* subdirp = open_directory_secure(usrdir_name);
 581 
 582     if (subdirp == NULL) {
 583       FREE_C_HEAP_ARRAY(char, usrdir_name);
 584       continue;
 585     }
 586 
 587     // Since we don't create the backing store files in directories
 588     // pointed to by symbolic links, we also don't follow them when
 589     // looking for the files. We check for a symbolic link after the
 590     // call to opendir in order to eliminate a small window where the
 591     // symlink can be exploited.
 592     //
 593     if (!is_directory_secure(usrdir_name)) {
 594       FREE_C_HEAP_ARRAY(char, usrdir_name);
 595       os::closedir(subdirp);
 596       continue;
 597     }
 598 
 599     struct dirent* udentry;

 600     errno = 0;
 601     while ((udentry = os::readdir(subdirp)) != NULL) {
 602 
 603       if (filename_to_pid(udentry->d_name) == searchpid) {
 604         struct stat statbuf;
 605         int result;
 606 
 607         char* filename = NEW_C_HEAP_ARRAY(char,
 608                    strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 609 
 610         strcpy(filename, usrdir_name);
 611         strcat(filename, "/");
 612         strcat(filename, udentry->d_name);
 613 
 614         // don't follow symbolic links for the file
 615         RESTARTABLE(::lstat(filename, &statbuf), result);
 616         if (result == OS_ERR) {
 617            FREE_C_HEAP_ARRAY(char, filename);
 618            continue;
 619         }
 620 
 621         // skip over files that are not regular files.


 625         }
 626 
 627         // compare and save filename with latest creation time
 628         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 629 
 630           if (statbuf.st_ctime > oldest_ctime) {
 631             char* user = strchr(dentry->d_name, '_') + 1;
 632 
 633             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 634             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 635 
 636             strcpy(oldest_user, user);
 637             oldest_ctime = statbuf.st_ctime;
 638           }
 639         }
 640 
 641         FREE_C_HEAP_ARRAY(char, filename);
 642       }
 643     }
 644     os::closedir(subdirp);

 645     FREE_C_HEAP_ARRAY(char, usrdir_name);
 646   }
 647   os::closedir(tmpdirp);

 648 
 649   return(oldest_user);
 650 }
 651 
 652 // Determine if the vmid is the parent pid
 653 // for a child in a PID namespace.
 654 // return the namespace pid if so, otherwise -1
 655 static int get_namespace_pid(int vmid) {
 656   char fname[24];
 657   int retpid = -1;
 658 
 659   snprintf(fname, sizeof(fname), "/proc/%d/status", vmid);
 660   FILE *fp = fopen(fname, "r");
 661 
 662   if (fp) {
 663     int pid, nspid;
 664     int ret;
 665     while (!feof(fp)) {
 666       ret = fscanf(fp, "NSpid: %d %d", &pid, &nspid);
 667       if (ret == 1) {


 749 //
 750 static void cleanup_sharedmem_resources(const char* dirname) {
 751 
 752   int saved_cwd_fd;
 753   // open the directory
 754   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 755   if (dirp == NULL) {
 756     // directory doesn't exist or is insecure, so there is nothing to cleanup
 757     return;
 758   }
 759 
 760   // for each entry in the directory that matches the expected file
 761   // name pattern, determine if the file resources are stale and if
 762   // so, remove the file resources. Note, instrumented HotSpot processes
 763   // for this user may start and/or terminate during this search and
 764   // remove or create new files in this directory. The behavior of this
 765   // loop under these conditions is dependent upon the implementation of
 766   // opendir/readdir.
 767   //
 768   struct dirent* entry;


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


 807 }
 808 
 809 // make the user specific temporary directory. Returns true if
 810 // the directory exists and is secure upon return. Returns false
 811 // if the directory exists but is either a symlink, is otherwise
 812 // insecure, or if an error occurred.
 813 //
 814 static bool make_user_tmp_dir(const char* dirname) {
 815 
 816   // create the directory with 0755 permissions. note that the directory
 817   // will be owned by euid::egid, which may not be the same as uid::gid.
 818   //
 819   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 820     if (errno == EEXIST) {
 821       // The directory already exists and was probably created by another
 822       // JVM instance. However, this could also be the result of a
 823       // deliberate symlink. Verify that the existing directory is safe.
 824       //
 825       if (!is_directory_secure(dirname)) {
 826         // directory is not secure


< prev index next >