7153347: System read/stat/open calls should be hardened to handle EINTR
authornishjain
Tue, 02 Aug 2016 10:31:05 +0900
changeset 39893 56745139718c
parent 39892 4418a310ddbb
child 39894 cd4f403f9618
7153347: System read/stat/open calls should be hardened to handle EINTR Reviewed-by: okutsu
jdk/src/java.base/unix/native/libjava/TimeZone_md.c
--- a/jdk/src/java.base/unix/native/libjava/TimeZone_md.c	Mon Aug 01 18:14:06 2016 -0700
+++ b/jdk/src/java.base/unix/native/libjava/TimeZone_md.c	Tue Aug 02 10:31:05 2016 +0900
@@ -44,6 +44,12 @@
 
 #define SKIP_SPACE(p)   while (*p == ' ' || *p == '\t') p++;
 
+#define RESTARTABLE(_cmd, _result) do { \
+  do { \
+    _result = _cmd; \
+  } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
 #if defined(_ALLBSD_SOURCE)
 #define dirent64 dirent
 #define readdir64_r readdir_r
@@ -121,6 +127,7 @@
     int fd = -1;
     char *dbuf = NULL;
     char *tz = NULL;
+    int res;
 
     dirp = opendir(dir);
     if (dirp == NULL) {
@@ -161,7 +168,8 @@
         if (pathname == NULL) {
             break;
         }
-        if (stat(pathname, &statbuf) == -1) {
+        RESTARTABLE(stat(pathname, &statbuf), res);
+        if (res == -1) {
             break;
         }
 
@@ -175,10 +183,12 @@
             if (dbuf == NULL) {
                 break;
             }
-            if ((fd = open(pathname, O_RDONLY)) == -1) {
+            RESTARTABLE(open(pathname, O_RDONLY), fd);
+            if (fd == -1) {
                 break;
             }
-            if (read(fd, dbuf, size) != (ssize_t) size) {
+            RESTARTABLE(read(fd, dbuf, size), res);
+            if (res != (ssize_t) size) {
                 break;
             }
             if (memcmp(buf, dbuf, size) == 0) {
@@ -230,6 +240,7 @@
     int fd;
     char *buf;
     size_t size;
+    int res;
 
 #if defined(__linux__)
     /*
@@ -260,7 +271,8 @@
     /*
      * Next, try /etc/localtime to find the zone ID.
      */
-    if (lstat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
+    RESTARTABLE(lstat(DEFAULT_ZONEINFO_FILE, &statbuf), res);
+    if (res == -1) {
         return NULL;
     }
 
@@ -294,10 +306,13 @@
      * If initial symbolic link resolution failed, we should treat target
      * file as a regular file.
      */
-    if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
+    RESTARTABLE(open(DEFAULT_ZONEINFO_FILE, O_RDONLY), fd);
+    if (fd == -1) {
         return NULL;
     }
-    if (fstat(fd, &statbuf) == -1) {
+
+    RESTARTABLE(fstat(fd, &statbuf), res);
+    if (res == -1) {
         (void) close(fd);
         return NULL;
     }
@@ -308,7 +323,8 @@
         return NULL;
     }
 
-    if (read(fd, buf, size) != (ssize_t) size) {
+    RESTARTABLE(read(fd, buf, size), res);
+    if (res != (ssize_t) size) {
         (void) close(fd);
         free((void *) buf);
         return NULL;
@@ -372,7 +388,8 @@
     /*
      * It assumes read open.
      */
-    if ((fd = open(fname, O_RDONLY)) == -1) {
+    RESTARTABLE(open(fname, O_RDONLY), fd);
+    if (fd == -1) {
         return NULL;
     }
 
@@ -420,7 +437,8 @@
         if (iop->ptr == iop->endptr) {
             ssize_t len;
 
-            if ((len = read(iop->fd, (void *)iop->buffer, BUFFER_SIZE)) == -1) {
+            RESTARTABLE(read(iop->fd, (void *)iop->buffer, BUFFER_SIZE), len);
+            if (len == -1) {
                 return NULL;
             }
             if (len == 0) {
@@ -558,6 +576,7 @@
     size_t size;
     char *buf;
     int fd;
+    int res;
     /* scf specific variables */
     scf_handle_t *h = NULL;
     scf_snapshot_t *snap = NULL;
@@ -593,7 +612,8 @@
     }
     cleanupScf(h, snap, inst, pg, prop, val, tz);
 
-    if (stat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
+    RESTARTABLE(stat(DEFAULT_ZONEINFO_FILE, &statbuf), res);
+    if (res == -1) {
         return NULL;
     }
     size = (size_t) statbuf.st_size;
@@ -601,12 +621,14 @@
     if (buf == NULL) {
         return NULL;
     }
-    if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
+    RESTARTABLE(open(DEFAULT_ZONEINFO_FILE, O_RDONLY), fd);
+    if (fd == -1) {
         free((void *) buf);
         return NULL;
     }
 
-    if (read(fd, buf, size) != (ssize_t) size) {
+    RESTARTABLE(read(fd, buf, size), res);
+    if (res != (ssize_t) size) {
         (void) close(fd);
         free((void *) buf);
         return NULL;