aboutsummaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@sourceware.org>2024-08-13 21:00:06 -0400
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2024-08-28 15:23:08 -0400
commitdac7a0694b5e853f08be518cd5a133ac5804666d (patch)
treef763adbfdef4a6f6ec8250e9de11ed20656eee08 /stdio-common
parent2f749d2b15cbc82268d7f8735f21ae1e3b68754f (diff)
downloadglibc-dac7a0694b5e853f08be518cd5a133ac5804666d.zip
glibc-dac7a0694b5e853f08be518cd5a133ac5804666d.tar.gz
glibc-dac7a0694b5e853f08be518cd5a133ac5804666d.tar.bz2
ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
When ungetc is called on an unused stream, the backup buffer is allocated without the main get area being present. This results in every subsequent ungetc (as the stream remains in the backup area) checking uninitialized memory in the backup buffer when trying to put a character back into the stream. Avoid comparing the input character with buffer contents when in backup to avoid this uninitialized read. The uninitialized read is harmless in this context since the location is promptly overwritten with the input character, thus fulfilling ungetc functionality. Also adjust wording in the manual to drop the paragraph that says glibc cannot do multiple ungetc back to back since with this change, ungetc can actually do this. Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> Reviewed-by: Carlos O'Donell <carlos@redhat.com> (cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c)
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/tst-ungetc.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
index 5c808f0..388b202 100644
--- a/stdio-common/tst-ungetc.c
+++ b/stdio-common/tst-ungetc.c
@@ -48,6 +48,8 @@ do_test (void)
TEST_VERIFY_EXIT (getc (fp) == 'b');
TEST_VERIFY_EXIT (getc (fp) == 'l');
TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
+ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
+ TEST_VERIFY_EXIT (getc (fp) == 'n');
TEST_VERIFY_EXIT (getc (fp) == 'm');
TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
TEST_VERIFY_EXIT (getc (fp) == EOF);