Fix -fsanitize=address on unreadable inferior strings
authorJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 19 Aug 2014 20:55:10 +0000 (22:55 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 19 Aug 2014 20:55:10 +0000 (22:55 +0200)
echo 'void f(char *s){}main(){f((char *)1);}'|gcc -g -x c -;../gdb ./a.out -ex 'b f' -ex r
====ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000aaccf at pc 0x96eea7 bp 0x7fff75bdbc90 sp 0x7fff75bdbc80
READ of size 1 at 0x6020000aaccf thread T0
    #0 0x96eea6 in extract_unsigned_integer .../gdb/findvar.c:108
    #1 0x9df02b in val_print_string .../gdb/valprint.c:2513
[...]
0x6020000aaccf is located 1 bytes to the left of 8-byte region [0x6020000aacd0,0x6020000aacd8)
allocated by thread T0 here:
    #0 0x7f45fad26b97 in malloc (/lib64/libasan.so.1+0x57b97)
    #1 0xdb3409 in xmalloc common/common-utils.c:45
    #2 0x9d8cf9 in read_string .../gdb/valprint.c:1845
    #3 0x9defca in val_print_string .../gdb/valprint.c:2502
[..]
====ABORTING

gdb/
2014-08-18  Jan Kratochvil  <jan.kratochvil@redhat.com>

Fix -fsanitize=address on unreadable inferior strings.
* valprint.c (val_print_string): Fix access before BUFFER.

gdb/ChangeLog
gdb/valprint.c

index f35ba1b2100765e4cc3db418d76c68b46a53ad32..67049161c260e88ab316ef64e48ca5b81d2ea7e3 100644 (file)
@@ -1,3 +1,8 @@
+2014-08-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix -fsanitize=address on unreadable inferior strings.
+       * valprint.c (val_print_string): Fix access before BUFFER.
+
 2014-08-19  Simon Marchi  <simon.marchi@ericsson.com>
 
        * target.c (target_struct_size): Remove.
index d3ab2675fcf035dd2f18b0f8326a0f7565b1ebe7..a87d67cc785d2250b4f922ca6941fbdd5a050652 100644 (file)
@@ -2510,8 +2510,10 @@ val_print_string (struct type *elttype, const char *encoding,
      LEN is -1.  */
 
   /* Determine found_nul by looking at the last character read.  */
-  found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
-                                       byte_order) == 0;
+  found_nul = 0;
+  if (bytes_read >= width)
+    found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
+                                         byte_order) == 0;
   if (len == -1 && !found_nul)
     {
       gdb_byte *peekbuf;