Hi

Vim-7.4.729 accesses invalid memory (global overflow) when doing:

$ vim -u NONE -c 'set re=1' \
  -c 'e ++enc=utf8 ++bad=keep crash-5' \
  -c 'call search(getline("."))'

... where crash-5 is the attached file (8 bytes).

Asan reports:

==5792==ERROR: AddressSanitizer: global-buffer-overflow on address
0x0000011f58e7 at pc 0xafd150 bp 0x7ffcc79a6ee0 sp 0x7ffcc79a6ed8
READ of size 1 at 0x0000011f58e7 thread T0
    #0 0xafd14f in utf_head_off /home/pel/sb/vim/src/mbyte.c:3514
    #1 0xd978ad in regmatch /home/pel/sb/vim/src/regexp.c:5588
    #2 0xd978ad in regtry /home/pel/sb/vim/src/regexp.c:4099
    #3 0xd9d845 in bt_regexec_both /home/pel/sb/vim/src/regexp.c:3988
    #4 0xdc439a in vim_regexec_multi /home/pel/sb/vim/src/regexp.c:8275
    #5 0xe87449 in searchit /home/pel/sb/vim/src/search.c:639
    #6 0x593533 in search_cmn /home/pel/sb/vim/src/eval.c:16366
    #7 0x593533 in f_search /home/pel/sb/vim/src/eval.c:16516
    #8 0x611d47 in call_func /home/pel/sb/vim/src/eval.c:8765
    #9 0x63e3dc in get_func_tv /home/pel/sb/vim/src/eval.c:8565
    #10 0x65ac39 in ex_call /home/pel/sb/vim/src/eval.c:3510
    #11 0x75aa1d in do_one_cmd /home/pel/sb/vim/src/ex_docmd.c:2940
    #12 0x77016d in do_cmdline /home/pel/sb/vim/src/ex_docmd.c:1133
    #13 0x4237c6 in exe_commands /home/pel/sb/vim/src/main.c:2922
    #14 0x4237c6 in main /home/pel/sb/vim/src/main.c:958
    #15 0x7fca25193ec4 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #0 0x42a5e9 in _start ??:?

0x0000011f58e7 is located 57 bytes to the left of global variable
'*.LC18' from 'regexp.c' (0x11f5920) of size 2
  '*.LC18' is ascii string '\'
0x0000011f58e7 is located 6 bytes to the right of global variable
'*.LC17' from 'regexp.c' (0x11f58e0) of size 1
  '*.LC17' is ascii string ''
SUMMARY: AddressSanitizer: global-buffer-overflow
/home/pel/sb/vim/src/mbyte.c:3514 utf_head_off
Shadow bytes around the buggy address:
  0x000080236ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x000080236b10: 00 00 00 00 00 00 00 00 00 00 00 00[01]f9 f9 f9
  0x000080236b20: f9 f9 f9 f9 02 f9 f9 f9 f9 f9 f9 f9 00 00 00 06
  0x000080236b30: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080236b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 right 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
  Contiguous container OOB:fc
  ASan internal:           fe
==5792==ABORTING


Code in regexp.c:5588

5583                     else
5584                     {
5585 #ifdef FEAT_MBYTE
5586                         if (has_mbyte)
5587                             rp->rs_un.regsave.rs_u.pos.col -=
5588                                 (*mb_head_off)(regline, regline
5589                                     +
rp->rs_un.regsave.rs_u.pos.col - 1) + 1;
5590                         else
5591 #endif

When bug happens:

*  rp->rs_un.regsave.rs_u.pos.col - 1  is equal to 7
* regline is an empty string which has been set by
reg_getline() at line 3718:

 3708     static char_u *
 3709 reg_getline(lnum)
 3710     linenr_T    lnum;
 3711 {
 3712     /* when looking behind for a match/no-match lnum is negative.  But we
 3713      * can't go before line 1 */
 3714     if (reg_firstlnum + lnum < 1)
 3715         return NULL;
 3716     if (lnum > reg_maxline)
 3717         /* Must have matched the "\n" in the last line. */
!3718         return (char_u *)"";
 3719     return ml_get_buf(reg_buf, reg_firstlnum + lnum, FALSE);
 3720 }

So "regline + rp->rs_un.regsave.rs_u.pos.col - 1"  at regexp.c:5588
is pointing to invalid memory (global overflow).

Bug was found by afl-fuzz (http://lcamtuf.coredump.cx/afl/).
Sorry, no patch as I don't know how to fix it.

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Attachment: crash-5
Description: Binary data

Reply via email to