From 194a2884f21a6fc02c446ca4e2dc9107298832db Mon Sep 17 00:00:00 2001
From: "Arnold D. Robbins" <arnold@skeeve.com>
Date: Fri, 3 Apr 2026 12:02:11 +0300
Subject: [PATCH] Small memory management fix in io.c.

CVE: CVE-2026-40467
Upstream-Status: Backport [https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=a2d18c74109e41bec29a23098eba2e00057286d8]

(cherry picked from commit a2d18c74109e41bec29a23098eba2e00057286d8)
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
 ChangeLog | 6 ++++++
 io.c      | 5 ++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index a714ca1a..517aba91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-04-03         Arnold D. Robbins     <arnold@skeeve.com>
+
+	* io.c (do_getline_redir): Don't DEREF redir_exp too early.
+	Thanks to Michał Majchrowicz <mmajchrowicz@afine.com>
+	for the report.
+
 2026-02-22         Arnold D. Robbins     <arnold@skeeve.com>
 
 	* 5.4.0: Release tar ball made.
diff --git a/io.c b/io.c
index a3b877c4..7a547aa1 100644
--- a/io.c
+++ b/io.c
@@ -2853,21 +2853,24 @@ do_getline_redir(int into_variable, enum redirval redirtype)
 	redir_exp = TOP();
 	redir_exp = elem_new_to_scalar(redir_exp);
 	rp = redirect(redir_exp, redirtype, & redir_error, false);
-	DEREF(redir_exp);
 	decr_sp();
 	if (rp == NULL) {
 		if (redir_error) { /* failed redirect */
 			update_ERRNO_int(redir_error);
 		}
+		DEREF(redir_exp);
 		return make_number((AWKNUM) -1.0);
 	} else if ((rp->flag & RED_TWOWAY) != 0 && rp->iop == NULL) {
 		if (is_non_fatal_redirect(redir_exp->stptr, redir_exp->stlen)) {
 			update_ERRNO_int(EBADF);
+			DEREF(redir_exp);
 			return make_number((AWKNUM) -1.0);
 		}
 		(void) close_rp(rp, CLOSE_ALL);
+		DEREF(redir_exp);	// we're about to die, but what the heck, release it anyway
 		fatal(_("getline: attempt to read from closed read end of two-way pipe"));
 	}
+	DEREF(redir_exp);
 	iop = rp->iop;
 	if (iop == NULL)		/* end of input */
 		return make_number((AWKNUM) 0.0);
-- 
2.53.0

