bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fflush: Fix a buffer overrun on 32-bit Android


From: Bruno Haible
Subject: fflush: Fix a buffer overrun on 32-bit Android
Date: Tue, 17 Jan 2023 19:25:32 +0100

On Android, I see a test failure:

FAIL: test-yesno.sh
===================

test-yesno: write error: Bad address
test-yesno: write error: Bad address
xout.tmp out.tmp differ: char 1, line 1
test-yesno: write error: Bad address
test-yesno: write error: Bad address
xout.tmp out.tmp differ: char 1, line 1
test-yesno: write error: Bad address
cmp: EOF on out.tmp which is empty
FAIL test-yesno.sh (exit status: 1)

The cause is that
  - This test uses atexit (close_stdin);
  - close_stdin calls fflush (stdin). This uses the Gnulib replacement for
    fflush. In function update_fpos_cache it overwrites a word of memory
    past *stdin. Namely the first word of *stdout.
  - Then, close_stdin calls close_stdout, which calls close_stream (stdout),
    which calls __fpending (stdout). Since *stdout is not in a valid state,
    __fpending (stdout) returns a huge value, rather than 0.
  - close_stream then goes along a wrong control path.

This patch fixes it.


2023-01-17  Bruno Haible  <bruno@clisp.org>

        fflush: Fix a buffer overrun on 32-bit Android.
        * lib/stdio-impl.h (fp_): On Android, change the type of _offset to
        'long'.
        * lib/fflush.c (update_fpos_cache): On Android, update a 'long', not an
        'fpos_t'.

diff --git a/lib/fflush.c b/lib/fflush.c
index d38f5f00a3..f3689b3e81 100644
--- a/lib/fflush.c
+++ b/lib/fflush.c
@@ -99,7 +99,7 @@ update_fpos_cache (_GL_ATTRIBUTE_MAYBE_UNUSED FILE *fp,
 {
 #  if defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
-#   if defined __CYGWIN__
+#   if defined __CYGWIN__ || defined __ANDROID__
   /* fp_->_offset is typed as an integer.  */
   fp_->_offset = pos;
 #   else
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
index 81e7f83837..89056b0de5 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -96,7 +96,7 @@
                          unsigned char _nbuf[1]; \
                          struct { unsigned char *_base; size_t _size; } _lb; \
                          int _blksize; \
-                         fpos_t _offset; \
+                         long _offset; \
                          /* More fields, not relevant here.  */ \
                        } *) fp)
 # else






reply via email to

[Prev in Thread] Current Thread [Next in Thread]