Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Crash by GC during specific processing #4579

Closed
wants to merge 3 commits into from
Closed

Conversation

ichizok
Copy link
Contributor

@ichizok ichizok commented Jun 24, 2019

Ref #4571

Repro steps

Case 1. Error in timer callback

timer.vim

func Func(timer)
  " fail to create list
  let x = [
endfunc
call timer_start(1, 'Func')

vim --clean -S timer.vim

Case 2. Error in map-expr

mapexpr.vim

func Func()
  " fail to create list
  let x = [
endfunc
nmap <expr> ! Func()

vim --clean -S mapexpr.vim and input !

In both case, the error message is shown:

Error detected while processing function Func:
line    2:
E697: Missing end of List ']':
Press ENTER or type command to continue

and leave Vim alone (with keep shown) few seconds (>= 4sec, GC runs), then Vim will crash.

Cause

ASAN log (case 1):

=================================================================
==6424==ERROR: AddressSanitizer: heap-use-after-free on address 0x6070000030b0 at pc 0x55a15a89bd0a bp 0x7ffcc07dbea0 sp 0x7ffcc07dbe90
READ of size 8 at 0x6070000030b0 thread T0
    #0 0x55a15a89bd09 in list_free_contents /workspace/vim/src/list.c:164
    #1 0x55a15a89c18e in list_free /workspace/vim/src/list.c:235
    #2 0x55a15a89ec23 in get_list_tv /workspace/vim/src/list.c:928
    #3 0x55a15a6ff628 in eval7 /workspace/vim/src/eval.c:4575
    #4 0x55a15a6fdfc6 in eval6 /workspace/vim/src/eval.c:4260
    #5 0x55a15a6fd036 in eval5 /workspace/vim/src/eval.c:4051
    #6 0x55a15a6fc792 in eval4 /workspace/vim/src/eval.c:3933
    #7 0x55a15a6fc326 in eval3 /workspace/vim/src/eval.c:3853
    #8 0x55a15a6fbe84 in eval2 /workspace/vim/src/eval.c:3785
    #9 0x55a15a6fb915 in eval1 /workspace/vim/src/eval.c:3713
    #10 0x55a15a6fb625 in eval0 /workspace/vim/src/eval.c:3671
    #11 0x55a15a6ee7d8 in ex_let_const /workspace/vim/src/eval.c:1470
    #12 0x55a15a6edb82 in ex_let /workspace/vim/src/eval.c:1371
    #13 0x55a15a7aba5d in do_one_cmd /workspace/vim/src/ex_docmd.c:2500
    #14 0x55a15a7a2d7a in do_cmdline /workspace/vim/src/ex_docmd.c:995
    #15 0x55a15abb8045 in call_user_func /workspace/vim/src/userfunc.c:1063
    #16 0x55a15abba9dd in call_func /workspace/vim/src/userfunc.c:1621
    #17 0x55a15abb9c0b in call_callback /workspace/vim/src/userfunc.c:1465
    #18 0x55a15a78c4b5 in timer_callback /workspace/vim/src/ex_cmds2.c:328
    #19 0x55a15a78cd5d in check_due_timer /workspace/vim/src/ex_cmds2.c:390
    #20 0x55a15ab91ebf in ui_wait_for_chars_or_timer /workspace/vim/src/ui.c:454
    #21 0x55a15a9ba859 in WaitForChar /workspace/vim/src/os_unix.c:5940
    #22 0x55a15ab91ca7 in inchar_loop /workspace/vim/src/ui.c:383
    #23 0x55a15a9ade0a in mch_inchar /workspace/vim/src/os_unix.c:388
    #24 0x55a15ab91755 in ui_inchar /workspace/vim/src/ui.c:231
    #25 0x55a15a850b81 in inchar /workspace/vim/src/getchar.c:3092
    #26 0x55a15a84fd1d in vgetorpeek /workspace/vim/src/getchar.c:2870
    #27 0x55a15a849e00 in vgetc /workspace/vim/src/getchar.c:1602
    #28 0x55a15a84a8a5 in safe_vgetc /workspace/vim/src/getchar.c:1821
    #29 0x55a15a912e40 in normal_cmd /workspace/vim/src/normal.c:596
    #30 0x55a15ac657e4 in main_loop /workspace/vim/src/main.c:1370
    #31 0x55a15ac64a9d in vim_main2 /workspace/vim/src/main.c:903
    #32 0x55a15ac6417d in main /workspace/vim/src/main.c:444
    #33 0x7fa4a728bb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #34 0x55a15a66c779 in _start (/workspace/vim/src/vim+0xf8779)

0x6070000030b0 is located 0 bytes inside of 80-byte region [0x6070000030b0,0x607000003100)
freed by thread T0 here:
    #0 0x7fa4a81177b8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xde7b8)
    #1 0x55a15a8e8786 in vim_free /workspace/vim/src/misc2.c:1805
    #2 0x55a15a89c043 in list_free_list /workspace/vim/src/list.c:208
    #3 0x55a15a89c11c in list_free_items /workspace/vim/src/list.c:225
    #4 0x55a15a705b99 in free_unref_items /workspace/vim/src/eval.c:5802
    #5 0x55a15a705a9c in garbage_collect /workspace/vim/src/eval.c:5748
    #6 0x55a15a8499d3 in before_blocking /workspace/vim/src/getchar.c:1520
    #7 0x55a15ab91c3d in inchar_loop /workspace/vim/src/ui.c:354
    #8 0x55a15a9ade0a in mch_inchar /workspace/vim/src/os_unix.c:388
    #9 0x55a15ab91755 in ui_inchar /workspace/vim/src/ui.c:231
    #10 0x55a15a850b81 in inchar /workspace/vim/src/getchar.c:3092
    #11 0x55a15a84fd1d in vgetorpeek /workspace/vim/src/getchar.c:2870
    #12 0x55a15a849e00 in vgetc /workspace/vim/src/getchar.c:1602
    #13 0x55a15a84a8a5 in safe_vgetc /workspace/vim/src/getchar.c:1821
    #14 0x55a15ac75dd1 in wait_return /workspace/vim/src/message.c:1098
    #15 0x55a15ac7fbc0 in msg_end /workspace/vim/src/message.c:3290
    #16 0x55a15ac72324 in msg_attr_keep /workspace/vim/src/message.c:182
    #17 0x55a15ac720b7 in msg_attr /workspace/vim/src/message.c:122
    #18 0x55a15ac744a2 in emsg_core /workspace/vim/src/message.c:701
    #19 0x55a15ac746b9 in semsg /workspace/vim/src/message.c:737
    #20 0x55a15a89ec08 in get_list_tv /workspace/vim/src/list.c:925
    #21 0x55a15a6ff628 in eval7 /workspace/vim/src/eval.c:4575
    #22 0x55a15a6fdfc6 in eval6 /workspace/vim/src/eval.c:4260
    #23 0x55a15a6fd036 in eval5 /workspace/vim/src/eval.c:4051
    #24 0x55a15a6fc792 in eval4 /workspace/vim/src/eval.c:3933
    #25 0x55a15a6fc326 in eval3 /workspace/vim/src/eval.c:3853
    #26 0x55a15a6fbe84 in eval2 /workspace/vim/src/eval.c:3785
    #27 0x55a15a6fb915 in eval1 /workspace/vim/src/eval.c:3713
    #28 0x55a15a6fb625 in eval0 /workspace/vim/src/eval.c:3671
    #29 0x55a15a6ee7d8 in ex_let_const /workspace/vim/src/eval.c:1470

previously allocated by thread T0 here:
    #0 0x7fa4a8117b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x55a15a8e641a in lalloc /workspace/vim/src/misc2.c:924
    #2 0x55a15a8e62bc in alloc_clear /workspace/vim/src/misc2.c:851
    #3 0x55a15a89b982 in list_alloc /workspace/vim/src/list.c:75
    #4 0x55a15a89e7c3 in get_list_tv /workspace/vim/src/list.c:890
    #5 0x55a15a6ff628 in eval7 /workspace/vim/src/eval.c:4575
    #6 0x55a15a6fdfc6 in eval6 /workspace/vim/src/eval.c:4260
    #7 0x55a15a6fd036 in eval5 /workspace/vim/src/eval.c:4051
    #8 0x55a15a6fc792 in eval4 /workspace/vim/src/eval.c:3933
    #9 0x55a15a6fc326 in eval3 /workspace/vim/src/eval.c:3853
    #10 0x55a15a6fbe84 in eval2 /workspace/vim/src/eval.c:3785
    #11 0x55a15a6fb915 in eval1 /workspace/vim/src/eval.c:3713
    #12 0x55a15a6fb625 in eval0 /workspace/vim/src/eval.c:3671
    #13 0x55a15a6ee7d8 in ex_let_const /workspace/vim/src/eval.c:1470
    #14 0x55a15a6edb82 in ex_let /workspace/vim/src/eval.c:1371
    #15 0x55a15a7aba5d in do_one_cmd /workspace/vim/src/ex_docmd.c:2500
    #16 0x55a15a7a2d7a in do_cmdline /workspace/vim/src/ex_docmd.c:995
    #17 0x55a15abb8045 in call_user_func /workspace/vim/src/userfunc.c:1063
    #18 0x55a15abba9dd in call_func /workspace/vim/src/userfunc.c:1621
    #19 0x55a15abb9c0b in call_callback /workspace/vim/src/userfunc.c:1465
    #20 0x55a15a78c4b5 in timer_callback /workspace/vim/src/ex_cmds2.c:328
    #21 0x55a15a78cd5d in check_due_timer /workspace/vim/src/ex_cmds2.c:390
    #22 0x55a15ab91ebf in ui_wait_for_chars_or_timer /workspace/vim/src/ui.c:454
    #23 0x55a15a9ba859 in WaitForChar /workspace/vim/src/os_unix.c:5940
    #24 0x55a15ab91ca7 in inchar_loop /workspace/vim/src/ui.c:383
    #25 0x55a15a9ade0a in mch_inchar /workspace/vim/src/os_unix.c:388
    #26 0x55a15ab91755 in ui_inchar /workspace/vim/src/ui.c:231
    #27 0x55a15a850b81 in inchar /workspace/vim/src/getchar.c:3092
    #28 0x55a15a84fd1d in vgetorpeek /workspace/vim/src/getchar.c:2870
    #29 0x55a15a849e00 in vgetc /workspace/vim/src/getchar.c:1602

When invoking timer-callback and handling map-expr vgetc_busy is set to 0 (save/restore), thus GC can run during them.
I propose should save/restore also may_garbase_collect.

Processing in timer-callback and map-expr are handled as in main_loop
so then GC can interrupt into script processing and release objects
unexpectedly.
@brammool brammool closed this in 7d491c4 Jun 25, 2019
@ichizok ichizok deleted the fix/gc branch June 25, 2019 04:34
manuelschiller pushed a commit to manuelschiller/vim that referenced this pull request Nov 10, 2019
Problem:    On error garbage collection may free memory in use.
Solution:   Reset may_garbage_collect when evaluating expression mapping.
            Add tests. (Ozaki Kiichi, closes vim#4579)
JaySandhu added a commit to JaySandhu/neovim that referenced this pull request Sep 8, 2020
Problem:    On error garbage collection may free memory in use.
Solution:   Reset may_garbage_collect when evaluating expression mapping.
            Add tests. (Ozaki Kiichi, closes vim/vim#4579)

vim/vim@7d491c4
JaySandhu added a commit to JaySandhu/neovim that referenced this pull request Sep 9, 2020
Problem:    On error garbage collection may free memory in use.
Solution:   Reset may_garbage_collect when evaluating expression mapping.
            Add tests. (Ozaki Kiichi, closes vim/vim#4579)

vim/vim@7d491c4
janlazo added a commit to janlazo/neovim that referenced this pull request Sep 26, 2020
Problem:    On error garbage collection may free memory in use.
Solution:   Reset may_garbage_collect when evaluating expression mapping.
            Add tests. (Ozaki Kiichi, closes vim/vim#4579)
vim/vim@7d491c4
janlazo added a commit to janlazo/neovim that referenced this pull request Oct 1, 2020
Problem:    On error garbage collection may free memory in use.
Solution:   Reset may_garbage_collect when evaluating expression mapping.
            Add tests. (Ozaki Kiichi, closes vim/vim#4579)
vim/vim@7d491c4
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.

None yet

1 participant