]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran: Fix runtime segfault closing negative unit
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 13 Apr 2025 02:51:23 +0000 (19:51 -0700)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 13 Apr 2025 15:39:32 +0000 (08:39 -0700)
When closing a UNIT with an invalid negative unit
number, a segfault ensued. This patch adds checks
for these conditions and issues errors.

PR libfortran/119502

libgfortran/ChangeLog:

* io/close.c (st_close): Issue an error and avoid
calling close_share when there is no stream assigned.
* io/open.c (st_open): If there is no stream assigned
to the unit, unlock the unit and issue an error.

gcc/testsuite/ChangeLog:

* gfortran.dg/pr119502.f90: New test.

gcc/testsuite/gfortran.dg/pr119502.f90 [new file with mode: 0644]
libgfortran/io/close.c
libgfortran/io/open.c

diff --git a/gcc/testsuite/gfortran.dg/pr119502.f90 b/gcc/testsuite/gfortran.dg/pr119502.f90
new file mode 100644 (file)
index 0000000..80d7c61
--- /dev/null
@@ -0,0 +1,15 @@
+! { dg-do run }
+
+! PR119502, negative unit numbers are not allowed without using NEWUNIT
+
+program foo
+  integer :: iun = -1
+  integer :: ios
+  open (iun, iostat=ios)
+  if (ios == 0) stop 1
+  write(iun,*, iostat=ios) "This is a test."
+  if (ios == 0) stop 2
+  close (iun, iostat=ios)
+  if (ios == 0) stop 3
+end
+
index 81223113dc5df0326f03a214e0bb4bb5e5e992ce..41d278c002c68db2fdd5a2e8b20974f50618344b 100644 (file)
@@ -84,8 +84,17 @@ st_close (st_parameter_close *clp)
 
   if (u != NULL)
     {
-      if (close_share (u) < 0)
-       generate_error (&clp->common, LIBERROR_OS, "Problem in CLOSE");
+      if (u->s == NULL)
+       {
+         if (u->unit_number < 0)
+           generate_error (&clp->common, LIBERROR_BAD_UNIT,
+                           "Unit number is negative with no associated file");
+         library_end ();
+         return;
+       }
+      else
+       if (close_share (u) < 0)
+         generate_error (&clp->common, LIBERROR_OS, "Problem in CLOSE");
       if (u->flags.status == STATUS_SCRATCH)
        {
          if (status == CLOSE_KEEP)
index 06ddf7f4dc28295efff37eb8920c760622b8da1e..e9fb0a7b3b05a397ff9aff52d7b4a6471b6df66b 100644 (file)
@@ -912,6 +912,16 @@ st_open (st_parameter_open *opp)
              library_end ();
              return;
            }
+
+         if (u->s == NULL)
+           {
+             unlock_unit (u);
+             generate_error (&opp->common, LIBERROR_BAD_OPTION,
+                       "Unit number is negative and unit was not already "
+                       "opened with OPEN(NEWUNIT=...)");
+             library_end ();
+             return;
+           }
        }
 
       if (u == NULL)