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

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

Closed
GoogleCodeExporter opened this issue Aug 18, 2015 · 6 comments

Comments

@GoogleCodeExporter
Copy link

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

Please check if patch 7.3.757 solves this problem.

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

  • Changed state: Started

@GoogleCodeExporter
Copy link
Author

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
Copy link
Author

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

  • Changed state: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant