Hi

Vim-7.4.802 accesses invalid memory when doing:

$ vim -u NONE -S crash.vim

... where crash.vim is the attached file which contains:

  call setreg('"',"")
  let k = getreg('"')
  let r = getregtype('"')
  call setreg('#',k,r)

Crash happens at fileio.c:10213

10212     endp = pat_end - 1;
10213     if (*endp == '*')

When bug happens, pat_end and pat are identical (pat is an empty string).
so endp points to one byte before the allocated block at fileio.c:10213.

Attached fixes it, but I don't know whether pat should have
been an empty string in the first place.  So maybe the patch
is hiding another bug.

Bug was found by fuzzing with afl-fuzz + asan.  Here is asan report:

=================================================================
==16314== ERROR: AddressSanitizer: heap-buffer-overflow on address
0x600400017dcf at pc 0x561f12 bp 0x7fffb9383af0 sp 0x7fffb9383ae8
READ of size 1 at 0x600400017dcf thread T0
    #0 0x561f11 in file_pat_to_reg_pat /home/dope/sb/vim/src/fileio.c:10213:0
    #1 0x40c35f in buflist_findpat /home/dope/sb/vim/src/buffer.c:2261:0
    #2 0x67e7bb in write_reg_contents_ex /home/dope/sb/vim/src/ops.c:6663:0
    #3 0x49a3c3 in f_setreg /home/dope/sb/vim/src/eval.c:17433:0
    #4 0x479e2e in call_func /home/dope/sb/vim/src/eval.c:8773:0
    #5 0x478eae in get_func_tv /home/dope/sb/vim/src/eval.c:8573:0
    #6 0x4666a0 in ex_call /home/dope/sb/vim/src/eval.c:3516:0
    #7 0x4f7e99 in do_one_cmd /home/dope/sb/vim/src/ex_docmd.c:2941:0
    #8 0x4eec56 in do_cmdline /home/dope/sb/vim/src/ex_docmd.c:1133:0
    #9 0x4ea664 in do_source /home/dope/sb/vim/src/ex_cmds2.c:3353:0
    #10 0x4e9302 in cmd_source /home/dope/sb/vim/src/ex_cmds2.c:2962:0
    #11 0x4e914e in ex_source /home/dope/sb/vim/src/ex_cmds2.c:2935:0
    #12 0x4f7e99 in do_one_cmd /home/dope/sb/vim/src/ex_docmd.c:2941:0
    #13 0x4eec56 in do_cmdline /home/dope/sb/vim/src/ex_docmd.c:1133:0
    #14 0x4edc1b in do_cmdline_cmd /home/dope/sb/vim/src/ex_docmd.c:738:0
    #15 0x850840 in exe_commands /home/dope/sb/vim/src/main.c:2926:0
    #16 0x84a9ea in main /home/dope/sb/vim/src/main.c:961:0
    #17 0x7f584d350ec4 in __libc_start_main
/build/buildd/eglibc-2.19/csu/libc-start.c:287:0
    #18 0x405a28 in _start ??:0:0
0x600400017dcf is located 1 bytes to the left of 1-byte region
[0x600400017dd0,0x600400017dd1)
allocated by thread T0 here:
    #0 0x7f584ee2d41a in malloc ??:0:0
    #1 0x605a66 in lalloc /home/dope/sb/vim/src/misc2.c:921:0
    #2 0x605870 in alloc /home/dope/sb/vim/src/misc2.c:820:0
    #3 0x605bbb in vim_strsave /home/dope/sb/vim/src/misc2.c:1246:0
    #4 0x4ac77e in copy_tv /home/dope/sb/vim/src/eval.c:21854:0
    #5 0x4a8c55 in get_var_tv /home/dope/sb/vim/src/eval.c:20844:0
    #6 0x46d8cb in eval7 /home/dope/sb/vim/src/eval.c:5260:0
    #7 0x46c3f7 in eval6 /home/dope/sb/vim/src/eval.c:4887:0
    #8 0x46b927 in eval5 /home/dope/sb/vim/src/eval.c:4703:0
    #9 0x469ea1 in eval4 /home/dope/sb/vim/src/eval.c:4396:0
    #10 0x469ac5 in eval3 /home/dope/sb/vim/src/eval.c:4308:0
    #11 0x469728 in eval2 /home/dope/sb/vim/src/eval.c:4237:0
    #12 0x469328 in eval1 /home/dope/sb/vim/src/eval.c:4162:0
    #13 0x478d89 in get_func_tv /home/dope/sb/vim/src/eval.c:8558:0
    #14 0x4666a0 in ex_call /home/dope/sb/vim/src/eval.c:3516:0
    #15 0x4f7e99 in do_one_cmd /home/dope/sb/vim/src/ex_docmd.c:2941:0
    #16 0x4eec56 in do_cmdline /home/dope/sb/vim/src/ex_docmd.c:1133:0
    #17 0x4ea664 in do_source /home/dope/sb/vim/src/ex_cmds2.c:3353:0
    #18 0x4e9302 in cmd_source /home/dope/sb/vim/src/ex_cmds2.c:2962:0
    #19 0x4e914e in ex_source /home/dope/sb/vim/src/ex_cmds2.c:2935:0
    #20 0x4f7e99 in do_one_cmd /home/dope/sb/vim/src/ex_docmd.c:2941:0
    #21 0x4eec56 in do_cmdline /home/dope/sb/vim/src/ex_docmd.c:1133:0
    #22 0x4edc1b in do_cmdline_cmd /home/dope/sb/vim/src/ex_docmd.c:738:0
    #23 0x850840 in exe_commands /home/dope/sb/vim/src/main.c:2926:0
    #24 0x84a9ea in main /home/dope/sb/vim/src/main.c:961:0
    #25 0x7f584d350ec4 in __libc_start_main
/build/buildd/eglibc-2.19/csu/libc-start.c:287:0
Shadow bytes around the buggy address:
  0x0c00ffffaf60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffffaf70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffffaf80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffffaf90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffffafa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 03 fa
=>0x0c00ffffafb0: fa fa 07 fa fa fa 02 fa fa[fa]01 fa fa fa 02 fa
  0x0c00ffffafc0: fa fa 07 fa fa fa 02 fa fa fa fd fd fa fa fd fa
  0x0c00ffffafd0: fa fa 01 fa fa fa fd fa fa fa fd fa fa fa 01 fa
  0x0c00ffffafe0: fa fa 00 fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c00ffffaff0: fa fa fd fa fa fa 00 05 fa fa 05 fa fa fa 00 00
  0x0c00ffffb000: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
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
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==16314== ABORTING

Regards
Dominique

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Attachment: crash.vim
Description: Binary data

diff -r 589a962ecc16 src/fileio.c
--- a/src/fileio.c	Tue Jul 28 17:16:33 2015 +0200
+++ b/src/fileio.c	Tue Jul 28 18:32:04 2015 +0200
@@ -10210,7 +10210,7 @@
     else
 	reg_pat[i++] = '^';
     endp = pat_end - 1;
-    if (*endp == '*')
+    if (endp - pat >= 0 && *endp == '*')
     {
 	while (endp - pat > 0 && *endp == '*')
 	    endp--;

Raspunde prin e-mail lui