[vim/vim] Crash when using funcref for 'operatorfunc' (Issue #9312)

6 views
Skip to first unread message

naohiro ono

unread,
Dec 9, 2021, 11:13:37 AM12/9/21
to vim/vim, Subscribed

Describe the issue

Using a funcref for 'operatorfunc' option might cause a crash.

Steps to reproduce

  1. Run vim -Nu NONE.

  2. :source this script:

    function SetOperatorfunc()
      let operator = {'execute': function('OperatorExecute')}
      let &operatorfunc = operator.execute
    endfunction
    function OperatorExecute(_) dict
    endfunction
    call SetOperatorfunc()
    call test_garbagecollect_now()
    set operatorfunc=

    Vim crashes.

Expected behavior

Vim does not crash.

Environment

  • Vim 8.2.3765
  • macOS 10.15.7
  • iTerm2


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

lacygoill

unread,
Dec 9, 2021, 12:23:34 PM12/9/21
to vim/vim, Subscribed

FWIW, I can't reproduce on Vim 8.2.3766 and Ubuntu 20.04.

Also, not sure the example is valid because it uses test_garbagecollect_now():

Right, test_garbagecollect_now() must be used with care, since it can cause freeing memory that is in use.
Thus the example is invalid.

Can you reproduce without test_garbagecollect_now()? And could you get some logs?

Yegappan Lakshmanan

unread,
Dec 9, 2021, 12:43:16 PM12/9/21
to vim_dev, reply+ACY5DGGDN7O254UZHK...@reply.github.com, vim/vim, Subscribed
Hi,

On Thu, Dec 9, 2021 at 8:13 AM naohiro ono <vim-dev...@256bit.org> wrote:

Describe the issue

Using a funcref for 'operatorfunc' option might cause a crash.


The garbage collection support for the callback functions is missing. I will send
out a PR later.

- Yegappan

vim-dev ML

unread,
Dec 9, 2021, 12:43:32 PM12/9/21
to vim/vim, vim-dev ML, Your activity

Hi,

On Thu, Dec 9, 2021 at 8:13 AM naohiro ono ***@***.***>
wrote:

> *Describe the issue*

>
> Using a funcref for 'operatorfunc' option might cause a crash.
>

The garbage collection support for the callback functions is missing. I
will send
out a PR later.

- Yegappan


> *Steps to reproduce*
>
> 1.
>
> Run vim -Nu NONE.
> 2.

>
> :source this script:
>
> function SetOperatorfunc()
> let operator = {'execute': function('OperatorExecute')}
> let &operatorfunc = operator.executeendfunctionfunction OperatorExecute(_) dictendfunctioncall SetOperatorfunc()call test_garbagecollect_now()set operatorfunc=
>
> Vim crashes.
>
> *Expected behavior*
>
> Vim does not crash.
>
> *Environment*
>
> - Vim 8.2.3765
> - macOS 10.15.7
> - iTerm2

naohiro ono

unread,
Dec 9, 2021, 1:32:25 PM12/9/21
to vim/vim, vim-dev ML, Comment

@lacygoill

FWIW, I can't reproduce on Vim 8.2.3766 and Ubuntu 20.04.

Also, not sure the example is valid because it uses test_garbagecollect_now():

Right, test_garbagecollect_now() must be used with care, since it can cause freeing memory that is in use.
Thus the example is invalid.

Thanks for the check. I didn't know that remark.

Can you reproduce without test_garbagecollect_now()?

I could, but the crash sometimes happened after wating a few seconds, so I guessed garbage collection is relevant.

And could you get some logs?

Thank you for the useful link! I'll attach a log if I can get.

@yegappan

Hi,
On Thu, Dec 9, 2021 at 8:13 AM naohiro ono @.***> wrote: Describe the issue Using a funcref for 'operatorfunc' option might cause a crash.


The garbage collection support for the callback functions is missing. I will send out a PR later. - Yegappan

Thank you for working on this. Using a funcref, especially a partial, is useful!


You are receiving this because you commented.

lacygoill

unread,
Dec 9, 2021, 1:51:13 PM12/9/21
to vim/vim, vim-dev ML, Comment

Thanks for the check. I didn't know that remark.

Ah sorry, the first link was wrong. Here is the source.

I'm never sure whether it's OK to include a test_*() function in a snippet. Sometimes, it seems OK (for example these crashes were fixed in patches 8.2.3379-8.23382), sometimes not.

I guess it depends.

Thank you for the useful link! I'll attach a log if I can get.

Now I can reproduce the crash. But it doesn't happen all the time. I think that's why I couldn't reproduce the first time. I tried to get a backtrace, but Vim never seems to crash when instrumented by gdb(1). However, I have been able to get a log with an asan-enabled Vim:

=================================================================
==237752==ERROR: AddressSanitizer: heap-use-after-free on address 0x6130000011c4 at pc 0x5632073bb25c bp 0x7ffdbe6afcb0 sp 0x7ffdbe6afca0
READ of size 4 at 0x6130000011c4 thread T0
    #0 0x5632073bb25b in dict_unref /home/lgc/Vcs/vim/src/dict.c:175
    #1 0x563207488d53 in partial_free /home/lgc/Vcs/vim/src/eval.c:4336
    #2 0x5632074892a6 in partial_unref /home/lgc/Vcs/vim/src/eval.c:4369
    #3 0x5632075021f7 in free_callback /home/lgc/Vcs/vim/src/evalvars.c:4525
    #4 0x5632078faba4 in option_set_callback_func /home/lgc/Vcs/vim/src/option.c:7197
    #5 0x56320789f583 in set_operatorfunc_option /home/lgc/Vcs/vim/src/ops.c:3337
    #6 0x56320790c288 in did_set_string_option /home/lgc/Vcs/vim/src/optionstr.c:2353
    #7 0x5632078bfc7b in do_set /home/lgc/Vcs/vim/src/option.c:2113
    #8 0x5632078b6bee in ex_set /home/lgc/Vcs/vim/src/option.c:1210
    #9 0x56320754bee1 in do_one_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:2578
    #10 0x56320753f9f1 in do_cmdline /home/lgc/Vcs/vim/src/ex_docmd.c:1000
    #11 0x563207ab8399 in do_source /home/lgc/Vcs/vim/src/scriptfile.c:1420
    #12 0x563207ab4f9b in cmd_source /home/lgc/Vcs/vim/src/scriptfile.c:985
    #13 0x563207ab5158 in ex_source /home/lgc/Vcs/vim/src/scriptfile.c:1011
    #14 0x56320754bee1 in do_one_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:2578
    #15 0x56320753f9f1 in do_cmdline /home/lgc/Vcs/vim/src/ex_docmd.c:1000
    #16 0x56320753d583 in do_cmdline_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:594
    #17 0x56320802f6ef in exe_commands /home/lgc/Vcs/vim/src/main.c:3080
    #18 0x563208021266 in vim_main2 /home/lgc/Vcs/vim/src/main.c:774
    #19 0x56320802074c in main /home/lgc/Vcs/vim/src/main.c:426
    #20 0x7f08092e00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #21 0x5632072bedfd in _start (/home/lgc/Vcs/vim/src/vim+0x1232dfd)

0x6130000011c4 is located 4 bytes inside of 352-byte region [0x6130000011c0,0x613000001320)
freed by thread T0 here:
    #0 0x7f080adb37cf in __interceptor_free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #1 0x5632072c0097 in vim_free /home/lgc/Vcs/vim/src/alloc.c:619
    #2 0x5632073bb145 in dict_free_dict /home/lgc/Vcs/vim/src/dict.c:155
    #3 0x5632073bb5bb in dict_free_items /home/lgc/Vcs/vim/src/dict.c:210
    #4 0x56320748a567 in free_unref_items /home/lgc/Vcs/vim/src/eval.c:4611
    #5 0x56320748a461 in garbage_collect /home/lgc/Vcs/vim/src/eval.c:4558
    #6 0x563207caf96b in f_test_garbagecollect_now /home/lgc/Vcs/vim/src/testing.c:1152
    #7 0x5632074a92ee in call_internal_func /home/lgc/Vcs/vim/src/evalfunc.c:2539
    #8 0x563207d5771c in call_func /home/lgc/Vcs/vim/src/userfunc.c:3426
    #9 0x563207d45f52 in get_func_tv /home/lgc/Vcs/vim/src/userfunc.c:1754
    #10 0x563207d68c9f in ex_call /home/lgc/Vcs/vim/src/userfunc.c:5078
    #11 0x56320754bee1 in do_one_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:2578
    #12 0x56320753f9f1 in do_cmdline /home/lgc/Vcs/vim/src/ex_docmd.c:1000
    #13 0x563207ab8399 in do_source /home/lgc/Vcs/vim/src/scriptfile.c:1420
    #14 0x563207ab4f9b in cmd_source /home/lgc/Vcs/vim/src/scriptfile.c:985
    #15 0x563207ab5158 in ex_source /home/lgc/Vcs/vim/src/scriptfile.c:1011
    #16 0x56320754bee1 in do_one_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:2578
    #17 0x56320753f9f1 in do_cmdline /home/lgc/Vcs/vim/src/ex_docmd.c:1000
    #18 0x56320753d583 in do_cmdline_cmd /home/lgc/Vcs/vim/src/ex_docmd.c:594
    #19 0x56320802f6ef in exe_commands /home/lgc/Vcs/vim/src/main.c:3080
    #20 0x563208021266 in vim_main2 /home/lgc/Vcs/vim/src/main.c:774
    #21 0x56320802074c in main /home/lgc/Vcs/vim/src/main.c:426
    #22 0x7f08092e00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

previously allocated by thread T0 here:
    #0 0x7f080adb3bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x5632072bf2a6 in lalloc /home/lgc/Vcs/vim/src/alloc.c:244
    #2 0x5632072bf10e in alloc_clear /home/lgc/Vcs/vim/src/alloc.c:175
    #3 0x5632073ba161 in dict_alloc /home/lgc/Vcs/vim/src/dict.c:32
    #4 0x5632073bf9d3 in eval_dict /home/lgc/Vcs/vim/src/dict.c:914
    #5 0x5632074829d9 in eval7 /home/lgc/Vcs/vim/src/eval.c:3498
    #6 0x563207481823 in eval7t /home/lgc/Vcs/vim/src/eval.c:3304
    #7 0x56320747ff0a in eval6 /home/lgc/Vcs/vim/src/eval.c:3096
    #8 0x56320747e039 in eval5 /home/lgc/Vcs/vim/src/eval.c:2859
    #9 0x56320747cccf in eval4 /home/lgc/Vcs/vim/src/eval.c:2712
    #10 0x56320747bbdd in eval3 /home/lgc/Vcs/vim/src/eval.c:2573
    #11 0x56320747ab55 in eval2 /home/lgc/Vcs/vim/src/eval.c:2447
    #12 0x56320747915a in eval1 /home/lgc/Vcs/vim/src/eval.c:2293
    #13 0x563207d455ac in get_func_tv /home/lgc/Vcs/vim/src/userfunc.c:1703
    #14 0x563207476f75 in eval_func /home/lgc/Vcs/vim/src/eval.c:2017
    #15 0x563207483dd4 in eval7 /home/lgc/Vcs/vim/src/eval.c:3606
    #16 0x563207481823 in eval7t /home/lgc/Vcs/vim/src/eval.c:3304
    #17 0x56320747ff0a in eval6 /home/lgc/Vcs/vim/src/eval.c:3096
    #18 0x56320747e039 in eval5 /home/lgc/Vcs/vim/src/eval.c:2859
    #19 0x56320747cccf in eval4 /home/lgc/Vcs/vim/src/eval.c:2712
    #20 0x56320747bbdd in eval3 /home/lgc/Vcs/vim/src/eval.c:2573
    #21 0x56320747ab55 in eval2 /home/lgc/Vcs/vim/src/eval.c:2447
    #22 0x56320747915a in eval1 /home/lgc/Vcs/vim/src/eval.c:2293
    #23 0x563207478b3c in eval0 /home/lgc/Vcs/vim/src/eval.c:2229
    #24 0x563207466b21 in eval_expr /home/lgc/Vcs/vim/src/eval.c:622
    #25 0x5632078facf9 in option_set_callback_func /home/lgc/Vcs/vim/src/option.c:7205
    #26 0x56320789f583 in set_operatorfunc_option /home/lgc/Vcs/vim/src/ops.c:3337
    #27 0x56320790c288 in did_set_string_option /home/lgc/Vcs/vim/src/optionstr.c:2353
    #28 0x5632078fdbbd in set_string_option /home/lgc/Vcs/vim/src/optionstr.c:543
    #29 0x5632078d2028 in set_option_value /home/lgc/Vcs/vim/src/option.c:4366

SUMMARY: AddressSanitizer: heap-use-after-free /home/lgc/Vcs/vim/src/dict.c:175 in dict_unref
Shadow bytes around the buggy address:
  0x0c267fff81e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c267fff81f0: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c267fff8200: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fff8210: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fff8220: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c267fff8230: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x0c267fff8240: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fff8250: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fff8260: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c267fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c267fff8280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Shadow gap:              cc
==237752==ABORTING


You are receiving this because you commented.

lacygoill

unread,
Dec 12, 2021, 1:42:39 PM12/12/21
to vim/vim, vim-dev ML, Comment

Not sure, but the issue could have been fixed in patch 8.2.3788. At least, an asan-enabled Vim no longer gives any relevant error.


You are receiving this because you commented.

Bram Moolenaar

unread,
Dec 12, 2021, 3:20:13 PM12/12/21
to vim/vim, vim-dev ML, Comment

Closed #9312.


You are receiving this because you commented.

Bram Moolenaar

unread,
Dec 12, 2021, 3:20:16 PM12/12/21
to vim/vim, vim-dev ML, Comment

I assume that the patch fixed this problem. If you can still reproduce it, please reopen.


You are receiving this because you commented.

Reply all
Reply to author
Forward
0 new messages