bug-gnulib
[Top][All Lists]
Advanced

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

write past end of buffer in vasnprintf() implementation of %f


From: Ben Pfaff
Subject: write past end of buffer in vasnprintf() implementation of %f
Date: Sat, 22 Sep 2018 22:33:36 -0700
User-agent: Mutt/1.5.23 (2014-03-12)

When I apply the following patch to gnulib:

----------------------------------------------------------------------
diff --git a/tests/test-vasnprintf.c b/tests/test-vasnprintf.c
index 19731bc93378..105ac24c94a3 100644
--- a/tests/test-vasnprintf.c
+++ b/tests/test-vasnprintf.c
@@ -59,6 +59,11 @@ test_function (char * (*my_asnprintf) (char *, size_t *, 
const char *, ...))
       if (result != buf)
         free (result);
     }
+
+  size_t length = 8;
+  char *result = my_asnprintf (buf, &length, "%2.0f", 0x1.e38417c792296p+893);
+  if (result != buf)
+    free (result);
 }
 
 static char *
----------------------------------------------------------------------

and then run:

CC='gcc -fsanitize=address -g -O0' ./gnulib-tool --test vasnprintf 
vasnprintf-posix

I get the following failure from test-vasnprintf:

----------------------------------------------------------------------
==17880==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4b03ece at 
pc 0xf770f8ed bp 0xffac9638 sp 0xffac962c
WRITE of size 1 at 0xf4b03ece thread T0
    #0 0xf770f8ec in convert_to_decimal ../../gllib/vasnprintf.c:899
    #1 0xf770f8ec in scale10_round_decimal_decoded ../../gllib/vasnprintf.c:1292
    #2 0xf771057c in scale10_round_decimal_double ../../gllib/vasnprintf.c:1328
    #3 0xf771755c in vasnprintf ../../gllib/vasnprintf.c:4119
    #4 0xf770c692 in my_asnprintf ../../gltests/test-vasnprintf.c:76
    #5 0xf770ca39 in test_function ../../gltests/test-vasnprintf.c:64
    #6 0xf770c384 in test_vasnprintf ../../gltests/test-vasnprintf.c:84
    #7 0xf770c384 in main ../../gltests/test-vasnprintf.c:96
    #8 0xf6f2be80 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18e80)
    #9 0xf770c4de  
(/home/blp/pspp/gnulib2/testdir21347/build/gltests/test-vasnprintf+0x14de)

0xf4b03ece is located 0 bytes to the right of 270-byte region 
[0xf4b03dc0,0xf4b03ece)
allocated by thread T0 here:
    #0 0xf71cc334 in malloc (/usr/lib/i386-linux-gnu/libasan.so.4+0xe0334)
    #1 0xf770f223 in convert_to_decimal ../../gllib/vasnprintf.c:863
    #2 0xf770f223 in scale10_round_decimal_decoded ../../gllib/vasnprintf.c:1292

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../gllib/vasnprintf.c:899 in 
convert_to_decimal
Shadow bytes around the buggy address:
  0x3e960780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e960790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9607a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9607b0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x3e9607c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x3e9607d0: 00 00 00 00 00 00 00 00 00[06]fa fa fa fa fa fa
  0x3e9607e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9607f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e960800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e960810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e960820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==17880==ABORTING
FAIL test-vasnprintf (exit status: 1)
----------------------------------------------------------------------

The line in convert_to_decimal() cited above is the assignment here:

      /* Terminate the string.  */
      *d_ptr = '\0';

I guess that the space calculation passed to malloc() at the top of the
same function is not precise.  I don't know whether the right thing to
do is to just add one.

This bug was originally reported against GNU PSPP:
        https://savannah.gnu.org/bugs/?func=detailitem&item_id=54686

For this report, I've simplified it to remove the PSPP dependency (and
to make sure it isn't somehow a PSPP bug).

I'd appreciate it if someone more familiar with this part of the
vasnprintf() code, which seems rather opaque to a newcomer, would
investigate this.  Bruno, you're the main committer to this file, so I'm
guessing that's you, hence the CC.

Thanks a lot!



reply via email to

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