Skip to content

Conversation

davidgranstrom
Copy link

wget is needed to build on osx (scripts/common.sh)

@kyleconroy
Copy link

You can also change common.sh to use cURL if we don't want to make people install wget

@tbelaire
Copy link
Contributor

I'm going to send a pull request that fixes this in a bit. It'll try and use either one.

@tbelaire
Copy link
Contributor

#61

justinmk pushed a commit to justinmk/neovim that referenced this pull request Feb 11, 2017
Does not actually matter for most uses, but critical for mark&sweep garbage
collector.

Closes neovim#5234
Closes neovim#5774
Closes neovim#5817
Closes neovim#5883
Closes neovim#5934
Closes neovim#5970
Closes neovim#5548

Helped-by: James McCoy <jamessan@jamessan.com>
Helped-by: Tommy Allen <tommy@esdf.io>
Helped-by: Justin M. Keyes <justinkz@gmail.com>

Sample backtrace showing dv_copyID being overwritten by clear_tv, which
allows it to be collected by garbage_collect .. free_unref_items:

    Old value = 152911
    New value = 152912
    0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    641               cur_mpsv->data.d.dict->dv_copyID = copyID - 1;
    (rr) bt
    #0  0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    #1  0x0000000000485dee in clear_tv (varp=0x7fb6348f3b20) at /home/foo/src/github.com/neovim/src/nvim/eval.c:19876
    #2  0x0000000000494e5e in vars_clear_ext (ht=0x7fb634351460, free_val=1) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20378
    #3  0x0000000000494dca in vars_clear (ht=0x7fb634351460) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20355
    #4  0x000000000048efa3 in free_funccal (fc=0x7fb634351200, free_val=0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:22927
    #5  0x0000000000491d8f in call_user_func (fp=0x7fb6340ae4e0, argcount=0, argvars=0x7ffdd216a050, rettv=0x7ffdd216a2b0, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22818
    #6  0x00000000004873a4 in call_func (funcname=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, argcount_in=0, argvars_in=0x7ffdd216a050, argv_func=0x0, firstline=2,
        lastline=2, doesrange=0x7ffdd216a2ac, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    neovim#7  0x000000000048a6f0 in get_func_tv (name=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, arg=0x7ffdd216a2c8, firstline=2, lastline=2, doesrange=0x7ffdd216a2ac,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    neovim#8  0x0000000000489691 in ex_call (eap=0x7ffdd216a598) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    neovim#9  0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216a878, flags=7, cstack=0x7ffdd216a880, fgetline=0x4f7c30 <get_loop_line>, cookie=0x7ffdd216a7f8)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    neovim#10 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x499f50 <get_func_line>, cookie=0x7fb634350800, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    neovim#11 0x00000000004918c0 in call_user_func (fp=0x7fb6340ae6a0, argcount=0, argvars=0x7ffdd216b6d0, rettv=0x7ffdd216b930, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22728
    neovim#12 0x00000000004873a4 in call_func (funcname=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, argcount_in=0, argvars_in=0x7ffdd216b6d0, argv_func=0x0,
        firstline=2, lastline=2, doesrange=0x7ffdd216b92c, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    neovim#13 0x000000000048a6f0 in get_func_tv (name=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, arg=0x7ffdd216b948, firstline=2, lastline=2, doesrange=0x7ffdd216b92c,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    neovim#14 0x0000000000489691 in ex_call (eap=0x7ffdd216bc18) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    neovim#15 0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216bef8, flags=7, cstack=0x7ffdd216bf00, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    neovim#16 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    neovim#17 0x00000000005390ee in apply_autocmds_group (event=EVENT_VIMRESIZED, fname=0x7fb6348ed2c0 "/home/foo/src/github.com/neovim/build/vimfiler:default", fname_io=0x0, force=false, group=-3,
        buf=0x7fb634858000, eap=0x0) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882
    neovim#18 0x000000000052f67c in apply_autocmds (event=EVENT_VIMRESIZED, fname=0x0, fname_io=0x0, force=false, buf=0x7fb634858000) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527
    neovim#19 0x0000000000640df2 in screenalloc (doclear=false) at /home/foo/src/github.com/neovim/src/nvim/screen.c:6234
    neovim#20 0x00000000006320d2 in screenclear () at /home/foo/src/github.com/neovim/src/nvim/screen.c:6277
    neovim#21 0x0000000000641edf in screen_resize (width=49, height=56) at /home/foo/src/github.com/neovim/src/nvim/screen.c:7366
    neovim#22 0x00000000006b2d82 in ui_refresh () at /home/foo/src/github.com/neovim/src/nvim/ui.c:175
    neovim#23 0x00000000006b3121 in ui_refresh_event (argv=0x7ffdd216c748) at /home/foo/src/github.com/neovim/src/nvim/ui.c:181
    neovim#24 0x00000000004d8297 in multiqueue_process_events (this=0x7fb634812370) at /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146
    neovim#25 0x00000000004d7616 in loop_poll_events (loop=0x96e900 <main_loop>, ms=-1) at /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56
    neovim#26 0x00000000005eb635 in input_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:326
    neovim#27 0x00000000005ea700 in inbuf_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:348
    neovim#28 0x00000000005ea61d in os_inchar (buf=0x0, maxlen=0, ms=-1, tb_change_cnt=0) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:110
    neovim#29 0x000000000068e0af in state_enter (s=0x7ffdd216c888) at /home/foo/src/github.com/neovim/src/nvim/state.c:49
    neovim#30 0x00000000005ac514 in normal_enter (cmdwin=false, noexmode=false) at /home/foo/src/github.com/neovim/src/nvim/normal.c:463
    neovim#31 0x0000000000565c62 in main (argc=9, argv=0x7ffdd216cc28) at /home/foo/src/github.com/neovim/src/nvim/main.c:540

ASAN trace after provoking the bug with VimFiler:
=================================================================
==8540==ERROR: AddressSanitizer: heap-use-after-free on address 0x613000054748 at pc 0x0000007d1dd8 bp 0x7ffe71be6660 sp 0x7ffe71be6658
READ of size 4 at 0x613000054748 thread T0
    #0 0x7d1dd7 in copy_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37
    #1 0x87b92c in f_get /home/foo/src/github.com/neovim/src/nvim/eval.c:9895:5
    #2 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11
    #3 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #4 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    #5 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #6 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#7 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#8 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#9 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#10 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#11 0x7abe36 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3494:9
    neovim#12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#13 0x830cac in ex_return /home/foo/src/github.com/neovim/src/nvim/eval.c:22191:10
    neovim#14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    neovim#20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#26 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#27 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    neovim#28 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#29 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#30 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#31 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#32 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#33 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    neovim#34 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#35 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#36 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#37 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#38 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#39 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    neovim#40 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#41 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#42 0xca2918 in apply_autocmds_group /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882:5
    neovim#43 0xc6c446 in apply_autocmds /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527:10
    neovim#44 0x140f374 in screenalloc /home/foo/src/github.com/neovim/src/nvim/screen.c:6234:5
    neovim#45 0x13958d1 in screenclear /home/foo/src/github.com/neovim/src/nvim/screen.c:6277:3
    neovim#46 0x1417573 in screen_resize /home/foo/src/github.com/neovim/src/nvim/screen.c:7366:5
    neovim#47 0x17fb59b in ui_refresh /home/foo/src/github.com/neovim/src/nvim/ui.c:175:3
    neovim#48 0x17fc100 in ui_refresh_event /home/foo/src/github.com/neovim/src/nvim/ui.c:181:3
    neovim#49 0xa05bbf in multiqueue_process_events /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146:7
    neovim#50 0x9ff8b6 in loop_poll_events /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56:3
    neovim#51 0x120d584 in input_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:326:3
    neovim#52 0x12092ef in inbuf_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:348:24
    neovim#53 0x1209193 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:110:18
    neovim#54 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    neovim#55 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    neovim#56 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    neovim#57 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    neovim#58 0x44b959 in _start (/home/foo/src/github.com/neovim/build/bin/nvim+0x44b959)

0x613000054748 is located 8 bytes inside of 352-byte region [0x613000054740,0x6130000548a0)
freed by thread T0 here:
    #0 0x4e9d70 in __interceptor_cfree.localalias.0 (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9d70)
    #1 0xefa184 in xfree /home/foo/src/github.com/neovim/src/nvim/memory.c:130:3
    #2 0x7e52b5 in dict_free_dict /home/foo/src/github.com/neovim/src/nvim/eval.c:6431:3
    #3 0x7e1e2c in free_unref_items /home/foo/src/github.com/neovim/src/nvim/eval.c:6063:7
    #4 0x7946cd in garbage_collect /home/foo/src/github.com/neovim/src/nvim/eval.c:5985:16
    #5 0xd08f4f in before_blocking /home/foo/src/github.com/neovim/src/nvim/getchar.c:1331:5
    #6 0x1209157 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:109:9
    neovim#7 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    neovim#8 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    neovim#9 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    neovim#10 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

previously allocated by thread T0 here:
    #0 0x4e9f08 in malloc (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9f08)
    #1 0xef9ee4 in try_malloc /home/foo/src/github.com/neovim/src/nvim/memory.c:84:15
    #2 0xefa0a4 in xmalloc /home/foo/src/github.com/neovim/src/nvim/memory.c:118:15
    #3 0x78bcc6 in dict_alloc /home/foo/src/github.com/neovim/src/nvim/eval.c:6321:15
    #4 0x86dc02 in get_dict_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:6789:9
    #5 0x865751 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4296:21
    #6 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#7 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#8 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#9 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#10 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#11 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#13 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    neovim#14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    neovim#20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#26 0x93f89a in filter_map_one /home/foo/src/github.com/neovim/src/nvim/eval.c:9398:7
    neovim#27 0x93f33a in filter_map /home/foo/src/github.com/neovim/src/nvim/eval.c:9372:13
    neovim#28 0x8ceb57 in f_map /home/foo/src/github.com/neovim/src/nvim/eval.c:12900:3
    neovim#29 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11

SUMMARY: AddressSanitizer: heap-use-after-free /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37 in copy_tv
Shadow bytes around the buggy address:
  0x0c2680002890: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028a0: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c26800028b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028d0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c26800028e0: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
  0x0c26800028f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002910: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2680002920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002930: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8540==ABORTING
justinmk pushed a commit to justinmk/neovim that referenced this pull request Feb 11, 2017
Does not actually matter for most uses, but critical for mark&sweep garbage
collector.

Closes neovim#5234
Closes neovim#5774
Closes neovim#5817
Closes neovim#5883
Closes neovim#5934
Closes neovim#5970
Closes neovim#5548

Helped-by: James McCoy <jamessan@jamessan.com>
Helped-by: Tommy Allen <tommy@esdf.io>
Helped-by: Justin M. Keyes <justinkz@gmail.com>

---

Steps to reproduce:

    Compile fb97457 with:
       CC=clang CFLAGS=" -O0 -g -DEXITFREE " cmake .. -DMIN_LOG_LEVEL=0 -DCMAKE_BUILD_TYPE=Debug -DBUSTED_OUTPUT_TYPE=utf
       -DCMAKE_INSTALL_PREFIX=$PWD/root -DJEMALLOC_USE_BUNDLED=1 -DCLANG_ASAN_UBSAN=ON -DPREFER_LUAJIT=false

    Directory `crash` contains:
    1. unite directory with Shougo/unite.vim@be09b0e
    2. vimfiler directory with Shougo/vimfiler.vim@72c37e8
    3. `init.vim` with a single line which sets `&rtp` to the above two directories (absolute path).

    bin/nvim -u ../crash/init.vim -i NONE --headless -s <(<<< $':split\n:VimFiler\n\C-ww:call garbagecollect()\n\C-w\C-w\C-w')

---

Sample backtrace showing dv_copyID being overwritten by clear_tv, which
allows it to be collected by garbage_collect .. free_unref_items:

    Old value = 152911
    New value = 152912
    0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    641               cur_mpsv->data.d.dict->dv_copyID = copyID - 1;
    (rr) bt
    #0  0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    #1  0x0000000000485dee in clear_tv (varp=0x7fb6348f3b20) at /home/foo/src/github.com/neovim/src/nvim/eval.c:19876
    #2  0x0000000000494e5e in vars_clear_ext (ht=0x7fb634351460, free_val=1) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20378
    #3  0x0000000000494dca in vars_clear (ht=0x7fb634351460) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20355
    #4  0x000000000048efa3 in free_funccal (fc=0x7fb634351200, free_val=0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:22927
    #5  0x0000000000491d8f in call_user_func (fp=0x7fb6340ae4e0, argcount=0, argvars=0x7ffdd216a050, rettv=0x7ffdd216a2b0, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22818
    #6  0x00000000004873a4 in call_func (funcname=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, argcount_in=0, argvars_in=0x7ffdd216a050, argv_func=0x0, firstline=2,
        lastline=2, doesrange=0x7ffdd216a2ac, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    neovim#7  0x000000000048a6f0 in get_func_tv (name=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, arg=0x7ffdd216a2c8, firstline=2, lastline=2, doesrange=0x7ffdd216a2ac,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    neovim#8  0x0000000000489691 in ex_call (eap=0x7ffdd216a598) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    neovim#9  0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216a878, flags=7, cstack=0x7ffdd216a880, fgetline=0x4f7c30 <get_loop_line>, cookie=0x7ffdd216a7f8)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    neovim#10 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x499f50 <get_func_line>, cookie=0x7fb634350800, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    neovim#11 0x00000000004918c0 in call_user_func (fp=0x7fb6340ae6a0, argcount=0, argvars=0x7ffdd216b6d0, rettv=0x7ffdd216b930, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22728
    neovim#12 0x00000000004873a4 in call_func (funcname=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, argcount_in=0, argvars_in=0x7ffdd216b6d0, argv_func=0x0,
        firstline=2, lastline=2, doesrange=0x7ffdd216b92c, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    neovim#13 0x000000000048a6f0 in get_func_tv (name=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, arg=0x7ffdd216b948, firstline=2, lastline=2, doesrange=0x7ffdd216b92c,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    neovim#14 0x0000000000489691 in ex_call (eap=0x7ffdd216bc18) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    neovim#15 0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216bef8, flags=7, cstack=0x7ffdd216bf00, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    neovim#16 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    neovim#17 0x00000000005390ee in apply_autocmds_group (event=EVENT_VIMRESIZED, fname=0x7fb6348ed2c0 "/home/foo/src/github.com/neovim/build/vimfiler:default", fname_io=0x0, force=false, group=-3,
        buf=0x7fb634858000, eap=0x0) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882
    neovim#18 0x000000000052f67c in apply_autocmds (event=EVENT_VIMRESIZED, fname=0x0, fname_io=0x0, force=false, buf=0x7fb634858000) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527
    neovim#19 0x0000000000640df2 in screenalloc (doclear=false) at /home/foo/src/github.com/neovim/src/nvim/screen.c:6234
    neovim#20 0x00000000006320d2 in screenclear () at /home/foo/src/github.com/neovim/src/nvim/screen.c:6277
    neovim#21 0x0000000000641edf in screen_resize (width=49, height=56) at /home/foo/src/github.com/neovim/src/nvim/screen.c:7366
    neovim#22 0x00000000006b2d82 in ui_refresh () at /home/foo/src/github.com/neovim/src/nvim/ui.c:175
    neovim#23 0x00000000006b3121 in ui_refresh_event (argv=0x7ffdd216c748) at /home/foo/src/github.com/neovim/src/nvim/ui.c:181
    neovim#24 0x00000000004d8297 in multiqueue_process_events (this=0x7fb634812370) at /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146
    neovim#25 0x00000000004d7616 in loop_poll_events (loop=0x96e900 <main_loop>, ms=-1) at /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56
    neovim#26 0x00000000005eb635 in input_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:326
    neovim#27 0x00000000005ea700 in inbuf_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:348
    neovim#28 0x00000000005ea61d in os_inchar (buf=0x0, maxlen=0, ms=-1, tb_change_cnt=0) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:110
    neovim#29 0x000000000068e0af in state_enter (s=0x7ffdd216c888) at /home/foo/src/github.com/neovim/src/nvim/state.c:49
    neovim#30 0x00000000005ac514 in normal_enter (cmdwin=false, noexmode=false) at /home/foo/src/github.com/neovim/src/nvim/normal.c:463
    neovim#31 0x0000000000565c62 in main (argc=9, argv=0x7ffdd216cc28) at /home/foo/src/github.com/neovim/src/nvim/main.c:540

---

ASAN trace after provoking the bug with VimFiler:

=================================================================
==8540==ERROR: AddressSanitizer: heap-use-after-free on address 0x613000054748 at pc 0x0000007d1dd8 bp 0x7ffe71be6660 sp 0x7ffe71be6658
READ of size 4 at 0x613000054748 thread T0
    #0 0x7d1dd7 in copy_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37
    #1 0x87b92c in f_get /home/foo/src/github.com/neovim/src/nvim/eval.c:9895:5
    #2 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11
    #3 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #4 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    #5 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #6 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#7 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#8 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#9 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#10 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#11 0x7abe36 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3494:9
    neovim#12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#13 0x830cac in ex_return /home/foo/src/github.com/neovim/src/nvim/eval.c:22191:10
    neovim#14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    neovim#20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#26 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#27 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    neovim#28 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#29 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#30 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#31 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#32 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#33 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    neovim#34 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#35 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#36 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#37 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#38 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#39 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    neovim#40 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#41 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#42 0xca2918 in apply_autocmds_group /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882:5
    neovim#43 0xc6c446 in apply_autocmds /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527:10
    neovim#44 0x140f374 in screenalloc /home/foo/src/github.com/neovim/src/nvim/screen.c:6234:5
    neovim#45 0x13958d1 in screenclear /home/foo/src/github.com/neovim/src/nvim/screen.c:6277:3
    neovim#46 0x1417573 in screen_resize /home/foo/src/github.com/neovim/src/nvim/screen.c:7366:5
    neovim#47 0x17fb59b in ui_refresh /home/foo/src/github.com/neovim/src/nvim/ui.c:175:3
    neovim#48 0x17fc100 in ui_refresh_event /home/foo/src/github.com/neovim/src/nvim/ui.c:181:3
    neovim#49 0xa05bbf in multiqueue_process_events /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146:7
    neovim#50 0x9ff8b6 in loop_poll_events /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56:3
    neovim#51 0x120d584 in input_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:326:3
    neovim#52 0x12092ef in inbuf_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:348:24
    neovim#53 0x1209193 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:110:18
    neovim#54 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    neovim#55 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    neovim#56 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    neovim#57 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    neovim#58 0x44b959 in _start (/home/foo/src/github.com/neovim/build/bin/nvim+0x44b959)

0x613000054748 is located 8 bytes inside of 352-byte region [0x613000054740,0x6130000548a0)
freed by thread T0 here:
    #0 0x4e9d70 in __interceptor_cfree.localalias.0 (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9d70)
    #1 0xefa184 in xfree /home/foo/src/github.com/neovim/src/nvim/memory.c:130:3
    #2 0x7e52b5 in dict_free_dict /home/foo/src/github.com/neovim/src/nvim/eval.c:6431:3
    #3 0x7e1e2c in free_unref_items /home/foo/src/github.com/neovim/src/nvim/eval.c:6063:7
    #4 0x7946cd in garbage_collect /home/foo/src/github.com/neovim/src/nvim/eval.c:5985:16
    #5 0xd08f4f in before_blocking /home/foo/src/github.com/neovim/src/nvim/getchar.c:1331:5
    #6 0x1209157 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:109:9
    neovim#7 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    neovim#8 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    neovim#9 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    neovim#10 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

previously allocated by thread T0 here:
    #0 0x4e9f08 in malloc (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9f08)
    #1 0xef9ee4 in try_malloc /home/foo/src/github.com/neovim/src/nvim/memory.c:84:15
    #2 0xefa0a4 in xmalloc /home/foo/src/github.com/neovim/src/nvim/memory.c:118:15
    #3 0x78bcc6 in dict_alloc /home/foo/src/github.com/neovim/src/nvim/eval.c:6321:15
    #4 0x86dc02 in get_dict_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:6789:9
    #5 0x865751 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4296:21
    #6 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#7 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#8 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#9 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#10 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#11 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    neovim#13 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    neovim#14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    neovim#15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    neovim#16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    neovim#17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    neovim#18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    neovim#19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    neovim#20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    neovim#21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    neovim#22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    neovim#23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    neovim#24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    neovim#25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    neovim#26 0x93f89a in filter_map_one /home/foo/src/github.com/neovim/src/nvim/eval.c:9398:7
    neovim#27 0x93f33a in filter_map /home/foo/src/github.com/neovim/src/nvim/eval.c:9372:13
    neovim#28 0x8ceb57 in f_map /home/foo/src/github.com/neovim/src/nvim/eval.c:12900:3
    neovim#29 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11

SUMMARY: AddressSanitizer: heap-use-after-free /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37 in copy_tv
Shadow bytes around the buggy address:
  0x0c2680002890: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028a0: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c26800028b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028d0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c26800028e0: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
  0x0c26800028f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002910: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2680002920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002930: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8540==ABORTING
justinmk added a commit that referenced this pull request Feb 11, 2017
Does not actually matter for most uses, but critical for mark&sweep garbage
collector.

Closes #5234
Closes #5774
Closes #5817
Closes #5883
Closes #5934
Closes #5970
Closes #5548

Helped-by: James McCoy <jamessan@jamessan.com>
Helped-by: Tommy Allen <tommy@esdf.io>
Helped-by: Justin M. Keyes <justinkz@gmail.com>

---

Steps to reproduce:

    Compile fb97457 with:
       CC=clang CFLAGS=" -O0 -g -DEXITFREE " cmake .. -DMIN_LOG_LEVEL=0 -DCMAKE_BUILD_TYPE=Debug -DBUSTED_OUTPUT_TYPE=utf
       -DCMAKE_INSTALL_PREFIX=$PWD/root -DJEMALLOC_USE_BUNDLED=1 -DCLANG_ASAN_UBSAN=ON -DPREFER_LUAJIT=false

    Directory `crash` contains:
    1. unite directory with Shougo/unite.vim@be09b0e
    2. vimfiler directory with Shougo/vimfiler.vim@72c37e8
    3. `init.vim` with a single line which sets `&rtp` to the above two directories (absolute path).

    bin/nvim -u ../crash/init.vim -i NONE --headless -s <(<<< $':split\n:VimFiler\n\C-ww:call garbagecollect()\n\C-w\C-w\C-w')

---

Sample backtrace showing dv_copyID being overwritten by clear_tv, which
allows it to be collected by garbage_collect .. free_unref_items:

    Old value = 152911
    New value = 152912
    0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    641               cur_mpsv->data.d.dict->dv_copyID = copyID - 1;
    (rr) bt
    #0  0x00000000004938e5 in encode_vim_to_nothing (ignored=0x7fb6348f3b20, top_tv=0x7fb6348f3b20, objname=0x6d62e9 "clear_tv argument") at ../src/nvim/eval/typval_encode.c.h:641
    #1  0x0000000000485dee in clear_tv (varp=0x7fb6348f3b20) at /home/foo/src/github.com/neovim/src/nvim/eval.c:19876
    #2  0x0000000000494e5e in vars_clear_ext (ht=0x7fb634351460, free_val=1) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20378
    #3  0x0000000000494dca in vars_clear (ht=0x7fb634351460) at /home/foo/src/github.com/neovim/src/nvim/eval.c:20355
    #4  0x000000000048efa3 in free_funccal (fc=0x7fb634351200, free_val=0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:22927
    #5  0x0000000000491d8f in call_user_func (fp=0x7fb6340ae4e0, argcount=0, argvars=0x7ffdd216a050, rettv=0x7ffdd216a2b0, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22818
    #6  0x00000000004873a4 in call_func (funcname=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, argcount_in=0, argvars_in=0x7ffdd216a050, argv_func=0x0, firstline=2,
        lastline=2, doesrange=0x7ffdd216a2ac, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    #7  0x000000000048a6f0 in get_func_tv (name=0x7fb6348ba3e0 "vimfiler#view#_redraw_screen", len=28, rettv=0x7ffdd216a2b0, arg=0x7ffdd216a2c8, firstline=2, lastline=2, doesrange=0x7ffdd216a2ac,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    #8  0x0000000000489691 in ex_call (eap=0x7ffdd216a598) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    #9  0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216a878, flags=7, cstack=0x7ffdd216a880, fgetline=0x4f7c30 <get_loop_line>, cookie=0x7ffdd216a7f8)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    #10 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x499f50 <get_func_line>, cookie=0x7fb634350800, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    #11 0x00000000004918c0 in call_user_func (fp=0x7fb6340ae6a0, argcount=0, argvars=0x7ffdd216b6d0, rettv=0x7ffdd216b930, firstline=2, lastline=2, selfdict=0x0)
        at /home/foo/src/github.com/neovim/src/nvim/eval.c:22728
    #12 0x00000000004873a4 in call_func (funcname=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, argcount_in=0, argvars_in=0x7ffdd216b6d0, argv_func=0x0,
        firstline=2, lastline=2, doesrange=0x7ffdd216b92c, evaluate=true, partial=0x0, selfdict_in=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7687
    #13 0x000000000048a6f0 in get_func_tv (name=0x7fb6348f3ee0 "vimfiler#view#_redraw_all_vimfiler", len=34, rettv=0x7ffdd216b930, arg=0x7ffdd216b948, firstline=2, lastline=2, doesrange=0x7ffdd216b92c,
        evaluate=1, partial=0x0, selfdict=0x0) at /home/foo/src/github.com/neovim/src/nvim/eval.c:7459
    #14 0x0000000000489691 in ex_call (eap=0x7ffdd216bc18) at /home/foo/src/github.com/neovim/src/nvim/eval.c:2817
    #15 0x00000000004fae46 in do_one_cmd (cmdlinep=0x7ffdd216bef8, flags=7, cstack=0x7ffdd216bf00, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508)
        at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198
    #16 0x00000000004f6ae3 in do_cmdline (cmdline=0x0, fgetline=0x539820 <getnextac>, cookie=0x7ffdd216c508, flags=7) at /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601
    #17 0x00000000005390ee in apply_autocmds_group (event=EVENT_VIMRESIZED, fname=0x7fb6348ed2c0 "/home/foo/src/github.com/neovim/build/vimfiler:default", fname_io=0x0, force=false, group=-3,
        buf=0x7fb634858000, eap=0x0) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882
    #18 0x000000000052f67c in apply_autocmds (event=EVENT_VIMRESIZED, fname=0x0, fname_io=0x0, force=false, buf=0x7fb634858000) at /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527
    #19 0x0000000000640df2 in screenalloc (doclear=false) at /home/foo/src/github.com/neovim/src/nvim/screen.c:6234
    #20 0x00000000006320d2 in screenclear () at /home/foo/src/github.com/neovim/src/nvim/screen.c:6277
    #21 0x0000000000641edf in screen_resize (width=49, height=56) at /home/foo/src/github.com/neovim/src/nvim/screen.c:7366
    #22 0x00000000006b2d82 in ui_refresh () at /home/foo/src/github.com/neovim/src/nvim/ui.c:175
    #23 0x00000000006b3121 in ui_refresh_event (argv=0x7ffdd216c748) at /home/foo/src/github.com/neovim/src/nvim/ui.c:181
    #24 0x00000000004d8297 in multiqueue_process_events (this=0x7fb634812370) at /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146
    #25 0x00000000004d7616 in loop_poll_events (loop=0x96e900 <main_loop>, ms=-1) at /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56
    #26 0x00000000005eb635 in input_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:326
    #27 0x00000000005ea700 in inbuf_poll (ms=-1) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:348
    #28 0x00000000005ea61d in os_inchar (buf=0x0, maxlen=0, ms=-1, tb_change_cnt=0) at /home/foo/src/github.com/neovim/src/nvim/os/input.c:110
    #29 0x000000000068e0af in state_enter (s=0x7ffdd216c888) at /home/foo/src/github.com/neovim/src/nvim/state.c:49
    #30 0x00000000005ac514 in normal_enter (cmdwin=false, noexmode=false) at /home/foo/src/github.com/neovim/src/nvim/normal.c:463
    #31 0x0000000000565c62 in main (argc=9, argv=0x7ffdd216cc28) at /home/foo/src/github.com/neovim/src/nvim/main.c:540

---

ASAN trace after provoking the bug with VimFiler:

=================================================================
==8540==ERROR: AddressSanitizer: heap-use-after-free on address 0x613000054748 at pc 0x0000007d1dd8 bp 0x7ffe71be6660 sp 0x7ffe71be6658
READ of size 4 at 0x613000054748 thread T0
    #0 0x7d1dd7 in copy_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37
    #1 0x87b92c in f_get /home/foo/src/github.com/neovim/src/nvim/eval.c:9895:5
    #2 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11
    #3 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #4 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    #5 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #6 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    #7 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    #8 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    #9 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    #10 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    #11 0x7abe36 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3494:9
    #12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    #13 0x830cac in ex_return /home/foo/src/github.com/neovim/src/nvim/eval.c:22191:10
    #14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    #15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    #16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    #17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    #18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    #20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    #22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    #23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    #24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    #25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    #26 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    #27 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    #28 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    #29 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    #30 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    #31 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    #32 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #33 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    #34 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    #35 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    #36 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    #37 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    #38 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #39 0x7c1d3d in ex_call /home/foo/src/github.com/neovim/src/nvim/eval.c:2843:9
    #40 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    #41 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    #42 0xca2918 in apply_autocmds_group /home/foo/src/github.com/neovim/src/nvim/fileio.c:6882:5
    #43 0xc6c446 in apply_autocmds /home/foo/src/github.com/neovim/src/nvim/fileio.c:6527:10
    #44 0x140f374 in screenalloc /home/foo/src/github.com/neovim/src/nvim/screen.c:6234:5
    #45 0x13958d1 in screenclear /home/foo/src/github.com/neovim/src/nvim/screen.c:6277:3
    #46 0x1417573 in screen_resize /home/foo/src/github.com/neovim/src/nvim/screen.c:7366:5
    #47 0x17fb59b in ui_refresh /home/foo/src/github.com/neovim/src/nvim/ui.c:175:3
    #48 0x17fc100 in ui_refresh_event /home/foo/src/github.com/neovim/src/nvim/ui.c:181:3
    #49 0xa05bbf in multiqueue_process_events /home/foo/src/github.com/neovim/src/nvim/event/multiqueue.c:146:7
    #50 0x9ff8b6 in loop_poll_events /home/foo/src/github.com/neovim/src/nvim/event/loop.c:56:3
    #51 0x120d584 in input_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:326:3
    #52 0x12092ef in inbuf_poll /home/foo/src/github.com/neovim/src/nvim/os/input.c:348:24
    #53 0x1209193 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:110:18
    #54 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    #55 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    #56 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    #57 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #58 0x44b959 in _start (/home/foo/src/github.com/neovim/build/bin/nvim+0x44b959)

0x613000054748 is located 8 bytes inside of 352-byte region [0x613000054740,0x6130000548a0)
freed by thread T0 here:
    #0 0x4e9d70 in __interceptor_cfree.localalias.0 (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9d70)
    #1 0xefa184 in xfree /home/foo/src/github.com/neovim/src/nvim/memory.c:130:3
    #2 0x7e52b5 in dict_free_dict /home/foo/src/github.com/neovim/src/nvim/eval.c:6431:3
    #3 0x7e1e2c in free_unref_items /home/foo/src/github.com/neovim/src/nvim/eval.c:6063:7
    #4 0x7946cd in garbage_collect /home/foo/src/github.com/neovim/src/nvim/eval.c:5985:16
    #5 0xd08f4f in before_blocking /home/foo/src/github.com/neovim/src/nvim/getchar.c:1331:5
    #6 0x1209157 in os_inchar /home/foo/src/github.com/neovim/src/nvim/os/input.c:109:9
    #7 0x16d3615 in state_enter /home/foo/src/github.com/neovim/src/nvim/state.c:49:13
    #8 0x101090b in normal_enter /home/foo/src/github.com/neovim/src/nvim/normal.c:463:3
    #9 0xdd0a82 in main /home/foo/src/github.com/neovim/src/nvim/main.c:542:3
    #10 0x7f3c61df42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

previously allocated by thread T0 here:
    #0 0x4e9f08 in malloc (/home/foo/src/github.com/neovim/build/bin/nvim+0x4e9f08)
    #1 0xef9ee4 in try_malloc /home/foo/src/github.com/neovim/src/nvim/memory.c:84:15
    #2 0xefa0a4 in xmalloc /home/foo/src/github.com/neovim/src/nvim/memory.c:118:15
    #3 0x78bcc6 in dict_alloc /home/foo/src/github.com/neovim/src/nvim/eval.c:6321:15
    #4 0x86dc02 in get_dict_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:6789:9
    #5 0x865751 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4296:21
    #6 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #7 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    #8 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    #9 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    #10 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    #11 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    #12 0x7a9ecc in eval0 /home/foo/src/github.com/neovim/src/nvim/eval.c:3420:9
    #13 0x7b78f2 in ex_let /home/foo/src/github.com/neovim/src/nvim/eval.c:1479:9
    #14 0xb06a1c in do_one_cmd /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:2198:5
    #15 0xae5557 in do_cmdline /home/foo/src/github.com/neovim/src/nvim/ex_docmd.c:601:20
    #16 0x7f2490 in call_user_func /home/foo/src/github.com/neovim/src/nvim/eval.c:21993:3
    #17 0x7b2eee in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7271:11
    #18 0x7c8d7a in get_func_tv /home/foo/src/github.com/neovim/src/nvim/eval.c:7091:11
    #19 0x8667f9 in eval7 /home/foo/src/github.com/neovim/src/nvim/eval.c:4353:15
    #20 0x8621e5 in eval6 /home/foo/src/github.com/neovim/src/nvim/eval.c:4073:7
    #21 0x85ce69 in eval5 /home/foo/src/github.com/neovim/src/nvim/eval.c:3925:7
    #22 0x858071 in eval4 /home/foo/src/github.com/neovim/src/nvim/eval.c:3666:7
    #23 0x857613 in eval3 /home/foo/src/github.com/neovim/src/nvim/eval.c:3588:7
    #24 0x856bb3 in eval2 /home/foo/src/github.com/neovim/src/nvim/eval.c:3525:7
    #25 0x7ab772 in eval1 /home/foo/src/github.com/neovim/src/nvim/eval.c:3458:7
    #26 0x93f89a in filter_map_one /home/foo/src/github.com/neovim/src/nvim/eval.c:9398:7
    #27 0x93f33a in filter_map /home/foo/src/github.com/neovim/src/nvim/eval.c:9372:13
    #28 0x8ceb57 in f_map /home/foo/src/github.com/neovim/src/nvim/eval.c:12900:3
    #29 0x7b35c0 in call_func /home/foo/src/github.com/neovim/src/nvim/eval.c:7286:11

SUMMARY: AddressSanitizer: heap-use-after-free /home/foo/src/github.com/neovim/src/nvim/eval.c:20116:37 in copy_tv
Shadow bytes around the buggy address:
  0x0c2680002890: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028a0: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c26800028b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c26800028d0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c26800028e0: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
  0x0c26800028f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002910: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2680002920: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2680002930: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8540==ABORTING
dwb pushed a commit to dwb/neovim that referenced this pull request Feb 21, 2017
Add some options to c-family makers
butwerenotthereyet pushed a commit to butwerenotthereyet/neovim that referenced this pull request Dec 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants