< prev index next >

src/java.base/unix/native/libjava/TimeZone_md.c

Print this page
rev 15588 : 8165936: Potential Heap buffer overflow when seaching timezone info files
Summary: readdir_r called with too small buffer
Reviewed-by: clanger, rriggs, okutsu, naoto


 111 
 112 /*
 113  * Scans the specified directory and its subdirectories to find a
 114  * zoneinfo file which has the same content as /etc/localtime on Linux
 115  * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
 116  * If file is symbolic link, then the contents it points to are in buf.
 117  * Returns a zone ID if found, otherwise, NULL is returned.
 118  */
 119 static char *
 120 findZoneinfoFile(char *buf, size_t size, const char *dir)
 121 {
 122     DIR *dirp = NULL;
 123     struct stat statbuf;
 124     struct dirent64 *dp = NULL;
 125     struct dirent64 *entry = NULL;
 126     char *pathname = NULL;
 127     int fd = -1;
 128     char *dbuf = NULL;
 129     char *tz = NULL;
 130     int res;

 131 
 132     dirp = opendir(dir);
 133     if (dirp == NULL) {
 134         return NULL;
 135     }
 136 
 137     entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));












 138     if (entry == NULL) {
 139         (void) closedir(dirp);
 140         return NULL;
 141     }
 142 
 143     while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
 144         /*
 145          * Skip '.' and '..' (and possibly other .* files)
 146          */
 147         if (dp->d_name[0] == '.') {
 148             continue;
 149         }
 150 
 151         /*
 152          * Skip "ROC", "posixrules", and "localtime".
 153          */
 154         if ((strcmp(dp->d_name, "ROC") == 0)
 155             || (strcmp(dp->d_name, "posixrules") == 0)
 156 #if defined(__solaris__)
 157             /*




 111 
 112 /*
 113  * Scans the specified directory and its subdirectories to find a
 114  * zoneinfo file which has the same content as /etc/localtime on Linux
 115  * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
 116  * If file is symbolic link, then the contents it points to are in buf.
 117  * Returns a zone ID if found, otherwise, NULL is returned.
 118  */
 119 static char *
 120 findZoneinfoFile(char *buf, size_t size, const char *dir)
 121 {
 122     DIR *dirp = NULL;
 123     struct stat statbuf;
 124     struct dirent64 *dp = NULL;
 125     struct dirent64 *entry = NULL;
 126     char *pathname = NULL;
 127     int fd = -1;
 128     char *dbuf = NULL;
 129     char *tz = NULL;
 130     int res;
 131     long name_max = 0;
 132 
 133     dirp = opendir(dir);
 134     if (dirp == NULL) {
 135         return NULL;
 136     }
 137 
 138     name_max = pathconf(dir, _PC_NAME_MAX);
 139     // If pathconf did not work, fall back to NAME_MAX.
 140     if (name_max < 0) {
 141         name_max = NAME_MAX;
 142     }
 143     // Some older System V systems have a very small NAME_MAX size of 14; as
 144     // there is no way to tell readdir_r the output buffer size, lets enforce
 145     // a mimimum buffer size.
 146     if (name_max < 1024) {
 147         name_max = 1024;
 148     }
 149 
 150     entry = (struct dirent64 *)malloc(offsetof(struct dirent64, d_name) + name_max + 1);
 151     if (entry == NULL) {
 152         (void) closedir(dirp);
 153         return NULL;
 154     }
 155 
 156     while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
 157         /*
 158          * Skip '.' and '..' (and possibly other .* files)
 159          */
 160         if (dp->d_name[0] == '.') {
 161             continue;
 162         }
 163 
 164         /*
 165          * Skip "ROC", "posixrules", and "localtime".
 166          */
 167         if ((strcmp(dp->d_name, "ROC") == 0)
 168             || (strcmp(dp->d_name, "posixrules") == 0)
 169 #if defined(__solaris__)
 170             /*


< prev index next >