[llvm] [flang] [flang-rt] Subscript overrun could occur in namelists during a READ command. (PR #176959)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 20 08:20:22 PST 2026


https://github.com/kwyatt-ext created https://github.com/llvm/llvm-project/pull/176959

NOTE: This is a new pull request, as the prior didn't have labels properly applied.

If a bad subscript is provided in a namelisted record, the HandleSubscripts() routine can read off into infinity. This patch ensures that a read will not go beyond the rank of the expected variable.

The failure will then be captured in the return status (IOSTAT) of the READ.

The small test demonstrates the failure before and after the fix.

>From a3eab981c8b33ca67165174fb8a8ddf88130b53c Mon Sep 17 00:00:00 2001
From: Kevin Wyatt <kwyatt at hpe.com>
Date: Fri, 9 Jan 2026 12:55:18 -0600
Subject: [PATCH] Subscript overrun could occur in namelists during a READ
 command.

---
 flang-rt/lib/runtime/namelist.cpp             |  4 +-
 .../test/Runtime/bad_subscript_overrun01.f90  | 50 +++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 flang-rt/test/Runtime/bad_subscript_overrun01.f90

diff --git a/flang-rt/lib/runtime/namelist.cpp b/flang-rt/lib/runtime/namelist.cpp
index e9c0b8ffa2da2..f30e615e8f0fa 100644
--- a/flang-rt/lib/runtime/namelist.cpp
+++ b/flang-rt/lib/runtime/namelist.cpp
@@ -170,7 +170,9 @@ static RT_API_ATTRS bool HandleSubscripts(IoStatementState &io,
   std::size_t byteCount{0};
   common::optional<char32_t> ch{io.GetNextNonBlank(byteCount)};
   char32_t comma{GetComma(io)};
-  for (; ch && *ch != ')'; ++j) {
+
+  // Read subscripts, but don't exceed rank to prevent buffer overrun.
+  for (int Rank = source.rank(); ch && *ch != ')' && j <= Rank; ++j) {
     SubscriptValue dimLower{0}, dimUpper{0}, dimStride{0};
     if (j < maxRank && j < source.rank()) {
       const Dimension &dim{source.GetDimension(j)};
diff --git a/flang-rt/test/Runtime/bad_subscript_overrun01.f90 b/flang-rt/test/Runtime/bad_subscript_overrun01.f90
new file mode 100644
index 0000000000000..70cc84b168bab
--- /dev/null
+++ b/flang-rt/test/Runtime/bad_subscript_overrun01.f90
@@ -0,0 +1,50 @@
+! Test a buffer overrun when an illegal vector-valued subscript is used in
+! namelist input.
+! The error should be reported through the READ's IOSTAT value.
+! RUN: %flang -L"%libdir" %s -o %t
+! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s
+! CHECK-NOT: FAIL
+
+PROGRAM bad_subscript_overrun01
+  IMPLICIT NONE
+
+  INTEGER,DIMENSION(5)                :: U, EXPECTU
+  INTEGER,DIMENSION(5)                :: V, EXPECTV
+  CHARACTER(LEN=20)                   :: NAMELIST_RECORD
+  INTEGER                             :: IOS, ILOOP
+
+  NAMELIST /SCORES/ U
+  NAMELIST /CHTEST/ NAMELIST_RECORD
+
+  U = 8
+  EXPECTU = U
+  V = 9
+  EXPECTV = V
+  IOS = 0
+
+  NAMELIST_RECORD = " &SCORES U(V) = -1 /"
+  OPEN(UNIT=10, ACCESS='SEQUENTIAL', ACTION='READWRITE')
+  WRITE(10,'(A)') NAMELIST_RECORD
+  REWIND 10
+
+  ! This should fail because of the bad index.
+  READ(10, NML = SCORES, IOSTAT=IOS)
+  CLOSE(UNIT=10, STATUS='KEEP')
+
+  ! Make sure the READ status was a failure.
+  IF(IOS.NE.0) THEN
+    PRINT *, "Test 1 - PASS"
+  ELSE
+    print *, "Test 1 - FAIL"
+  ENDIF
+
+  ! Make sure the values of the array haven't changed.
+  DO ILOOP = 1,5
+    IF(U(ILOOP).EQ.EXPECTU(ILOOP)) THEN
+      PRINT *, "Test 2 - PASS"
+    ELSE
+      PRINT *, "Test 2 - FAIL"
+    ENDIF
+  ENDDO
+
+END PROGRAM bad_subscript_overrun01



More information about the llvm-commits mailing list