[libgfortran] Fix uninitialized variable use in fallback_access
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Fri, 14 Sep 2018 09:22:01 +0000 (09:22 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Fri, 14 Sep 2018 09:22:01 +0000 (09:22 +0000)
I've been tracking down a bug in a Fortran program on a newlib target and it boils down to fallback_access doing something bad.
The unconditional calls to close cause havoc when open doesn't get called due to the short-circuiting in the if-statement above
because the fd is uninitialised. In my environment GCC ends up calling close on file descriptor 0, thus trying to close stdin.

This patch tightens up the calling so that close is called only when the corresponding open call succeeded.
With this my runtime failure disappears.

Bootstrapped and tested on aarch64-none-linux-gnu.
Though that doesn't exercise this call I hope it's an obviously correct change.

* io/unix.c (fallback_access): Avoid calling close on
uninitialized file descriptor.

From-SVN: r264305

libgfortran/ChangeLog
libgfortran/io/unix.c

index 1120d30fd2a695044fce8e209ac2df11ad496cef..56828b1bee5c8cdb056f39709ac1d518e7c7c23d 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * io/unix.c (fallback_access): Avoid calling close on
+       uninitialized file descriptor.
+
 2018-09-12  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        * runtime/minimal.c (estr_write): Define in terms of write.
index 4a133fd44bd20d2e8424e0990dfc9c92b875a074..ad2577c44a9432db2a83ef3d2f474b04b9d7d70c 100644 (file)
@@ -150,13 +150,21 @@ fallback_access (const char *path, int mode)
 {
   int fd;
 
-  if ((mode & R_OK) && (fd = open (path, O_RDONLY)) < 0)
-    return -1;
-  close (fd);
+  if (mode & R_OK)
+    {
+      if ((fd = open (path, O_RDONLY)) < 0)
+       return -1;
+      else
+       close (fd);
+    }
 
-  if ((mode & W_OK) && (fd = open (path, O_WRONLY)) < 0)
-    return -1;
-  close (fd);
+  if (mode & W_OK)
+    {
+      if ((fd = open (path, O_WRONLY)) < 0)
+       return -1;
+      else
+       close (fd);
+    }
 
   if (mode == F_OK)
     {