jeromejj / vim

Automatically exported from code.google.com/p/vim
0 stars 0 forks source link

Use of memory after free when pasting in read-only file using Perforce plugin #96

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Using latest Vim-7.3.753, I can reproduce this error 100% of the time
with valgrind:

==4589== Invalid read of size 8
==4589==    at 0x74857D: do_put (ops.c:3493)
==4589==    by 0x719B0C: nv_put (normal.c:9463)
==4589==    by 0x6FE952: normal_cmd (normal.c:1198)
==4589==    by 0xA5692C: main_loop (main.c:1306)
==4589==    by 0xA4E9A3: main (main.c:1010)
==4589==  Address 0xc89bd90 is 0 bytes inside a block of size 8 free'd
==4589==    at 0x4C2B6F9: free (vg_replace_malloc.c:446)
==4589==    by 0x6B38C3: vim_free (misc2.c:1744)
==4589==    by 0x747214: free_yank (ops.c:2855)
==4589==    by 0x7327B6: free_yank_all (ops.c:2867)
==4589==    by 0x758D8F: clip_free_selection (ops.c:5868)
==4589==    by 0x99AB00: clip_lose_selection (ui.c:514)
==4589==    by 0x78583A: loose_clipboard (os_unix.c:1150)
==4589==    by 0x789D49: mch_call_shell (os_unix.c:3959)
==4589==    by 0x6BFDE3: call_shell (misc2.c:3230)
==4589==    by 0x6ABB3D: get_cmd_output (misc1.c:10721)
==4589==    by 0x4D1BFB: f_system (eval.c:17850)
==4589==    by 0x4948E2: call_func (eval.c:8513)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x4E1982: eval7 (eval.c:5160)
==4589==    by 0x4E07B4: eval6 (eval.c:4812)
==4589==    by 0x4E00C8: eval5 (eval.c:4628)
==4589==    by 0x4DF08D: eval4 (eval.c:4321)
==4589==    by 0x4DEE79: eval3 (eval.c:4233)
==4589==    by 0x4DEC69: eval2 (eval.c:4162)
==4589==    by 0x492602: eval1 (eval.c:4087)
==4589==    by 0x491F13: eval0 (eval.c:4044)
==4589==    by 0x495A59: ex_let (eval.c:1899)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x4E1982: eval7 (eval.c:5160)
==4589==    by 0x4E07B4: eval6 (eval.c:4812)
==4589==    by 0x4E00C8: eval5 (eval.c:4628)
==4589==    by 0x4DF08D: eval4 (eval.c:4321)
==4589==    by 0x4DEE79: eval3 (eval.c:4233)
==4589==    by 0x4DEC69: eval2 (eval.c:4162)
==4589==    by 0x492602: eval1 (eval.c:4087)
==4589==    by 0x491F13: eval0 (eval.c:4044)
==4589==    by 0x4A6F0A: ex_return (eval.c:22779)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x4E1982: eval7 (eval.c:5160)
==4589==    by 0x4E07B4: eval6 (eval.c:4812)
==4589==    by 0x4E00C8: eval5 (eval.c:4628)
==4589==    by 0x4DF08D: eval4 (eval.c:4321)
==4589==    by 0x4DEE79: eval3 (eval.c:4233)
==4589==    by 0x4DEC69: eval2 (eval.c:4162)
==4589==    by 0x492602: eval1 (eval.c:4087)
==4589==    by 0x491F13: eval0 (eval.c:4044)
==4589==    by 0x495A59: ex_let (eval.c:1899)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x4E1982: eval7 (eval.c:5160)
==4589==    by 0x4E07B4: eval6 (eval.c:4812)
==4589==    by 0x4E00C8: eval5 (eval.c:4628)
==4589==    by 0x4DF08D: eval4 (eval.c:4321)
==4589==    by 0x4DEE79: eval3 (eval.c:4233)
==4589==    by 0x4DEC69: eval2 (eval.c:4162)
==4589==    by 0x492602: eval1 (eval.c:4087)
==4589==    by 0x491F13: eval0 (eval.c:4044)
==4589==    by 0x495A59: ex_let (eval.c:1899)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x49E302: func_call (eval.c:9216)
==4589==    by 0x4B5568: f_call (eval.c:9263)
==4589==    by 0x4948E2: call_func (eval.c:8513)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x4E1982: eval7 (eval.c:5160)
==4589==    by 0x4E07B4: eval6 (eval.c:4812)
==4589==    by 0x4E00C8: eval5 (eval.c:4628)
==4589==    by 0x4DF08D: eval4 (eval.c:4321)
==4589==    by 0x4DEE79: eval3 (eval.c:4233)
==4589==    by 0x4DEC69: eval2 (eval.c:4162)
==4589==    by 0x492602: eval1 (eval.c:4087)
==4589==    by 0x491F13: eval0 (eval.c:4044)
==4589==    by 0x4A6F0A: ex_return (eval.c:22779)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x497C9F: ex_call (eval.c:3467)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x4B23DB: call_user_func (eval.c:22569)
==4589==    by 0x494691: call_func (eval.c:8484)
==4589==    by 0x4990DE: get_func_tv (eval.c:8326)
==4589==    by 0x497C9F: ex_call (eval.c:3467)
==4589==    by 0x52B0E6: do_one_cmd (ex_docmd.c:2681)
==4589==    by 0x524836: do_cmdline (ex_docmd.c:1122)
==4589==    by 0x5AD702: apply_autocmds_group (fileio.c:9434)
==4589==    by 0x5A7DE7: apply_autocmds (fileio.c:9031)
==4589==    by 0x687858: change_warning (misc1.c:3202)
==4589==    by 0x9A8A74: u_savecommon (undo.c:393)
==4589==    by 0x9A8887: u_save (undo.c:248)
==4589==    by 0x7483F3: do_put (ops.c:3480)
==4589==    by 0x719B0C: nv_put (normal.c:9463)
==4589==    by 0x6FE952: normal_cmd (normal.c:1198)
==4589==    by 0xA5692C: main_loop (main.c:1306)
==4589==    by 0xA4E9A3: main (main.c:1010)
(and more errors follow after that).

ops.c:

! 3480         if (u_save(lnum - 1, lnum) == FAIL)  <--- frees y_array
  3481             goto end;
  3482 #ifdef FEAT_FOLDING
  3483         if (dir == FORWARD)
  3484             curwin->w_cursor.lnum = lnum - 1;
  3485         else
  3486             curwin->w_cursor.lnum = lnum;
  3487         curbuf->b_op_start = curwin->w_cursor;  /* for mark_adjust() */
  3488 #endif
  3489     }
  3490     else if (u_save_cursor() == FAIL)
  3491         goto end;
  3492 
! 3493     yanklen = (int)STRLEN(y_array[0]); <--- uses y_array after free

y_array points to y_current->y_array, which is freed at
ops.c:3480 by an autocommand and the freed memory is then
used a few lines below (ops.c:3493).

What steps will reproduce the problem?

The way to trigger the bug is a bit complicated. I don't have a simple
case. It happens 100% of the times when I press P in normal mode (to
paste and thus modify) in a read-only file using the perforce plugin,
which has an autocomand:

    :autocmd FileChangedRO
    -- Auto-Commands ---
    P4CheckOut  FileChangedRO
        *         :call <SID>CheckOutFile()

The plugin asks:

  Readonly file, do you want to checkout from perforce?
  (Y)es, (N)o, [C]ancel: 

I press Y.  Plugin then prints:

  OK:

I press CTRL-C and I get the valgrind error.
Without Valgrind, it crashes sometimes.

Perforce Vim plugin is required (perforce-4.1.zip) to
reproduce this issue:

http://www.vim.org/scripts/script.php?script_id=240

It's not clear to me how to fix it.

What version of the product are you using? On what operating system?

Vim-7.3.753 (huge) on Linux x86_64, in terminal.

Original issue reported on code.google.com by dominiqu...@gmail.com on 7 Dec 2012 at 9:14

GoogleCodeExporter commented 9 years ago
It's tricky that u_undo() may cause an autocommand to be executed, it could do 
just about anything and make any pointers invalid.
Probably the best solution is to invoke u_undo() first, before calling 
get_yank_register().  It might change undo behavior a bit, perhaps only do it 
when there is an autocommand?

Original comment by brammool...@gmail.com on 8 Dec 2012 at 1:51

GoogleCodeExporter commented 9 years ago
I need to add that this issue has caused several crashes to me while working 
normally with Vim and Perforce plugin in the last few days.  What I find 
strange is that I was working with the same setup for months without such 
crash.  And in the last few days, I experienced 3 or 4 crashes.  So something 
must have changed recently either to make the crash happening more frequently.  
Here is a gdb stack trace when crash happened while checking-out a file within 
Vim:

(gdb) bt
#0  0x00007f9f793ed707 in kill () at ../sysdeps/unix/syscall-template.S:82
#1  0x0000000000788bd7 in may_core_dump () at os_unix.c:3166
#2  0x00000000007889d3 in mch_exit (r=1) at os_unix.c:3132
#3  0x0000000000a55d94 in getout (exitval=1) at main.c:1478
#4  0x00000000006a6c66 in preserve_exit () at misc1.c:9134
#5  0x0000000000797305 in deathtrap (sigarg=11) at os_unix.c:1097
#6  <signal handler called>
#7  __strlen_sse2_pminub () at 
../sysdeps/x86_64/multiarch/strlen-sse2-pminub.S:39
#8  0x0000000000748585 in do_put (regname=43, dir=1, count=1, flags=0) at 
ops.c:3493
#9  0x0000000000719b0d in nv_put (cap=0x7fff970b3c48) at normal.c:9463
#10 0x00000000006fe953 in normal_cmd (oap=0x7fff970b3d08, toplevel=1) at 
normal.c:1198
#11 0x0000000000a5692d in main_loop (cmdwin=0, noexmode=0) at main.c:1306
#12 0x0000000000a4e9a4 in main (argc=2, argv=0x7fff970b4318) at main.c:1010
(gdb) 

Notice that it crashes where valgrind was also complaining.

Full stack trace:

gdb) bt full
#0  0x00007f9f793ed707 in kill () at ../sysdeps/unix/syscall-template.S:82
No locals.
#1  0x0000000000788bd7 in may_core_dump () at os_unix.c:3166
No locals.
#2  0x00000000007889d3 in mch_exit (r=1) at os_unix.c:3132
No locals.
#3  0x0000000000a55d94 in getout (exitval=1) at main.c:1478
        buf = 0x0
        wp = 0x0
        tp = 0x0
        next_tp = 0x0
#4  0x00000000006a6c66 in preserve_exit () at misc1.c:9134
        buf = 0x0
#5  0x0000000000797305 in deathtrap (sigarg=11) at os_unix.c:1097
        i = 7
        entered = 1
#6  <signal handler called>
No symbol table info available.
#7  __strlen_sse2_pminub () at 
../sysdeps/x86_64/multiarch/strlen-sse2-pminub.S:39
No locals.
#8  0x0000000000748585 in do_put (regname=43, dir=1, count=1, flags=0) at 
ops.c:3493
        newp = 0x0
        oldlen = 32767
        bd = {startspaces = -1760869616, endspaces = 112, textlen = 1, textstart = 0x70 <Address 0x70 out of bounds>, textcol = 7026884, start_vcol = 0, end_vcol = 0, is_short = 0, is_MAX = 39385520, 
          is_oneChar = 0, pre_whitesp = -1760874992, pre_whitesp_c = 112, end_char_vcols = 13413992, start_char_vcols = 0}
        indent = 0
        ptr = 0x6ffb14 "\307E\344\001"
        oldp = 0x70 <Address 0x70 out of bounds>
        yanklen = 0
        col = 1
        totlen = 0
        lnum = 46
        i = 7364200
        vcol = 32767
        delcount = -1760874976
        nr_lines = 0
        allocated = 0
        cnt = 13413992
        y_size = 1
        j = 0
        new_cursor = {lnum = 140735727480400, col = 0, coladd = 0}
        orig_indent = 0
        first_indent = 1
        y_type = 1
        incr = 0
        y_array = 0x2651050
        insert_string = 0x0
        y_width = 0
        indent_diff = 0
        lendiff = 0
        old_pos = {lnum = 10927409, col = 33, coladd = 0}
#9  0x0000000000719b0d in nv_put (cap=0x7fff970b3c48) at normal.c:9463
        regname = 0
        reg2 = 0x0
        empty = 0
        was_visual = 0
        dir = 1
        flags = 0
        reg1 = 0x0
#10 0x00000000006fe953 in normal_cmd (oap=0x7fff970b3d08, toplevel=1) at 
normal.c:1198
        ca = {oap = 0x7fff970b3d08, prechar = 0, cmdchar = 112, nchar = 0, ncharC1 = 0, ncharC2 = 0, extra_char = 0, opcount = 0, count0 = 0, count1 = 1, arg = 0, retval = 0, searchbuf = 0x0}
        c = 112
        idx = 113
        set_prevcount = 0
        ctrl_w = 0
        old_col = 31
        need_flushbuf = 1
        old_pos = {lnum = 45, col = 31, coladd = 0}
        mapped_len = 0
        old_mapped_len = 0
#11 0x0000000000a5692d in main_loop (cmdwin=0, noexmode=0) at main.c:1306
        oa = {op_type = 0, regname = 0, motion_type = 0, motion_force = 0, use_reg_one = 0, inclusive = 0, end_adjusted = 0, start = {lnum = 112, col = 33, coladd = 0}, end = {lnum = 112, col = 33, 
            coladd = 0}, cursor_start = {lnum = 0, col = 0, coladd = 0}, line_count = 1, empty = 0, is_VIsual = 0, block_mode = 0, start_vcol = 0, end_vcol = 13, prev_opcount = 0, prev_count0 = 0}
        previous_got_int = 0
        conceal_old_cursor_line = 0
        conceal_new_cursor_line = 0
        conceal_update_lines = 0
#12 0x0000000000a4e9a4 in main (argc=2, argv=0x7fff970b4318) at main.c:1010
        fname = 0x2219b30 "NDS-poi-region.cpp"
        params = {argc = 2, argv = 0x7fff970b4318, evim_mode = 0, use_vimrc = 0x0, n_commands = 0, commands = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
          cmds_tofree = "\000\000\000\000\000\000\000\000\000", n_pre_commands = 0, pre_commands = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, edit_type = 1, tagname = 0x0, use_ef = 0x0, 
          want_full_screen = 1, stdout_isatty = 1, term = 0x0, ask_for_key = 0, no_swap_file = 0, use_debug_break_level = -1, window_count = 1, window_layout = 0, serverArg = 0, serverName_arg = 0x0, 
          serverStr = 0x0, serverStrEnc = 0x0, servername = 0x221ce20 "VIM", diff_mode = 0}
        i = 2
(gdb) 

Original comment by dominiqu...@gmail.com on 10 Dec 2012 at 3:58

GoogleCodeExporter commented 9 years ago
I found that this bug only happens when I have this line in my ~/.virmc:

  :set clipboard=unnamedplus,autoselect,exclude:cons\|linux

I had recently added this line in my ~/.vimrc (and then forgot about it) 
because I tried to reproduce a bug with yankring intentioned here:

https://groups.google.com/forum/?fromgroups=#!topic/vim_dev/Hgrb2O4A7yQ

That explains why I only started to see several crashes in the last few days.

So this setting of 'clipboard' not only causes a bug with yankring (plugin 
which I'm not using) but also creates a bug with the perforce-4.1 plugin 
(plugin which I'm using).

I'll try later when I find time to find a minimalistic ~/.vimrc to reproduce 
this bug and will try to reproduce it without any plugin if possible.

Original comment by dominiqu...@gmail.com on 12 Dec 2012 at 12:48

GoogleCodeExporter commented 9 years ago
Please check if patch 7.3.757 solves this problem.

Original comment by brammool...@gmail.com on 12 Dec 2012 at 3:13

GoogleCodeExporter commented 9 years ago
Bram wrote:

> Please check if patch 7.3.757 solves this problem.

Yes, it fixes it.  Thanks!

Original comment by dominiqu...@gmail.com on 12 Dec 2012 at 7:14

GoogleCodeExporter commented 9 years ago

Original comment by brammool...@gmail.com on 12 Dec 2012 at 8:02