Status: New
Owner: ----
Labels: Type-Defect Priority-Medium

New issue 96 by [email protected]: Use of memory after free when pasting in read-only file using Perforce plugin
http://code.google.com/p/vim/issues/detail?id=96

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.

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui