[PATCH] input: Fix heap buffer overflow in preadbuffer for non-SMALL builds

Daniel Snider <[email protected]> Sun, 22 Feb 2026 05:09:10 -0600
Newsgroups org.kernel.vger.dash
Message-ID <CAB_UPCCnoM-7oU=u51jCDGarLPTM5TzYWVSfhqWHaQP0BFpotQ@mail.gmail.com>
From 0242b3e94da8de5043d5b2a8fba2f380347f6eaf Mon Sep 17 00:00:00 2001
From: Daniel Snider <[email protected]>
Date: Fri, 20 Feb 2026 20:37:21 -0600
Subject: [PATCH] input: Fix heap buffer overflow in preadbuffer for non-SMALL
 builds

Commit a065467 ("input: Move newline loop into preadbuffer") removed a
guard that prevented looping back to preadfd when no more characters
remain in the buffer.  In non-SMALL builds (with libedit), this causes
preadbuffer to call preadfd again without resynchronising the buffer
pointer, overwriting heap memory past the allocated IBUFSIZ input buffer.

Any single-line shell input longer than IBUFSIZ (~8 KB) triggers a heap
buffer overflow that corrupts glibc malloc metadata, resulting in
SIGABRT or SIGSEGV.

Reproducer (requires --with-libedit build):

  { printf 'export X='; head -c 16000 /dev/zero | tr '\0' A; echo; } > /tmp/t.sh
  dash -c '. /tmp/t.sh'

Restore the guard so that "goto again" only fires when no characters
have been consumed from the current buffer (q == parsefile->nextc),
matching the pre-a065467 behaviour.

Signed-off-by: Daniel Snider <[email protected]>
---
 src/input.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/input.c b/src/input.c
index c36d120..c0f5a9f 100644
--- a/src/input.c
+++ b/src/input.c
@@ -429,7 +429,7 @@ again:

 check:
         if (more <= 0) {
-            if (!IS_DEFINED_SMALL)
+            if (!IS_DEFINED_SMALL && q == parsefile->nextc)
                 goto again;
             break;
         }
--
2.53.0